欢迎回到虚拟现实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”);
}
}
这是我们添加的代码的新流程:
- 在Start()中,我们实例化Animator,稍后将使用它播放死亡动画。
- 当敌人死亡时,在TakeDamage()(从PlayerShootingController调用)中,我们将其称为Death()。
- 在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;
}
}
}
这是代码流:
- 在Start()中,我们获取EnemyHealth脚本,以便我们可以访问骑士的健康状况。
- 在Update()中,如果骑士死了,我们将禁用Nav Mesh Agent,否则它将像往常一样继续行走。
现在,当我们玩游戏时,骑士在击败后会进入死亡状态,如下所示:
改善射击技巧
此时,您可能会注意到一个问题……。
…好吧,我知道有很多问题,但是我指的是两个具体问题。
- 每当我们射击时,骑士几乎都会死
- 当我们射击时,敌人真的没有发生任何事情,使我们感到我们甚至射击了他们
所以我们要解决这些问题
增加拍摄延迟
现在,每当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);
}
}
}
}
这是我们添加内容的逻辑:
- 我们创建了时间变量来确定再次拍摄之前必须等待的时间
- 在Update()中,如果我们等待了足够长的时间,我们可以再次触发
- 旁注:我决定将所有拍摄代码移至Shoot()
- 在Shoot()内部,因为玩家被解雇了,所以我们将重置计时器并开始等待,直到我们可以再次射击为止。
添加玩家命中效果
设置游戏对象
当我们射击敌人的骑士时,什么也没有发生。 他只会无视你,继续向你走去。
我们可以做很多事情来使它变得更好:
- 添加声音效果
- 增加伤害血液效果
- 推他回来
- 上述所有的
1)最终会添加,2)可能会完成,但是3)是我要实现的。
每次射击骑士时,我们都想将其推回去。 这样,如果他们中的一群人涌向我们,我们将不得不管理先射击哪一个。
这个小功能花了很长时间解决。
问题
每当我们射击敌人时,我们都想将其推回去,但是,Nav Mesh Agent会覆盖我们尝试的任何更改。 具体来说,骑士将永远继续前进。
解决方案
我们编写了一些代码,将Nav Mesh Agent的速度更改为向后几个单位。
但是,当我这样做时,骑士继续向前奔跑!
为什么?
这是一个很好的问题,我仍在调查,希望明天能找到解决方案。
第13天结束
今天是我第一次遇到一个我一天都无法解决的问题。
我希望随着我们开始跳得越来越深,这种情况会越来越普遍。
话虽如此,今天我们修复了玩家的漂移问题,方法是使用拖曳并添加敌人死亡动画,以防他们耗尽生命。
明天我将继续研究如何将敌人退回。
第14天见! 或者只要我能弄清楚这个击退问题!
原始日13
访问Unity VR开发的主要100天页面
访问我的主页