VR的100天:Unity中修复游戏对象对撞机的第20天

欢迎回到第20天Unity开发的又一个激动人心的一天! 你相信吗? 我们是100天的1/5! 我希望这种势头能使我继续前进,直到我发货为止!

现在回首第19天,我们创建了一个可以使用的医疗系统,但是遇到了问题。

由于某种原因,即使我们经过攻击动画,对撞机也只会击中敌人一次。

今天,我们将解决这个问题。 所以,让我们开始吧!

问题在于我们在第12天为骑士创建的Mesh Collider。还记得吗?

那个站立的网状对撞机,实际上就是每次骑士攻击我们时我们都会与之碰撞的东西。

问题是网格碰撞器无法跟随模型的动画,因此当骑士第一次触摸我们时,网格物体可能会触摸我们,但是之后,我们(玩家)就不会被碰撞器向后推,网永远不会再碰我们。

这是说明问题的图片:

尽管骑士模型本身可能正在触碰我们,但我们的Mesh Collider却是静态的,不会移动。

这不好! 当骑士的拳头接触到玩家时,我们想伤害我们的玩家! 不是这个静态的网格对撞机!

要解决此问题,需要进行一些更改。

  1. 我们仍然需要我们的Mesh碰撞机。 这阻止了我们穿越敌人。 现在,我们遇到了一个问题,我们可以在骑士上行走,但是现在我们将解决此问题。
  2. 我们将在骑士手中增加一个Box Collider。 这样,我们就可以确定我们的玩家何时受到重击。

目前,我们无法移动网格,因为它位于父实体中。 根据这篇关于网格定位不正确的文章,我们将制作一个新的空对象并在其中添加网格碰撞器。

这对我们有用,因为我们只需要网格即可进行碰撞检测和光线投射以进行拍摄。

我们开始做吧!

最初,我们将Mesh Collider放置在我们的KnightPrefab游戏对象中。 让我们现在将其删除。

选择knightprefab ,单击鼠标右键,然后选择创建空 ,以制作一个新的游戏对象。 让我们将该对象重命名为Collider

选择Collider并向其中添加一个新的Mesh Collider组件。 对于“ 网格” ,选择“ 主体”以恢复我们的“骑士”模型。

您可能必须在自己周围移动对撞机 ,以使对撞机与我们的骑士相匹配,但是,最后您应该具有以下内容:

现在有了这个,我们不能只是走过骑士。

既然我们已经解决了网格对撞机问题,那么我们将解决最初的问题,即当敌人攻击我们时对他们造成伤害。

为此,我们将在骑士的拳头上增加盒子对撞机。 具体来说,在knightprefab中->臀部->脊柱->胸部-> L_shoulder / R_shoulder->一直到L_Wrist / R_Wrist。

对于每个盒子对撞机 ,我将盒子的比例设置为0.25以适合手的大小。

现在我们有了这个,我们需要将脚本附加到每个可以检测到碰撞的手模型上。 父对象的脚本无法为其子级检测到冲突。

同样重要的是,原始脚本EnemyAttack保持原样 ,因为我们需要访问位于父级中的动画师组件。

为了解决我们的问题,我们将代码的冲突部分从EnemyAttack移到名为FistCollider的新脚本中。

FistCollider将处理骑士拳头的碰撞,我们将在EnemyAttack脚本中获得结果。

这是我们的FistCollider脚本:

 使用UnityEngine;公共类FistCollider:MonoBehaviour
 {
    私人GameObject _player;
    私人布尔_collidedWithPlayer; 无效Start()
     {
         _player = GameObject.FindGameObjectWithTag(“ Player”);
         _collidedWithPlayer = false;
     } void OnCollisionEnter(Collision other)
     {
        如果(other.gameObject == _player)
         {
             _collidedWithPlayer = true;
         }
        打印(“输入与_player相撞”);
     } void OnCollisionExit(Collision other)
     {
        如果(other.gameObject == _player)
         {
             _collidedWithPlayer = false;
         }
         print(“退出与_player相撞”);
    公共布尔IsCollidingWithPlayer()
     {
         return _collidedWithPlayer;
     }
 } 

这是代码流:

  1. 像我们的EnemyAttack脚本一样,我们要访问我们的玩家游戏对象,并且要检查是否与敌人相撞。
  2. Start()中 ,确保实例化两个变量。
  3. OnCollisionEnter()OnCollisionExit()中,如果与我们发生冲突的是玩家,那么我们将设置布尔标志。 再一次,这与
  4. IsCollidingWithPlayer()中,我们会将布尔值_collidedWithPlayer交给任何调用它的人。 请注意,此功能是公共的,因此其他脚本可以访问此功能。 我们稍后将使用它。

让我们将脚本附加到L_WristR_Wrist。

现在,我们将部分碰撞代码从EnemyAttack移到了FistCollider ,让我们在EnemyAttack中使用FistCollider 。 这是代码:

 使用UnityEngine;
公共课程EnemyAttack:MonoBehaviour
 {
    公共FistCollider LeftFist;
    公共FistCollider RightFist; 私人Animator _animator;
    私人GameObject _player; 无效Awake()
     {
         _player = GameObject.FindGameObjectWithTag(“ Player”);
         _animator = GetComponent ();
     } void OnTriggerEnter(对撞机其他)
     {
        如果(other.gameObject == _player)
         {
             _animator.SetBool(“ IsNearPlayer”,true);
         }
         print(“使用_player输入触发器”);
     } void OnTriggerExit(Collider other)
     {
        如果(other.gameObject == _player)
         {
             _animator.SetBool(“ IsNearPlayer”,false);
         }
         print(“使用_player退出触发器”);
     } private void Attack()
     {
        如果(LeftFist.IsCollidingWithPlayer()|| RightFist.IsCollidingWithPlayer())
         {
             _player.GetComponent ()。TakeDamage(10);
         }
     }
 } 

这是我们代码中的更改:

  1. 首先,我们创建新的公共变量: LeftArmRightArm ,它们是我们刚刚创建的FistCollider脚本。
  2. 我们清理了很多代码,特别是Collision部分以及与之相关的所有内容。
  3. Attack()中,我们使用新的FistCollider与玩家发生碰撞,然后在触发动画中的攻击事件时,检查玩家是否被击中。 如果他们这样做(意味着骑士的拳头与玩家相撞),玩家将受到伤害。

完成脚本后,我们需要做的最后一件事就是确保将FirstCollider对象附加到播放器上。

我们可以将我们的游戏对象直接附加到该地点,脚本将被自动选择。

完成后,我们应该有以下内容:

ew,这是很多工作!

在过去的两天中,我们创建了健康系统,然后重新探视了敌方骑士的网状对撞机存在的一些问题,例如在它们上方行走而无法与玩家精确碰撞的情况。

我们还分离了具有攻击冲突功能的代码,同时仍使我们原来的冲突脚本正常运行。

既然我们终于可以为玩家带来健康,那么明天,我们要做的下一件事就是在玩家的生命值达到0时开始最终游戏状态。

在那之前,度过一个愉快的夜晚,我要睡觉了!

资料来源:第20天

访问Unity VR开发的100天主页。

访问我们的主页