x


Change direction on collision problem

Hi guys. I’m a beginner, and am doing a simple game using triggers but not using any Kind of physics as acceleration. What I want to do is when the cube collides with the wall his direction change randomly.

Any code or any explanation will be welcome. alt text

example.jpg (48.1 kB)
more ▼

asked Jul 14 '12 at 01:51 PM

t.pedrob gravatar image

t.pedrob
7 1 4 6

(comments are locked)
10|3000 characters needed characters left

4 answers: sort voted first

Well I'll consider that you know how to make it move in any direction. For a normal reflection you should reflect the movement direction using the normal vector of collision. You can get the normal from the parameter returned by the collision handler function

function OnControllerColliderHit (hit : ControllerColliderHit)
{
var normal : Vector3 = hit.normal;
}

After this you can reflect the movement using the Reflect function:

 var reflectionDirection : Vector3 = Vector3.Reflect( movementCurrentDirection, normal);

This will be a perfect reflect, if you want something random, you should rotate the normal vector or the final reflected vector by a little random angle.

 randomReflectDirection = Quaternion.Euler( 0, 0, littleRandNumHere ) * reflectionDirection;
more ▼

answered Jul 14 '12 at 03:45 PM

Kaze_Senshi gravatar image

Kaze_Senshi
162 15 18 19

(comments are locked)
10|3000 characters needed characters left

alt text

Sorry to border you again.

I made some research and I did what you said but with this code the boxes collide with each other not just the wall and now they don’t reflect the movement on collision, they go on predefined direction, collide with the wall for some time until get out of bounds.

Any help?

public var speed : float;

private var movementCurrentDirection = Vector3.zero;

private var controller : CharacterController;

function Start (){

movementCurrentDirection = transform.TransformDirection(speed,speed,0);

}

function Update() {

controller = GetComponent(CharacterController);

controller.Move(movementCurrentDirection * Time.deltaTime);

}

function OnControllerColliderHit(hit:ControllerColliderHit){

if(hit.gameObject.tag == "Wall") {

var normal : Vector3 = hit.normal;

var reflectionDirection : Vector3 = Vector3.Reflect(movementCurrentDirection, normal);

movementCurrentDirection = reflectionDirection; } }

exemplo2.jpg (48.7 kB)
more ▼

answered Jul 15 '12 at 11:18 PM

t.pedrob gravatar image

t.pedrob
7 1 4 6

Hmmm I don't have idea what is wrong, for me it looks right. Try these things: * call the debugLine after the reflection to see where the normal and the reflector vector are pointing, maybe you can see what is wrong with this, you must pause the game play and make gizmos visible to see the lines;

  • Put a time constraint to avoid your object to have a possibility to reflect a hundread times per second;

Use this code as reference, I didn't tested it :P ...

var reflectRepeatTime : float : 0.1;

function Start (){ movementCurrentDirection = Vector3( speed, speed, 0 ); }

...

function OnControllerColliderHit(hit:ControllerColliderHit){

if(hit.gameObject.tag == "Wall") {

if( lastReflectTime + reflectRepeatTime > Time.time) return;

lastReflectTime = Time.time;

var normal : Vector3 = hit.normal;

var reflectionDirection : Vector3 = Vector3.Reflect(movementCurrentDirection, normal);

movementCurrentDirection = reflectionDirection;

Debug.DrawLine (transform.position, transform.position+reflectionDirection, Color.blue, 60); Debug.DrawLine (transform.position, transform.position+normal, Color.red, 60); } }

Jul 16 '12 at 12:57 AM Kaze_Senshi
(comments are locked)
10|3000 characters needed characters left

Hi! Thanks, you were a great help. My problem is solved. The final code is below for everyone who need it. Thanks again ^^

public var speed : float;

private var movementCurrentDirection = Vector3.zero;

private var controller : CharacterController;

public var reflectRepeatTime : float;

private var lastReflectTime: float;

function Start (){

movementCurrentDirection = transform.TransformDirection(speed,speed,0);

}

function Update() {

controller = GetComponent(CharacterController);

controller.Move(movementCurrentDirection * Time.deltaTime); }

function OnControllerColliderHit(hit:ControllerColliderHit){

if(hit.gameObject.tag == "Wall") { if(lastReflectTime + reflectRepeatTime > Time.time) return; lastReflectTime = Time.time; var normal : Vector3 = hit.normal; var reflectionDirection : Vector3 = Vector3.Reflect(movementCurrentDirection, normal); var randomReflectDirection = Quaternion.Euler( 0, 0, Random.Range(-80, 80)) * reflectionDirection; movementCurrentDirection = randomReflectDirection;

Debug.DrawLine (transform.position, transform.position+reflectionDirection, Color.blue, 60); Debug.DrawLine (transform.position, transform.position+normal, Color.red, 60); } }

more ▼

answered Jul 16 '12 at 03:27 PM

t.pedrob gravatar image

t.pedrob
7 1 4 6

Oh good, mark my answer as the correct one for me gain some karma points :P Also I forgot to talk, you don't need to get the controller component in every Update function call, this will make your game slower. You can get the component one time in the Start function and just use it in update:

function Start (){

movementCurrentDirection = transform.TransformDirection(speed,speed,0); controller = GetComponent(CharacterController); if( controller == null ) { Debug.LogError( "Controller not found in object, destroying it to avoid crashes"); GameObject.Destroy(gameObject); }

}

function Update() {

controller.Move(movementCurrentDirection * Time.deltaTime); } ...

Jul 16 '12 at 07:47 PM Kaze_Senshi
(comments are locked)
10|3000 characters needed characters left

OnControllerColliderHit don’t work and I don’t know why. So I did the code bellow with OnCollisionEnter and collision work but the boxes after a while get out of bounds or get stuck on the walls .

Anyone known how so resolve this problem?

var speed : float;

private var movementCurrentDirection = Vector3.zero;

function Start (){

movementCurrentDirection = transform.TransformDirection(speed,speed,0);

}

function Update() {

transform.Translate(movementCurrentDirection);

}

function OnCollisionEnter(collision : Collision) {

if(collision.collider.tag == "Wall") {

 var contact : ContactPoint = collision.contacts[0];
 var normal = contact.normal;
 var reflectionDirection : Vector3 = Vector3.Reflect(movementCurrentDirection, normal);
 movementCurrentDirection = reflectionDirection;

} }

more ▼

answered Jul 14 '12 at 07:55 PM

t.pedrob gravatar image

t.pedrob
7 1 4 6

Here I get the normal directly from the function parameter function OnCollisionEnter(collision : Collision) { var normal = collision.normal; } And for the collision works if you use the OnControllerColliderHit() function, you must attach a CharacterController collider instead of a normal one, take a look here: http://docs.unity3d.com/Documentation/Components/class-CharacterController.html

Jul 14 '12 at 10:08 PM Kaze_Senshi
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2584
x296
x170
x128
x105

asked: Jul 14 '12 at 01:51 PM

Seen: 777 times

Last Updated: Jul 16 '12 at 07:47 PM