2nd and additional items are picked up fine but the first item, in this case, CaveFloor isn’t. Other scripts have the same problem. What am I doing wrong?
Best
J
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMODUnity;
using FMOD.Studio;
public class FootStep_Terrain_Manager : MonoBehaviour
{
private enum CURRENT_TERRAIN { CaveFloor, WoodFloor, StairFloor, WaterFloor };
[SerializeField]
private CURRENT_TERRAIN currentTerrain;
private EventInstance Footsteps;
private EventInstance FootLand;
public float Maxdistance = 10.0f;
private void Update()
{
DetermineTerrain();
Debug.DrawRay(this.transform.position, Vector3.down, Color.green);
}
private void DetermineTerrain()
{
RaycastHit[] hit;
hit = Physics.RaycastAll(transform.position, Vector3.down, Maxdistance);
foreach (RaycastHit rayhit in hit)
{
if (rayhit.transform.gameObject.layer == LayerMask.NameToLayer("CaveFloor"))
{
currentTerrain = CURRENT_TERRAIN.CaveFloor;
Debug.Log("Cavefloor");
}
else if (rayhit.transform.gameObject.layer == LayerMask.NameToLayer("WoodFloor")) //LayerMask.NameToLayer
{
currentTerrain = CURRENT_TERRAIN.WoodFloor;
Debug.Log("Wood");
//print(rayhit.transform.name);
}
else if (rayhit.transform.gameObject.layer == LayerMask.NameToLayer("StairFloor"))
{
currentTerrain = CURRENT_TERRAIN.StairFloor;
Debug.Log("Stair");
}
else if (rayhit.transform.gameObject.layer == LayerMask.NameToLayer("CaveFloor"))
{
currentTerrain = CURRENT_TERRAIN.CaveFloor;
Debug.Log("cave");
}
}
}
}
There can be two reasons for this, either the element is missing in the loop, or it is named differently than in the first condition. Just put the following code at the very beginning of the loop and see what will be displayed in the console (without conditions).
hey, one thing you can be sure of is that the foreach loop is iterating as expected. A couple of side notes first as it seems like an odd use of a raycastall + foreach loop in general:
it seems like you are interested in ONLY the last INDEXED hit that has one of those 4 layers. you can provide a layermask to the raycast and it will ONLY detect hits with the defined layers, this is more efficient and easy to work with in general.
you would then only be interested in the hit at the last index (or iterate backward in your version and end when first is found)
the order of the returned array is undefined according to Unity’s docs, so being interested in the last one doesnt necesarily mean that its the furthest one Unity - Scripting API: Physics.RaycastAll
if you are in fact interested only in the fursthest hit, consider reversing the source and destination of your raycast. then you would only care about the first hit, which can be attained by a regular Physics.Raycast (rather than RaycastAll)
to address your issue with the foreach loop, before any of the conditional layers checks, print out the hit.gameObject.layer. You will probably find a spelling mistake, or that you didnt set the layer properly.
if (rayhit.transform.gameObject.layer == LayerMask.NameToLayer("CaveFloor"))
{
currentTerrain = CURRENT_TERRAIN.CaveFloor;
Debug.Log("Cavefloor");
}
I don’t know what is causing what you’re experiencing but as was pointed out the foreach loop is not to blame. Adding some debug statements as a sanity check is always the first step.
BTW I think your code can be simplified quite a bit. It won’t necessarily fix your problem but there will be few lines of code to look at.
rayhit.transform.gameObject.layer should be able to be assigned to a variable but more importantly if you convert that to a string then each of the LayerMask.NameToLayer calls can be eliminated and you are simply comparing strings.
You could also (I assume) use the enum as a string insuring that the term matches and that you didn’t inadvertently type some string literal in wrong. And speaking of which I think your problem is that you are matching CaveFloor twice and never checking for WaterFloor.
Thanks, this is very helpful! Yes the script and my skills can deffo use some upgrading. And while the debug I used still doesn’t pick up the first item the suggested one does so I going to go with user error haha!