VR的100天:Unity中的第13天攻击敌人,健康系统和死亡动画

欢迎回到虚拟现实100天的第13天! 上一次,我们创建了使用Nav Mesh Agent来帮助我们移动敌方骑士的敌人动作。

我们添加了一个触发器对撞机,以在敌人靠近玩家时帮助启动攻击动画。

最后,我们在骑士的身体上添加了一个网格碰撞器,因此当它在攻击动画中接触到玩家时,我们将能够使用伤害逻辑。

今天,我们将继续为玩家实施射击逻辑,并修复令人讨厌的错误,即当玩家与其他对撞机接触后,玩家将永远移动。

解决漂移问题

我首先想到的问题是播放器的刚体组件一定有问题。

如果我们还记得的话,刚体是我们玩家的Unity物理引擎。

根据RigidBody的文档,当任何东西与我们的播放器发生碰撞时,物理引擎就会向我们施加速度。

此时,我们有2个选项:

  • 发生碰撞后将速度设置为0
  • 提高阻力值

什么是阻力? 我也不是第一次遇到它,也没有真正理解它,但是经过更多的研究,特别是在Rigidbody2D中阅读了它。拖动拖动是对象因摩擦而减速的时间。 具体而言,越高对我们越快,我们减慢速度。

RigidBody中的拖动值从0切换为5。

我不确定该值代表什么,但是在我们的速度从未因阻力值而因摩擦而减小之前,但是在添加一个后,随着时间的推移,我们将开始放慢速度。

游戏中添加敌人射击

解决了阻力问题之后,我们终于回到游戏的主要部分:射击敌人。

我们将必须在两个地方添加代码:EnemyHealth和EnemyMovement。

EnemyHealth

 使用UnityEngine; 
 公共课程EnemyHealth:MonoBehaviour 
{
公众持股量= 10;
 私人Animator _animator; 
 无效Start() 
{
_animator = GetComponent ();
}

公共无效TakeDamage(浮动损坏)
{
如果(健康<= 0)
{
返回;
}
 健康-=伤害; 
如果(健康<= 0)
{
死亡();
}
}
 私人void Death() 
{
_animator.SetTrigger(“ Death”);
}
}

这是我们添加的代码的新流程:

  1. 在Start()中,我们实例化Animator,稍后将使用它播放死亡动画。
  2. 当敌人死亡时,在TakeDamage()(从PlayerShootingController调用)中,我们将其称为Death()。
  3. 在Death()中,我们设置死亡触发器以使骑士播放死亡动画。

接下来,我们需要对EnemyMovement进行快速更改,以阻止我们的骑士死后移动。

 使用UnityEngine; 
使用UnityEngine.AI;
 公共课程EnemyMovement:MonoBehaviour 
{
私有NavMeshAgent _nav;
私人变形_player;
私人EnemyHealth _enemyHealth;
 无效开始() 
{
_nav = GetComponent ();
_player = GameObject.FindGameObjectWithTag(“ Player”)。transform;
_enemyHealth = GetComponent ();
}

无效更新()
{
如果(_enemyHealth.Health> 0)
{
_nav.SetDestination(_player.position);
}
其他
{
_nav.enabled = false;
}
}
}

这是代码流:

  1. 在Start()中,我们获取EnemyHealth脚本,以便我们可以访问骑士的健康状况。
  2. 在Update()中,如果骑士死了,我们将禁用Nav Mesh Agent,否则它将像往常一样继续行走。

现在,当我们玩游戏时,骑士在击败后会进入死亡状态,如下所示:

改善射击技巧

此时,您可能会注意到一个问题……。

…好吧,我知道有很多问题,但是我指的是两个具体问题。

  1. 每当我们射击时,骑士几乎都会死
  2. 当我们射击时,敌人真的没有发生任何事情,使我们感到我们甚至射击了他们

所以我们要解决这些问题

增加拍摄延迟

现在,每当Update()检测到鼠标被按下时,我们总是向敌人的骑士射击。

因此,让我们为Player Shooting Controller脚本添加一个延迟。

 使用UnityEngine; 
 公共类PlayerShootingController:MonoBehaviour 
{
公共浮动范围= 100;
公共浮动ShootingDelay = 0.1f;
 私人相机_camera; 
专用ParticleSystem _particle;
私有LayerMask _shootableMask;
私有浮点数_timer;
 无效的开始(){ 
_camera = Camera.main;
_particle = GetComponentInChildren ();
Cursor.lockState = CursorLockMode.Locked;
_shootableMask = LayerMask.GetMask(“ Shootable”);
_timer = 0;
}

无效更新()
{
_timer + = Time.deltaTime;
 如果(Input.GetMouseButton(0)&& _timer> = ShootingDelay) 
{
射击();
}
}
 私人void Shoot() 
{
_timer = 0;
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit =新的RaycastHit();
 如果(Physics.Raycast(ray,out hit,Range,_shootableMask)) 
{
print(“ hit” + hit.collider.gameObject);
_particle.Play();
  EnemyHealth health = hit.collider.GetComponent (); 
如果(健康!= null)
{
health.TakeDamage(1);
}
}
}
}

这是我们添加内容的逻辑:

  1. 我们创建了时间变量来确定再次拍摄之前必须等待的时间
  2. 在Update()中,如果我们等待了足够长的时间,我们可以再次触发
  3. 旁注:我决定将所有拍摄代码移至Shoot()
  4. 在Shoot()内部,因为玩家被解雇了,所以我们将重置计时器并开始等待,直到我们可以再次射击为止。

添加玩家命中效果

设置游戏对象

当我们射击敌人的骑士时,什么也没有发生。 他只会无视你,继续向你走去。

我们可以做很多事情来使它变得更好:

  1. 添加声音效果
  2. 增加伤害血液效果
  3. 推他回来
  4. 上述所有的

1)最终会添加,2)可能会完成,但是3)是我要实现的。

每次射击骑士时,我们都想将其推回去。 这样,如果他们中的一群人涌向我们,我们将不得不管理先射击哪一个。

这个小功能花了很长时间解决。

问题

每当我们射击敌人时,我们都想将其推回去,但是,Nav Mesh Agent会覆盖我们尝试的任何更改。 具体来说,骑士将永远继续前进。

解决方案

我们编写了一些代码,将Nav Mesh Agent的速度更改为向后几个单位。

但是,当我这样做时,骑士继续向前奔跑!

为什么?

这是一个很好的问题,我仍在调查,希望明天能找到解决方案。

第13天结束

今天是我第一次遇到一个我一天都无法解决的问题。

我希望随着我们开始跳得越来越深,这种情况会越来越普遍。

话虽如此,今天我们修复了玩家的漂移问题,方法是使用拖曳并添加敌人死亡动画,以防他们耗尽生命。

明天我将继续研究如何将敌人退回。

第14天见! 或者只要我能弄清楚这个击退问题!

原始日13

访问Unity VR开发的主要100天页面

访问我的主页