Bug place an enemy behind a walkable layer

if you place an enemy behind a walkable surface you can’t walk there… it only detects the enemy behind the surface.

This is a late response but I noticed this too because I had an “enemy” right next to an elevated walkable block. The bug is caused because we use a foreach loop in CameraRaycaster and search for an enemy layer BEFORE searching for a walkable layer, so its ignoring the walkable surface and just detecting the enemy behind it.

To fix this I got rid of the array and the foreach loop. Instead of checking for 1 layer at a time using the “layer” parameter we pass in, I check for both at the same time using a bitwise OR.

int layer1 = (int)Layer.Enemy;
int layer2 = (int)Layer.Walkable;
int layerMask = (1 << layer1) | (1 << layer2);

Also had to change the assignment of m_layerHit in the update since “layer” doesnt exist anymore.

m_layerHit = (Layer)hit.Value.transform.gameObject.layer;
1 Like

With the changes seen in the previous post, I have a puzzling issue when I try to get the m_layerHit value
from the other scripts.

Here is my Update method in CameraRaycaster(), with enough logs to see what’s happening:

void Update()
    {
        var hit = RaycastForLayer();
        if (hit.HasValue)
        {
            Debug.Log("CameraRaycaster: HIT HAS VALUE");
            m_hit = hit.Value;
            Debug.Log("CameraRaycaster: m_hit = " + m_hit);
            m_layerHit = (Layer)hit.Value.transform.gameObject.layer;
            Debug.Log("CameraRaycaster: m_layerHit = " + m_layerHit);
        }
        // Otherwise return a hit with default values
        m_hit.distance = distanceToBackground;
        m_layerHit = Layer.RaycastEndStop;
    }

And here is the FixedUpdate() from PlayerMovement(), unchanged from the course:

private void FixedUpdate()
    {
        if (Input.GetMouseButton(0))
        {
            Debug.Log("PlayerMovement: raycast hit object with name: " + cameraRaycaster.hit.transform.gameObject.name.ToString());
            Debug.Log("PlayerMovement: cameraRaycaster.layerHit: " + cameraRaycaster.layerHit);
          
            switch (cameraRaycaster.layerHit)
            {
                case Layer.Walkable:
                    {
                        currentClickTarget = cameraRaycaster.hit.point;
                        break;
                    }
                case Layer.Enemy:
                    {
                        break;
                    }
                default:
                {
                    Debug.Log("PlayerMovement: Unexpected Layer");
                    break;
                }
            }
        }

With this code, when pointing the ground, I see that m_layerHit = Walkable as expected.
BUT in PlayerMovement(), I see that cameraRaycaster.layerHit = RaycastEndStop, while in the same script I can properly access cameraRaycaster.hit and get the name Ground of the hit object.

Unity_2018-08-30_17-37-42

Any idea? I am pulling my hair on this for quite some time aleady :slight_smile:

Fortunately there is a workaround: instead of using a getter to get layerHit from cameraRaycaster, we can access the layer from the hit directly.
In other words, in the switch statement of PlayerMovement(), we do

switch ((Layer)cameraRaycaster.hit.transform.gameObject.layer)

instead of

switch (cameraRaycaster.layerHit)

EDIT: The workaround breaks the default cases where we need m_layerHit = Layer.RaycastEndStop
since we don’t use layerHit anymore. I’ll rollback for now. Hope @ben comes back to this later in the course :slight_smile:

Privacy & Terms