Sunday, October 6, 2019

unity - Wander steering behaviour in 3D


I'm trying to implement the Wander Steering Behaviour but getting strange result (see .gif). What am i doing wrong? I want to move a sphere in a random direction.



wander problem


using UnityEngine;

public class UnitWander : MonoBehaviour
{
public const float CircleDistance = 1f;
public const float CircleRadius = 0.1f;

public const float AngleChange = 50f;

public float Mass = 1;
public float MaxSpeed = 1;
public float MaxForce = 1;

private Vector3 velocity = Vector3.forward;
private float wanderAngle;

private void Update()

{
var steering = GetWanderForce();
steering = Vector3.ClampMagnitude(steering, MaxForce);
steering /= Mass;

velocity = Vector3.ClampMagnitude(velocity + steering, MaxSpeed);
transform.position += velocity;
transform.forward = velocity;
}


private Vector3 GetWanderForce()
{
var circleCenter = velocity.normalized * CircleDistance;

var displacement = transform.right * Mathf.Cos(wanderAngle * Mathf.Deg2Rad) * CircleRadius;
displacement += transform.up * Mathf.Sin(wanderAngle * Mathf.Deg2Rad) * CircleRadius;

wanderAngle += (Random.value * AngleChange) - (AngleChange * 0.5f);

var wanderForce = circleCenter + displacement;

return wanderForce;
}
}

Answer



I solved the problem. Now script work fine. Just drop this script on game object and enjoy.


wander swarm


using UnityEngine;

public class UnitWander : MonoBehaviour
{

public float CircleRadius = 1;
public float TurnChance = 0.05f;
public float MaxRadius = 5;

public float Mass = 15;
public float MaxSpeed = 3;
public float MaxForce = 15;

private Vector3 velocity;
private Vector3 wanderForce;

private Vector3 target;

private void Start()
{
velocity = Random.onUnitSphere;
wanderForce = GetRandomWanderForce();
}

private void Update()
{

var desiredVelocity = GetWanderForce();
desiredVelocity = desiredVelocity.normalized * MaxSpeed;

var steeringForce = desiredVelocity - velocity;
steeringForce = Vector3.ClampMagnitude(steeringForce, MaxForce);
steeringForce /= Mass;

velocity = Vector3.ClampMagnitude(velocity + steeringForce, MaxSpeed);
transform.position += velocity * Time.deltaTime;
transform.forward = velocity.normalized;


Debug.DrawRay(transform.position, velocity.normalized * 2, Color.green);
Debug.DrawRay(transform.position, desiredVelocity.normalized * 2, Color.magenta);
}

private Vector3 GetWanderForce()
{
if (transform.position.magnitude > MaxRadius)
{
var directionToCenter = (target - transform.position).normalized;

wanderForce = velocity.normalized + directionToCenter;
}
else if (Random.value < TurnChance)
{
wanderForce = GetRandomWanderForce();
}

return wanderForce;
}


private Vector3 GetRandomWanderForce()
{
var circleCenter = velocity.normalized;
var randomPoint = Random.insideUnitCircle;

var displacement = new Vector3(randomPoint.x, randomPoint.y) * CircleRadius;
displacement = Quaternion.LookRotation(velocity) * displacement;

var wanderForce = circleCenter + displacement;
return wanderForce;

}
}

No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...