Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] Help with vector?

Discussion in 'Scripting' started by Rusoski, Sep 21, 2017.

  1. Rusoski

    Rusoski

    Joined:
    Nov 6, 2013
    Posts:
    63
    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):
    1. if (Input.GetKey(KeyCode.W))
    2. {
    3.                 Quaternion q = Quaternion.LookRotation(Camera.main.transform.forward, cameraPivot.up);
    4.                 transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * speed);
    5.                 moving = true;
    6. }
    7.  
    8. if (moving)
    9. {
    10.                 rb.AddRelativeForce(Vector3.forward * force, ForceMode.Force);
    11. }
    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):
    1. using UnityEngine;
    2.  
    3. public class CameraAlignment : MonoBehaviour
    4. {
    5.     float alignSpeed = 10f;
    6.  
    7.     void FixedUpdate()
    8.     {
    9.         foreach (GameObject go in GameObject.FindGameObjectsWithTag("Planet"))
    10.         {
    11.             if (go.activeSelf)
    12.             {
    13.                 float atmosthereRadius = go.GetComponent<Planet>().atmosphere;
    14.  
    15.                 float distance = Vector3.Distance(go.transform.position, transform.position);
    16.  
    17.                 if (distance <= atmosthereRadius)
    18.                 {
    19.                     //Align with planet
    20.                     Vector3 v = go.transform.position - transform.position;
    21.                     Quaternion q = Quaternion.FromToRotation(-transform.up, v);
    22.                     Quaternion targetRotation = q * transform.rotation;
    23.                     transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * alignSpeed);
    24.                 }
    25.                 else
    26.                 {
    27.                     Vector3 targetPoint = new Vector3(0f, 0f, 0f);
    28.                     Quaternion targetRotation = Quaternion.LookRotation(targetPoint);
    29.                     transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * alignSpeed);
    30.                 }
    31.             }
    32.         }
    33.     }
    34. }
    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

     
    Last edited: Sep 21, 2017
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    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.
     
    Rusoski likes this.
  3. Rusoski

    Rusoski

    Joined:
    Nov 6, 2013
    Posts:
    63
    Yes, camera's theta angle is limited to -60° and 60°
     
  4. Rusoski

    Rusoski

    Joined:
    Nov 6, 2013
    Posts:
    63
    That did not help :/

    I am walking over a spherical surface
     
  5. lordconstant

    lordconstant

    Joined:
    Jul 4, 2013
    Posts:
    389
    You can use the cross product of the cameras right vector and the surface normal.

    Code (CSharp):
    1. Vector3 playerHeading = Vector3.Cross(cam.transform.right, surfaceNormal;
    Use a raycast to get the surface normal if you dont already know it.
     
    Rusoski likes this.
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    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.
     
    Rusoski likes this.
  7. Rusoski

    Rusoski

    Joined:
    Nov 6, 2013
    Posts:
    63
    Problem solved! Thank you so mutch! Works flawless! :D

    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
     
    Last edited: Sep 22, 2017