Source file unity-csharp/nature-of-code/random-walker-2d/RandomWalker2D.cs from the GDnD code examples. Download raw file
// GDnD wiki example
// Demonstrates: random walker motion in Unity 2D
// Related pages: [[procedural-generation]], [[overview-unity-nature-of-code-examples]]
using UnityEngine;
public class RandomWalker2D : MonoBehaviour
{
private static readonly Vector2[] CardinalDirections =
{
Vector2.up,
Vector2.right,
Vector2.down,
Vector2.left
};
[SerializeField] private float stepSize = 0.25f;
[SerializeField] private float stepsPerSecond = 20f;
[SerializeField] private bool cardinalOnly = true;
[SerializeField] private bool clampToCamera = true;
private Camera cachedCamera;
private float stepTimer;
private void Awake()
{
cachedCamera = Camera.main;
}
private void Update()
{
float interval = 1f / Mathf.Max(stepsPerSecond, 0.01f);
stepTimer += Time.deltaTime;
while (stepTimer >= interval)
{
stepTimer -= interval;
Step();
}
}
private void Step()
{
Vector2 direction = cardinalOnly
? CardinalDirections[Random.Range(0, CardinalDirections.Length)]
: Random.insideUnitCircle.normalized;
Vector3 nextPosition = transform.position + (Vector3)(direction * stepSize);
if (clampToCamera && cachedCamera != null && cachedCamera.orthographic)
{
nextPosition = ClampToCamera(nextPosition);
}
transform.position = nextPosition;
}
private Vector3 ClampToCamera(Vector3 position)
{
float halfHeight = cachedCamera.orthographicSize;
float halfWidth = halfHeight * cachedCamera.aspect;
Vector3 cameraPosition = cachedCamera.transform.position;
position.x = Mathf.Clamp(position.x, cameraPosition.x - halfWidth, cameraPosition.x + halfWidth);
position.y = Mathf.Clamp(position.y, cameraPosition.y - halfHeight, cameraPosition.y + halfHeight);
position.z = 0f;
return position;
}
}