1
\$\begingroup\$

Essentially, in my game, I have 3 objects: a player, a shield and a puck. I want to have the shield orbit the player to automatically face the puck. (So the position will change with the rotation).

Transform.LookAt() works for having the shield look at the puck, but I can't seem to figure out the mathematical wizardry required to apply that rotation to the relative position of the player.

public class Shield : MonoBehaviour
{
    [SerializeField]
    private GameObject playerObject;

    private GameObject puck;
    private Vector3 offset;
    
    void Start()
    {
        GetPuckObject();
        offset = transform.position - playerObject.transform.position;
    }
    
    void LateUpdate()
    {
        transform.position = playerObject.transform.position + offset;

        if (!puck)
        {
            if (!GetPuckObject())
                return;
        }
        
        transform.LookAt(puck.transform);
    }

    bool GetPuckObject()
    {
        puck = GameObject.FindWithTag("Puck");
        return puck;
    }
} 

I feel so dumb for asking for help with this and I'm sure it's been asked before but I can't find anything which yields the behaviour I describe (possibly because I'm struggling to describe it). I think it's a case of translating the rotation to a position but not sure how to approach this.

Edit
This moves in relation to the rotation but doesn't work properly past 180 degrees (and is questionable before that)

  void LateUpdate()
    {
        if (!puck)
        {
            transform.position = playerObject.transform.position + offset;
            if (!GetPuckObject())
                return;
        }
        transform.position = playerObject.transform.position + offset;
        Quaternion lookRotation = Quaternion.LookRotation(puck.transform.position - transform.position);
        transform.rotation = lookRotation;
        transform.Translate(transform.forward);
        Debug.Log(transform.forward);
    }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I suspect a diagram would help here. \$\endgroup\$
    – Adam B
    May 28, 2022 at 5:54

1 Answer 1

2
\$\begingroup\$

The relative distance between the shield and the player is a fixed length instead of a fixed offset. Record this fixed length and calculate the position according to the rotation.

enter image description here

public class Shield : MonoBehaviour
{
    [SerializeField]
    private GameObject playerObject;

    private GameObject puck;
    private float offset;

    void Start()
    {
        GetPuckObject();
    }

    void LateUpdate()
    {
        if (!puck)
        {
            if (!GetPuckObject())
                return;
        }
        var lookRotation = Quaternion.LookRotation(puck.transform.position - transform.position);
        transform.position = playerObject.transform.position + lookRotation * (Vector3.forward * offset);
        transform.rotation = lookRotation;
    }

    bool GetPuckObject()
    {
        puck = GameObject.FindWithTag("Puck");
        offset = (transform.position - playerObject.transform.position).magnitude;
        return puck;
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .