Last active
September 21, 2020 15:28
-
-
Save mminer/1337455 to your computer and use it in GitHub Desktop.
Another Unity script to simulate a wandering behaviour for NPCs, this one taking into account collisions with boundaries.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
/// <summary> | |
/// Creates wandering behaviour for a CharacterController. | |
/// </summary> | |
[RequireComponent(typeof(CharacterController))] | |
public class Wander2 : MonoBehaviour | |
{ | |
public float speed = 5; | |
public float directionChangeInterval = 1; | |
public float maxHeadingChange = 30; | |
CharacterController controller; | |
float heading; | |
Vector3 targetRotation; | |
Vector3 forward | |
{ | |
get { return transform.TransformDirection(Vector3.forward); } | |
} | |
void Awake () | |
{ | |
controller = GetComponent<CharacterController>(); | |
// Set random initial rotation | |
heading = Random.Range(0, 360); | |
transform.eulerAngles = new Vector3(0, heading, 0); | |
StartCoroutine(NewHeadingRoutine()); | |
} | |
void Update () | |
{ | |
transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * directionChangeInterval); | |
controller.SimpleMove(forward * speed); | |
} | |
void OnControllerColliderHit (ControllerColliderHit hit) | |
{ | |
if (hit.gameObject.tag != "Boundary") { | |
return; | |
} | |
// Bounce off the wall using angle of reflection | |
var newDirection = Vector3.Reflect(forward, hit.normal); | |
transform.rotation = Quaternion.FromToRotation(Vector3.forward, newDirection); | |
heading = transform.eulerAngles.y; | |
NewHeading(); | |
} | |
/// <summary> | |
/// Calculates a new direction to move towards. | |
/// </summary> | |
void NewHeading () | |
{ | |
var floor = transform.eulerAngles.y - maxHeadingChange; | |
var ceil = transform.eulerAngles.y + maxHeadingChange; | |
heading = Random.Range(floor, ceil); | |
targetRotation = new Vector3(0, heading, 0); | |
} | |
/// <summary> | |
/// Repeatedly calculates a new direction to move towards. | |
/// Use this instead of MonoBehaviour.InvokeRepeating so that the interval can be changed at runtime. | |
/// </summary> | |
IEnumerator NewHeadingRoutine () | |
{ | |
while (true) { | |
NewHeading(); | |
yield return new WaitForSeconds(directionChangeInterval); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment