TorqTB (2) [Avatar] Offline
#1
From reading the Unity documentation, as well as test results.
Both vectors used in Vector3.Dot need to be normalized, to get an accurate angle

For example in Listing 9.3 Adjusting DeviceOperator to only operate devices that player faces:
Vector3.Dot(transform.forward, direction) > .5f)


Should instead be:
Vector3.Dot(transform.forward, direction.normalized) > .5f)


Otherwise as the direction vector maginitude increases we start getting Cosine values greater then one. Even though the angle is outside the desired field of view.
jhocking (200) [Avatar] Offline
#2
oops great catch, I missed that subtlety. In this particular case it doesn't matter too much because you can't be far away (only within the overlap sphere) but you are correct about this vector needing to be normalized.
TorqTB (2) [Avatar] Offline
#3
Thanks for confirming. I was not sure if I was missing some esoteric concept that caused it to not matter.

In beginning of Chapter 12, I used DOT to update WanderingAI. To give the enemy a wider vision as suggested in the book.
And this required using the normalization to function correctly.


    private void Fire() {
        Vector3 vectorToPlayer = (_playerTransform.position - transform.position);
        
        // Check if within Line of Sight Distance
        if (vectorToPlayer.sqrMagnitude > Mathf.Pow(fireRange, 2))
            return;
       
        // Check if within Enemy viewing angle
        if (Vector3.Dot(vectorToPlayer.normalized, transform.forward) < fireCosAngle)
            return;
        
        // Create ray from this object, towards the direct being faced
        Ray ray = new Ray(transform.position, vectorToPlayer);

        // Give ray size corresponding to object width
        RaycastHit hit;
        if (Physics.SphereCast(ray, 0.6f, out hit))
        {        
            GameObject hitObject = hit.transform.gameObject;
            if (hitObject.GetComponent<PlayerCharacter>())
            {
                // Shoot at player
                if (_fireball == null)
                {
                    _fireball = Instantiate(fireballPrefab) as GameObject;                   
                    _fireball.transform.position = transform.position + ray.direction * 1.5f;                    
                    _fireball.transform.rotation = Quaternion.LookRotation(ray.direction);
                }
            }
        }                    
    }