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;
    }
}