- Home /
Random movement on a plain
Hi all,
I'm new to Unity and just started exploring its functions. As a test I wanted to make a simple scene with a plain and a cylinder hoovering above the plain.
The idea was to let the cylinder fall and when it hits the ground for it to move forward randomly.
I setup the scene, put the cylinder (with Rigidbody, Capsule Collider and Character Controler) and wrote a small script but it's not working...
What am I (obviously) doing wrong?
var Speed : float = 1.0;
var rotateSpeed : float = 10.0;
var gravity : float = 9.8;
private var moveDirection : Vector3 = Vector3.zero;
private var curDir = 1;
function Start () {
}
function Update () {
var controller: CharacterController = GetComponent(CharacterController);
if( controller.isGrounded ) {
// Rotate around y - axis
if (Random.value < 0.05f){
curDir = -curDir;
}
transform.Rotate(Vector3.up * curDir * rotateSpeed);
// Move forward object
moveDirection = Speed * transform.TransformDirection(Vector3.forward);
}
// Apply gravity
moveDirection.y -= gravity;
controller.Move(moveDirection * Time.deltaTime);
}
@script RequireComponent(CharacterController)
Answer by aldonaletto · Dec 24, 2012 at 12:50 AM
There are some weird things in your script:
1- Don't add CharacterController and Rigidbody to the same object, unless the Rigidbody is kinematic - the object may show an absolutely weird behaviour. You should use only the CharacterController and add gravity by script.
2- You're using two Move instructions in Update: this will double the actual speed in this case.
3- The chance to flip direction is 50%, thus the rotation may be reversed almost each frame, producing barely noticeable results. You could change the code a little to reduce the chances of flipping direction to about 5%, for instance.
var speed : float = 1.0;
var rotateSpeed : float = 20.0; // rotate speed in degrees per second
var gravity : float = 10.0;
private var moveDirection : Vector3 = Vector3.zero;
private var curDir = 1;
function Update () {
var controller: CharacterController = GetComponent(CharacterController);
if ( controller.isGrounded ) {
if (Random.value < 0.05f){ // if random value < 5/100...
curDir = -curDir; // flip direction
}
// Rotate around y - axis
transform.Rotate(Vector3.up * curDir * rotateSpeed * Time.deltaTime);
moveDirection = speed * transform.TransformDirection(Vector3.forward);
}
moveDirection.y -= gravity * Time.deltaTime; // apply gravity
controller.Move(moveDirection * Time.deltaTime);
}
Thanks for your help. It did improve a bit but is not doing what I intend. Right now gravity works fine (I removed rigidbody and the collider) but the cylinder just moves back and forth and does not rotate...
However, if I change the form to a cube it works!! Strange...
There was an error in my answer: the line where controller is assigned should be the first one in Update, but it was the second to last. I fixed the answer and tested it, and everything worked fine. I suspect that you may be another victim of the Inspector's elephant memory: change rotateSpeed in the Inspector to 10 or 20 - it was originally 1, and modifying it in the script has no effect because the Inspector always initialize it to the last value saved