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;
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.
Any idea? I am pulling my hair on this for quite some time aleady
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