Hi, I’m making a 2D game. I need the enemy to be able to spot the player and shoot, I did it with Physics2d.Raycast, but if there is another layer in front of the enemy, it still detects the player and shoots, although the damage is not passed through the other layer to the player, but the render line I made still shoots and hits the obstacle. I need the enemy to be unable to see through the other layer. If the code is needed, I provide it.
If you already use Raycast, then you are probably doing something minor wrong. You should only check the first hit, and obviously make sure that you can hit other things than the player. Thus the raycast should hit the wall if it’s in front of the player and if that’s the case you couldnt shoot/detect the player. As soon as the placer moves in front of the wall, the raycast would hit the player and you would detect him. Your approach is fine, so you probably either get all objects hit by the ray and check if the player is contained (meaning it doesnt matter if it hits the wall), or you did use some collision layer that only contains the player, thus ignoring anything else anyways. Should be one of these two.
You need to pass a layermask with the obstacle and the player in your Raycast call.
Thanks for your answer
I think that’s the second thing you said. The obstacle and player have different layers. Now enemy is shooting trought obstacles(obstacles contains collider and layer) and deals damage i think that is due to the fact that i changedthe script a little. In the enemyshooting script:
public const float Seconds = 0.02f;
public LayerMask PlayerLayer;
public Transform firePoint;
public int damage = 40;
public GameObject impactEffect;
public LineRenderer lineRenderer;
public int shootDist;
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
if (Physics2D.Raycast(firePoint.position, firePoint.right,shootDist, PlayerLayer))
{
StartCoroutine(Shoot1());
Debug.Log("shoot");
}
}
IEnumerator Shoot1()
{
RaycastHit2D hitInfo = Physics2D.Raycast(firePoint.position, firePoint.right, shootDist, PlayerLayer);
if (hitInfo)
{
HealthBar health = hitInfo.transform.GetComponent<HealthBar>();
if (health != null)
{
health.TakeDamage(damage);
}
Instantiate(impactEffect, hitInfo.point, Quaternion.identity);
lineRenderer.SetPosition(0, firePoint.position);
lineRenderer.SetPosition(1, hitInfo.point);
}
else
{
lineRenderer.SetPosition(0, firePoint.position);
lineRenderer.SetPosition(1, firePoint.position + firePoint.right * 100);
}
lineRenderer.enabled = true;
yield return new WaitForSeconds(Seconds);
lineRenderer.enabled = false;
}
thank you for any response
Yeah, you are checking for ‘PlayerLayer’. You should either remove the layer completely (unless there are objects with an collider you can detect the player through, like maybe a window) or create a new layer that contains the player and all other things the ray interacts with (player, wall, ground, but not window for example).
Thanks,
Ok and then check for tag?
If you remove the layer completely you dont need to check for a tag or anything. Just take a look at the example:
You can call the method with different sets of parameters, it’s not required to add all of them. Thus you can just remove the layer and it will collide with everything that has a collider.
Thanks for answer. I don’t remove layer completely. I make layer for objects that I can hit with raycast.