Search code examples
c#unity-game-enginequaternionsraycasting

How do I point a gameobject towards another one, while it's rotating around a moving player?


Im making a space exploration game and I'm trying to have an arrow rotating around the player, pointing towards the sun in the center of the level. This is to make the game more readable. The "arrow" is for now just a cylinder with a sphere on it - with the sphere representing the arrow point. The rotation around the player is working, but I can't get it to point towards the sun, consistently. As seen in the image here, the arrow is pointing almost opposite of where I want it to.

Left to right : Sun, Arrow, Player

The code I'm using is as follows

    playerPos = transform.position;
    sunPos = sun.transform.position;

    // Cast ray from player to sun
    Ray ray = new Ray(playerPos, sunPos - playerPos);
    RaycastHit hitInfo;

    if (Physics.Raycast(ray, out hitInfo, 400, mask))
        Debug.DrawLine(ray.origin, sunPos, Color.green);
    Debug.Log("Distance" + hitInfo.distance);
    
    // Rotate arrow around player.
    arrow.transform.position = playerPos + ray.direction.normalized*2;
    // Point arrow towards sun. This is not working
    arrow.transform.rotation = Quaternion.FromToRotation(gameObject.transform.position, sunPos);

In addition to Quaternion.FromToRotation I have also tried using LookAt, which also gave me weird results. (I tried all the different up directions, i.e. LookAt(sun, Vector3.left) and (sun, Vector3.back), etc. Hoping some clever minds can help. Thanks in advance.


Solution

  • Theory

    You can use

    Quaternion.FormToRotation

    It create a quaternion (thing who handle the rotation of your gameobject) by giving a direction vector and the "0" vector. With these informations it'll know how to rotate your transform.

    Exemple

    I would do something like :

    Vector3 direction = sunPos - playerPos;
    transform.rotation = Quaternion.FromToRotation(direction, Vector3.right);
    

    Vector3.right = (1f,0f,0f) and you should use the standard direction of your arrow. For exemple if when arrow have no rotation it point up (0f,1f,0f), you should use Vector3.up insteed.

    As I said on comment you don't need raycast for this. (Maybe you need it later on your code)

    Vector3 delta = sunPos - playerPos;
    Vector3 direction = delta.normalized;
    float distance = delta.magnitude;