Good day community! I need help getting a vector. Please first look at the image at the end of the post first to get the idea. The camera rotates arround a pivot, always looking at it. I got a vector N which is perpendicular to the surface (I use a Quaternion.Slerp() to align it) and I also got a V vector which point from the camera to the pivot. I need to get the player walking forward over the surface in to the direction the camera point to, my current code for this is: Code (CSharp): if (Input.GetKey(KeyCode.W)) { Quaternion q = Quaternion.LookRotation(Camera.main.transform.forward, cameraPivot.up); transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed); moving = true; } if (moving) { rb.AddRelativeForce(Vector3.forward * force, ForceMode.Force); } Problem with this is that if I look down, player moves down into the ground (with gravity disabled) and if I look up, it flyes into the sky, the movement should only be limited to Z and X axis. I know that I can align the plaver with the direction of the pivot, and instead of rotating the camera arround the pivot, rotate the pivot, so the camera will also rotate,but I can not do this because of the script I got to align the pivot with the surface which is: Code (CSharp): using UnityEngine; public class CameraAlignment : MonoBehaviour { float alignSpeed = 10f; void FixedUpdate() { foreach (GameObject go in GameObject.FindGameObjectsWithTag("Planet")) { if (go.activeSelf) { float atmosthereRadius = go.GetComponent<Planet>().atmosphere; float distance = Vector3.Distance(go.transform.position, transform.position); if (distance <= atmosthereRadius) { //Align with planet Vector3 v = go.transform.position - transform.position; Quaternion q = Quaternion.FromToRotation(-transform.up, v); Quaternion targetRotation = q * transform.rotation; transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * alignSpeed); } else { Vector3 targetPoint = new Vector3(0f, 0f, 0f); Quaternion targetRotation = Quaternion.LookRotation(targetPoint); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * alignSpeed); } } } } } I don't know If It is posible to get vector V´ from V and N, this means that V´ is perpendicular to N, but points in the same direction that V but only over N's Z and X axis, excluding the inclication. The V´ vector should basicaly rotate arround N along the Y axis. If the image is not shown, this is the link: https://image.ibb.co/noAvZQ/IMG_20170921_151241495.jpg
Just take your vector V, set V.y = 0, and then normalize it with V.Normalize(). This will work for all cases except where V.x == V.z == 0, i.e., pointing directly up or down. But in that case, the problem is ill defined anyway. You can (and probably should) avoid this case by limiting your camera angles.
You can use the cross product of the cameras right vector and the surface normal. Code (CSharp): Vector3 playerHeading = Vector3.Cross(cam.transform.right, surfaceNormal; Use a raycast to get the surface normal if you dont already know it.
Handily enough, the normal at a point on the sphere is the normal of the coordinate of that point in the local sphere's coordinate system! Also, it might be useful to keep the player always pointing with his feet at the center of your earth, and have a separate sub-transform that the camera is on, and allow that transform to move up/down while the player himself still remains "standing upright" wherever he is on the globe.
Problem solved! Thank you so mutch! Works flawless! I am not using a RayCast, instead I use the magnitude of the vector, to simulate the "Atmosphere", so i know whene I can align or just orbit