Wander

From Unify Community Wiki
Jump to: navigation, search

Author: Matthew Miner (matthew@matthewminer.com)

Contents

Description

Creates a wandering behaviour for NPCs.

Usage

Attach the script to your NPC, ensuring a CharacterController component is also attached. Tweak the inspector variables to get the desired behaviour.

C# - Wander.cs

using UnityEngine;
using System.Collections;
 
/// <summary>
/// Creates wandering behaviour for a CharacterController.
/// </summary>
[RequireComponent(typeof(CharacterController))]
public class Wander : MonoBehaviour
{
	public float speed = 5;
	public float directionChangeInterval = 1;
	public float maxHeadingChange = 30;
 
	CharacterController controller;
	float heading;
	Vector3 targetRotation;
 
	void Awake ()
	{
		controller = GetComponent<CharacterController>();
 
		// Set random initial rotation
		heading = Random.Range(0, 360);
		transform.eulerAngles = new Vector3(0, heading, 0);
 
		StartCoroutine(NewHeading());
	}
 
	void Update ()
	{
		transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * directionChangeInterval);
		var forward = transform.TransformDirection(Vector3.forward);
		controller.SimpleMove(forward * speed);
	}
 
	/// <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 NewHeading ()
	{
		while (true) {
			NewHeadingRoutine();
			yield return new WaitForSeconds(directionChangeInterval);
		}
	}
 
	/// <summary>
	/// Calculates a new direction to move towards.
	/// </summary>
	void NewHeadingRoutine ()
	{
		var floor = Mathf.Clamp(heading - maxHeadingChange, 0, 360);
		var ceil  = Mathf.Clamp(heading + maxHeadingChange, 0, 360);
		heading = Random.Range(floor, ceil);
		targetRotation = new Vector3(0, heading, 0);
	}
}


JavaScript Version Wander.js

#pragma strict
 
/// <summary>
/// Creates wandering behaviour for a CharacterController.
/// </summary>
@script RequireComponent(CharacterController)
 
    var speed:float = 5;
    var directionChangeInterval:float = 1;
    var maxHeadingChange:float = 30;
 
    var heading: float=0;
    var targetRotation: Vector3 ;
 
    function Awake (){
 
        // Set random initial rotation
		transform.eulerAngles = Vector3(0, Random.Range(0,360), 0);  // look in a random direction at start of frame.
 
        //StartCoroutine
		NewHeadingRoutine ();
    }
 
    function Update (){
		var controller : CharacterController = GetComponent(CharacterController);
 
        transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, targetRotation, Time.deltaTime * directionChangeInterval);
        var forward = transform.TransformDirection(Vector3.forward);
        controller.SimpleMove(forward * speed);
    }
 
    /// <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>
	while (true){
		NewHeadingRoutine();
		yield WaitForSeconds(directionChangeInterval);
	}
 
    /// <summary>
    /// Calculates a new direction to move towards.
    /// </summary>
    function NewHeadingRoutine (){
        var floor = Mathf.Clamp(heading - maxHeadingChange, 0, 360);
        var ceil  = Mathf.Clamp(heading + maxHeadingChange, 0, 360);
        heading = Random.Range(floor, ceil);
        targetRotation = new Vector3(0, heading, 0);
    }
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox