unity3d 如何在Unity中将一个碰撞器阻挡在另一个碰撞器后面

2eafrhcq  于 2023-04-21  发布在  其他
关注(0)|答案(2)|浏览(522)

在2D Unity游戏中,有没有一种方法可以将一个碰撞器对象阻挡在另一个碰撞器对象后面?我在屏幕上有敌人行走的碰撞器,但如果敌人走在障碍物后面(它们有自己的对撞机),敌人的碰撞器仍然对玩家的子弹有React。所以基本上我只想在敌人没有在任何障碍后面的时候才暴露他们。目前我的子弹穿过障碍并探测到敌人。我把敌人和障碍物放在不同的UI面板和图层上,但这只是在视觉上区分它们。从碰撞的Angular 来看,我如何使一个(障碍物)优先于另一个(敌人)?

ttvkxqim

ttvkxqim1#

你可以使用光线投射的方法。你可以从玩家的位置向敌人的位置投射一条光线,如果它探测到中间有一堵墙,你就不允许他们射击。

public LayerMask wallsLayer;

bool HasPathFreeOfWalls(Transform player, Transform enemy, float reticleRadius)
{
  Vector2 direction = enemy.position - player.position;
  Vector2 origin = player.position + (direction.normalized) * reticleRadius;
  float distance = direction.magnitude - reticleRadius;

  RaycastHit2D rayHit = Physics2D.Raycast( origin , direction, distance, wallsLayer);

  return rayHit.transform == null; // if does not hit anything, it means that the path is free of walls
}

编辑以匹配游戏描述
一种方法是将所有碰撞器偏移到各自gameObject的枢轴点上方,如this
然后你在十字线周围投射一个CircleCast来检测那里的所有对象,并检查哪个对象具有最低的Y位置,这意味着那个对象在前面。像这样:

public LayerMask enemysAndWallsLayers;

bool HasEnemyInFront(Vector2 reticlePosition, float reticleRadius)
{
    RaycastHit2D[] enemysAndWallsHitted; // holds the results of the circle cast
    ContactFilter2D collisionFilter = new ContactFilter2D(); // filter user by the circleCast
    collisionFilter.layerMask = enemysAndWallsLayers;
    collisionFilter.useLayerMask = true;

    Physics2D.CircleCast(reticlePosition, reticleRadius, Vector2.zero, collisionFilter, enemysAndWallsHitted, 0);

    GameObject closestGameObject = null;
    float closestY = Mathf.Infinity;

    foreach(RaycastHit2D objHitted in enemysAndWallsHitted)
    {
        if(objHitted.transform.position.y < closestY)
        {
            closestY = objHitted.transform.position.y;
            closestGameObject = objHitted.transform?.gameobject;
        }
    }

    return closestGameObject != null && IsGameObjectEnemy(closestGameObject );
}

IsGameObjectEnemy()函数必须由你以一种你可以分辨它是敌人还是墙的方式来实现

1mrurvl1

1mrurvl12#

我评论了这一点,但我认为,因为它可能会解决你的问题,我会提供它作为一个答案。
在检查碰撞的功能上,把障碍检查放在敌人检查之前。例如:

if(collider.gameObejct.tag == "Barrier") {//Destroy object} 
else if(collider.gameObject.tag == "Enemy") {//Damage enemy}

这样它会先检查自己是否撞到了结界,如果撞到了结界,敌人就不会被夺走生命。
希望这对你有帮助。编码快乐!

相关问题