Robotic mouse movement steering behavior help

Hi

I’m new to Unity3d scripting, but have been coding for 8 years, so I know my way around C# :slight_smile:

I’m trying to do a steering behavior like the mouse have in “Cyber mice” : Play Cyber Mice Party 2003 3 Online - Free Game - MuchGames.com

They start with random direction and then move forward until they hit an obstacle. Here they turn, until they don’t collide anymore (thats the part I cant figure out how to do) and then move forward again.

I’m using the new 2D colliders here.

I’m asking for help to make a script that can do the above behavior, here’s what I have now, which DOESN’T work exactly as above.
The problem is the rotate until not colliding anymore.

Guess this is a easy one, I just can’t figure out how to do this in Unity3d :slight_smile:

Thanks in advance,

public class WanderMovement : MonoBehaviour 
{
	public float _speed = 0.4f;

	private Animator _anim;
	private Transform _transform;
	private Vector2 _direction;
	private float _rotationAngle = 0f;
	private Vector2 _lastPosition;
	private bool _isColliding = false;

	void Start () 
	{
		_anim = GetComponent<Animator>();
		_transform = transform;
		_lastPosition = _transform.position;

		//Start moving in random direction
		_direction = new Vector2(Random.Range(-1.0f, 1.0f),
		                         Random.Range(-1.0f, 1.0f));
		_direction.Normalize();

	}
	
	// Update is called once per frame
	void Update () 
	{
		_transform.Translate(_direction * _speed * Time.deltaTime);

		if(_isColliding == false)
			_lastPosition = _transform.position;

		_anim.SetFloat("DirectionY", _direction.y);
		_isColliding = false;
	}


	void OnTriggerEnter2D(Collider2D other)
	{
		if(other.tag == "Obstacle")
		{
			_isColliding = true;
			_transform.position = _lastPosition;
		}
	}


	void OnTriggerStay2D(Collider2D other)
	{
		if(other.tag == "Obstacle")
		{
			_isColliding = true;
			_transform.position = _lastPosition;
			_rotationAngle += 0.001f;
			_direction = Quaternion.AngleAxis(_rotationAngle, Vector3.forward) * _direction;
			Debug.Log(_rotationAngle);
		}
	}
}

UPDATE:
I see I forgot to mention an important think, here goes:

My “mice” doesn’t rotate as the mice in “Cyber mice”, at least not visually like the mice in “Cyber mice”. Their direction change, but their rotation is not. Think 2.5D spritesheet, where you have sprites to move up,down,right,left without the image/sprite rotating.

Here’s an sample of what I mean:

http://i387.photobucket.com/albums/oo313/anonbird/RPG%20Maker%20VX/birdzilla_sheep-recolors.png

Hi Laumania, you have far more programming experience than me, but I think I can see a small logic mistake in your code. If I am correct, then your “cyber mice” don’t rotate at all when they hit an obstacle, yes?

This is because Transform.Translate only moves an object. In order to rotate it, you have to use Transform.Rotate

So although in your Update() you are giving a new _direction every time while the “cyber mouse” is touching a trigger, it never actually rotates the object, but rather tries to move it to that new vector.

http://docs.unity3d.com/Documentation/ScriptReference/Transform.html

Also of note, if your “cyber mice” have RigidBody components, you should use FixedUpdate() rather than Update()

See if this works :slight_smile:

http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.FixedUpdate.html

Ok, I got it working now. It’s not perfect, as the rotateAngle can go crazy because it’s just +=. Should be based on the current direction/angle. But I’ll figure that out later.

Added a DrawRay so I can see the direction - pretty neat :slight_smile:

Here goes:

[RequireComponent(typeof(Rigidbody2D))]
public class WanderMovement2 : MonoBehaviour 
{
	private float _speed = 2.0f;
	private Transform _transform;
	private Vector2 _direction;
	private bool _isColliding = false;
	private float _rotationAngle = 0f;
	private Vector3 _lastPosition;

	void Start () 
	{
		_transform = rigidbody2D.transform;
		_lastPosition = _transform.position;

		//Start moving in random direction
		_direction = new Vector2(Random.Range(-1.0f, 1.0f),
		                         Random.Range(-1.0f, 1.0f));
		_direction.Normalize();
	}

	void FixedUpdate () 
	{
		if(_isColliding == false)
		{
			_lastPosition = _transform.position;
			_rotationAngle = 0f;

		}
		else
		{
			_transform.position = _lastPosition;
			_rotationAngle -= 2.0f * Time.deltaTime;
			_direction = Quaternion.AngleAxis(_rotationAngle, Vector3.forward) * _direction;
			_direction.Normalize();
			_isColliding = false;
		}

		_transform.Translate(_direction * _speed * Time.deltaTime);
		Debug.DrawRay(_transform.position, _direction);

	}

	void OnTriggerEnter2D(Collider2D other)
	{
		_isColliding = true;
	}
	
	
	void OnTriggerStay2D(Collider2D other)
	{
		_isColliding = true;
	}
}