- Home /
Orienting character to walls and ceiling
I'm trying to make an AI object move "around" a vertical 2D room (y = up) while keeping its base (feet) oriented / aligned to the current surface. So as it moves around the room, its base would align to the floor -> right wall -> ceiling -> left wall -> floor etc...
Update: Based on answers so far, I came up with the following script and attached it to a sphere. When the sphere hits the right wall, it rotates 90 degrees on the z-axis and moves up the wall (correct!). But when it hits the ceiling, it rotates back to zero and then gets stuck in the corner flipping between 0 and 90 instead of adding 90 to the z to get 180 (upside down).
private var thisTransform : Transform;
function Start() { thisTransform = transform; }
function Update() { thisTransform.Translate (Vector3.right Time.deltaTime 2.0); CheckCollide(); }
function CheckCollide() { var hit : RaycastHit; var dirRight = thisTransform.TransformDirection (Vector3.right); var castPos = Vector3(thisTransform.position.x + 0.5, thisTransform.position.y + 0.5, thisTransform.position.z);
if (Physics.Raycast (castPos, dirRight, hit, 1)) {
var hitRotation = Quaternion.FromToRotation(-Vector3.up, hit.normal);
thisTransform.rotation = hitRotation;
}
}
Even if it did work, I think this approach is incorrect. What I need is for the object to recognize which surface it's on and then rotate accordingly. So if it's on the ceiling then the Z rotation should be 180 regardless of its angle when it collided with the ceiling. If it collides with the floor the rotation should be zero, etc. Also it shouldn't care what direction it's moving in. I hope this makes sense.
Note I plan to have several of these guys moving around the room at the same time, so modifying the global gravity isn't an option.
Answer by duck · Dec 05, 2009 at 12:17 AM
This is how you align an object to a surface normal (or hit normal):
var hitRotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
transform.rotation = hitRotation;
Thanks, I've seen similar examples in the forums and I've tried them (and your code) but my character isn't rotating properly. When translating forward along the X axis into a 90 degree wall, it rotates 180 on the Y and 180 on the Z. I think that I'm not calculating the hit.normal correctly. How should the rest of the script look so that I'm casting my raycast in the proper direction and getting the correct normal?
Answer by Brian-Kehrer · Dec 04, 2009 at 10:49 PM
If you detect the normals of the object your character is colliding with, you can use that as the orientation direction.
You could try raycasting, and using Raycasthit.normal
I'd like to use Raycasthit.normal, but so far I haven't found a good example of how to rotate the object to match the normal.
Answer by runevision · Dec 08, 2009 at 09:49 AM
The other answers answer well how to align an object to a normal.
Since it still doesn't seem to work for you, here are some things you can consider for trouble-shooting:
You can use Debug.DrawRay to draw the ray you are using for the raycast for debugging purposes. This is very helpful to make sure you are casting the ray from the right position and in the right direction.
If the ray starts from a position inside the (player/ball) object itself, you need to use a layermask so that the ray doesn't collide with the object itself. You can put either the object itself in a special layer, or the environment. The important part is that they shouldn't be in the same layer. Also see the helpful discussion on layermasks here.
Your answer
Follow this Question
Related Questions
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
How to get Quaternion.FromToRotation and hit.normal to allow the Y-axis to not be set to 0 4 Answers
Only assignment, call, increment, decrement, and new object expressions can be used as a statement 1 Answer
Conform mesh to arbitrary surfaces? 3 Answers