Make collider work only if player faced in certain direction.

Just trying to make a collider work only if player is faced in a certain direction. Not sure where I’m going wrong. Any advice would be great. Hopefully you can see what I mean from the code.

public class ScientistVanish : MonoBehaviour {

    public GameObject Scientist;
    public GameObject Pplayer;
    public float yRotation = -3;



    // Use this for initialization
    void Start () {
       
    }
   
    void OnTriggerEnter (Collider Pplayer) {
        if (Pplayer.gameObject.tag == "Player" && Pplayer.transform.rotation.y < yRotation)
        {
            Scientist.SetActive(false);
        }
       
    }
}
  1. use CompareTag, not tag ==… nothing to do with your problem, it’s just far more performant

  2. Why is there a field named ‘Pplayer’ and you also have a parameter called ‘Pplayer’? This makes for confusing naming conventions.

  3. transform.rotation returns a Quaternion, the y component is going to be a value from -1 to 1. You may want ‘eulerAngles’ instead… but even then, there’s no guarantee that the value will come out in the range you want since 270 and -90 are the same thing.

1 Like

Cheers thanks for your insight.

I would use a Dot product.

Dot(currentForward,targetForward) basically means it performs a dot product comparison on how similar the currentforward is with the targetForward (in this example I’ll use east). Dot will return a value from 1 to -1, where 1 is if the player is looking in the exact same direction (looking east), -1 means the player is looking in the exact opposite direction (looking west), and where 0 means they are looking exactly perpendicular (ie. north or south).

I prefer to use angle limits as they are more intuitive in the inspector (when you’re looking for that specific angle), but in code I’ll convert that value to a Dot Threshold and compare against that.

    [Range(0,180)] public float angle = 90;
    public Gameobject Scientist;

    
    void OnTriggerEnter (Collider player) 
    {
        if (!player.CompareTag("Player")) return;

        if(!LookingAt(player.transform, Scientist.transform, angle))
        {
            Scientist.SetActive(false);
        }
    }

    private bool LookingAt(Transform looker, Transform target, float angleLimit)
    {
        //find rotation that looks directly at target
        var targetLook = Quaternion.LookRotation(target.position - looker.position, looker.up);

        // even if clamped in the inspector, this ensures no shenanigans if the value was changed by code
        angleLimit = Mathf.PingPong(angleLimit,180);  

        // calc target Dot product threshold from provided angle
        var dot          = Mathf.Acos(angleLimit * Mathf.Deg2Rad); 

        return Quaternion.Dot(looker.rotation,targetLook)>=dot;
    }
1 Like

Thanks for taking the time to give me some help and more education.