I’m doing some sort of a planetary gravity except I don’t have planets and my player object (a ball) can step anywhere. The gravity thing works great but I’m having some trouble rotating the camera properly.
Now what I have is a camera parent object which position (only position) strictly duplicates the player’s position. The rotation changes according to the normal of the polygon the player is stepping on.
I first get the average of the normals, then I use Quaternion.FromToRotation(Vector3.up, avgNormals); to get a rotation which will point with the y away from the normal and then pass it to the camera object (a variable named correctRotation). Then in the camera object I have this: transform.rotation = Quaternion.Lerp(transform.rotation, correctRotation, Time.deltaTime*5);
This thing works almost great but in some cases I get weird rotations on the Y axis with an unknown to me reason. I’ve showed this in the video below, because I can’t really explain it better.
I tried different things so far and none of them had effect. My last try was to put this:
transform.localRotation.y = 0;
after the Quaternion.Lerp function.
I guess I don’t fully understand how rotations work in Unity.
I already tried that before posting. The effect was absolutely the same. I also tried to look at the scene in the editor while playing and see how the camera object’s axis changes. it just rotates itself around the y axis (exactly what it looks like in the game)
It’s not the track, it’s the rotation. For example if the object has it’s transform rotated in world X on 90 degrees and then I try to rotate it locally on it’s Z (which after the X rotation has now become the world’s Y), the object rotates around it’s local Y coordinate. This also happens when I roll the ball on the upside down side of the platforms. The axes get messed up and the camera starts to rotate on it’s Y. The problem is that this object is not a child of anything so I can’t just set localRotation.y to 0 or localEulerAngles to 0.
Just sharing my observations if that is of any help
Yes, of course. I’ll just try to recreate it and explain.
The whole group of game objects is NOT parented to the player. It’s completely apart from it, but sticks to it’s position using a script.
- BallCamera (this is the object I'm trying to rotate)
-XGuide (this object rotates around it's local Y axis to achieve horizontal rotation)
-YGuide (this object rotates around it's local X axis to achieve vertical rotation)
-Main Camera (the camera itself it's away from the YGuide so I get an orbit effect)
I need to keep the XGuide and YGuide apart and not merge their functions into one object. I collect important information from both of them separately.
Have you checked if some script is attached to the camera and gives the WoW kind of camera movement ? Whenever an object is place between the target and the camera, the camera orbit to avoid the obstacle… it looks like this kind of script (standard asset)
Nah. I do have a script that casts a ray from the camera and repositions the camera if there’s an obstacle in the way, but this cannot be the problem.
Here, let’s summarize my code so everyone can test and see what happens:
function OnCollisionStay(col : Collision){
//Let's get the average of the collision normals
var avgNormals : Vector3;
for(i=0; i<col.contacts.length; i++){
avgNormals += col.contacts[i].normal;
}
avgNormals/=col.contacts.length
//Then create a rotation from this
var correctRotation : Quaternion = Quaternion.FromToRotation(Vector3.up, avgNormals);
//And set the rotation
transform.rotation = Quaternion.Lerp(transform.rotation, correctRotation, Time.deltaTime*5);
}
Note that this is not the real script. In my game, the player object calculates the normals and the rotation and then passes them to the camera object, which rotates itself. However the operations are no different than the ones in my game and you are likely to get the same problem. Try to make a scene similar to mine (from the video) with planes and test it with a cube. It is going to rotate on it’s local Y axis at some point. You can also try to print the correctRotation in the console.
I think the Quaternion.FromToRotation function is a bit misleading in Unity’s docs because from what I’ve found it actually returns the ‘rotation movement’ to get from one rotation to another, not the final rotation itself. So you might try applying it to the current rotation (kind of like adding vectors to get a new position/direction)
// Calculate rotation from the camera's up instead
var rotationAdjustment : Quaternion = Quaternion.FromToRotation(transform.up, avgNormals);
// Apply the adjustment to the current rotation
var correctRotation : Quaternion = rotationAdjustment * transform.rotation;
// Smoothly change the rotation towards the correct rotation
transform.rotation = Quaternion.RotateTowards(transform.rotation, correctRotation, rotationSpeed * Time.deltaTime);
Hey, thanks for joining ! I tried it and the camera behaves pretty randomly. I tried several variations of your suggestion, but none of them gave a different effect. Did you see the video? The gameobject just cannot rotate itself only around it’s X and Z axes. At some point it needs to be rotated on it’s Y axis. If this object was a child of another object, I could have done it like this: transform.localEulerAngles.y = 0 (I guess).
Maybe if we can alter the output from FromToRotation so it doesn’t alter the Y rotation, relative to it’s coordinate system in anyway.
…or just lock the object’s local Y rotation axis somehow.
I still can’t solve this problem. And no, what I thought was wrong. Making the rotating camera object a child of another object and modifying it’s local rotation DOES NOT work :
Sorry, tripple posting but I really need some support. This is going to be one of the main features of our small game and if I can’t get it to work, I won’t be able to proceed with the development.
I’m sure, that there’s people who have done such things before. I wonder if they’ve had the same problems…
This looks exactly like something I’m programming right now. I’m trying to get the player walk on walls in every rotation possible, but I always get issues with the normals. But I was wondering if I could look into your script for reference?