- Home /
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.
Answer by Kaze_Senshi · Jul 14, 2012 at 03:45 PM
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;
Answer by t-pedrob · Jul 14, 2012 at 07:55 PM
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;
} }
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 ins$$anonymous$$d of a normal one, take a look here: http://docs.unity3d.com/Documentation/Components/class-CharacterController.html
Answer by t-pedrob · Jul 15, 2012 at 11:18 PM
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; } }
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); } }
Answer by t-pedrob · Jul 16, 2012 at 03:27 PM
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); } }
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.$$anonymous$$ove(movementCurrentDirection * Time.deltaTime); } ...
Your answer
Follow this Question
Related Questions
GameObject moving forward depending on its orientation? 2 Answers
Player rotating after wall collision 1 Answer
how do i correctly use a box collider 0 Answers
Simple Colliders Question 1 Answer