novice to intermediate Unity developer here. I've been hitting a pretty significant roadblock the past ~2 days concerning the raycast detection of objects with specific layers. I've been researching this issue quite a lot, and all the solutions I've found don't seem to reflect the strange issue I'm facing.
Basically, the problem follows this sequence of events:
- My player character has a vision cone shaped trigger mesh called 'InSightBox' which detects all objects with the tag 'Mob' and adds them to a List of colliders called 'MobsInRange'.
public List<Collider> mobsInRange;
public List<Collider> GetColliders()
{
return mobsInRange;
}
// Start is called before the first frame update
void Start()
{
mobsInRange = new List<Collider>();
}
// Update is called once per frame
void Update()
{
}
//add enemy with tag 'mob' to list
private void OnTriggerEnter(Collider other)
{
if(!mobsInRange.Contains(other) && other.tag == "Mob")
{
mobsInRange.Add(other);
}
}
//remove enemy with tag 'mob' to list
private void OnTriggerExit(Collider other)
{
if (mobsInRange.Contains(other) && other.tag == "Mob")
{
mobsInRange.Remove(other);
}
}
- This list is then fed up to the root/parent player game object containing everything relating to the player.
public Transform closestMob;
public List<Collider> mobs;
public Transform GetClosestEnemy()
{
Transform tMin = null;
float minDist = Mathf.Infinity;
Vector3 currentPos = transform.position;
foreach(Collider trans in mobs)
{
//find enemy with closest distance and set tMin to it. Method returns tMin
float dist = Vector3.Distance(trans.transform.position, currentPos);
if(dist < minDist)
{
tMin = trans.transform;
minDist = dist;
}
}
//Debug.Log(tMin);
return tMin;
}
- The player then uses a 'Look at' method to find the closest of all 'mobs' to the player. The player will set their forward transform to look at the closest mob.
Problem Step ---> 4) When the player raises their gun and attempts to shoot the closest enemy, a ray is cast with a layermask that looks only for objects on the layer 'Enemy', the 8th layer. When the ray detects the enemy, the enemy script should fire its 'TakeDamage' method which decreases the 'curHealth' variable by 8. Only problem is, the cast doesn't seem to detect the enemy object on the 'Enemy' layer.
LayerMask layerMask = 1 << 8;
void Fire()
{
//play the audio of the gunshot
StartCoroutine("SetPlaying");
RaycastHit hit;
//cast a ray from the player forward and check if the hit object is on layer 'Enemy'
if (Physics.Raycast(transform.position, transform.forward, out hit, Mathf.Infinity, layerMask))
{
//if hit object is an enemy, set its 'gotShot' bool to true
print("hit enemy");
closestMob.GetComponent<EnemyBase>().gotShot = true;
}
//play gunshot sound and stop player from turning
source.clip = fireSound;
source.PlayOneShot(fireSound, gunshotVolumeScale);
turnSpeed = 0;
}
I'll also note that all the solutions I've seen to this issue are not working for me. I declared an int variable called 'layerMask' and initialized it in Awake() by bit shifting layer 8 into it (i.e. int layerMask = 1 << 8), but it still isn't detecting it. The enemy contains all that I belive it should need for this to work, including a rigidbody, a capsule collider, the associated scripts, as well as being on the 'Enemy' layer. This is where it gets weird (at least to my knowledge), when I invert the mask in the cast (~layerMask), it does exactly what I'd expect, and begins firing the code within the raycasts if statement when the player 'shoots' anything that doesn't have the 'Enemy' layer.
Any help would be suuuper appreciated as I'm getting to the point of slamming my face into the desk :/
Side Note: I'm getting to the point where I may just attach a 'fire range' cube trigger to my player and enabled it when the Fire() event is triggered, then have that check for game objects with the tag 'mob' as that kind of detection works most consistent to me.