判断伤害触发动画帧
观察动画,发现只需要在第4帧时才进行伤害,即发生剑影的那一帧。其他动画同理
添加碰撞盒
目前不需要再玩家Player身上建立过多的碰撞体,因为采用新的方式
选中Player,右击选择Create Empty
,创建一个子级对象。命名为,Attack Area
并在Attack Area
下方再创建三个子对象,Attack1、Attack2、Attack3
选中Attack1,在右侧点击Add Property
,添加一个碰撞盒作为触发器,选择Polygon Collider 2D
勾选Is Trigger
,作为触发器使用
点击Edit Collider
,将碰撞盒的边界对准剑影的边界
此处的碰撞盒作为触发器去判定伤害,只需要在剑影出现的那一帧进行判定。因此,只需要在此帧到达的时候打开此碰撞盒,不在此帧则关闭此碰撞盒
打开或关闭碰撞盒
碰撞盒的伤害判定只需要在合适的动画帧进行,不需要的动画帧不打开碰撞盒
在Animation窗口中,点击Add Property
,选择Attack Area下的Attack1中的Game Object.Is Active
添加进窗口中
选择第一帧,对碰撞盒进行关闭
选择剑影出现的那一帧,打开碰撞盒,即可打上关键帧
同理,在下一帧取消勾选
实现攻击伤害
选择Attack1,点击Add Component
,添加Attack脚本
将Damage
设置为10,即10点伤害
按照上面的方法,将Attack2和Attack3绑定上碰撞盒和Attack脚本
在测试前,一定要先关闭三段攻击的碰撞盒
在测试前,一定要先关闭三段攻击的碰撞盒
在测试前,一定要先关闭三段攻击的碰撞盒
解决剑影的碰撞盒伤害到人物自身的问题
打开剑影的碰撞盒,将Contack Capture Layer
选择Enemy层。这样,此碰撞盒只会跟Enemy进行碰撞判定,不会跟自己进行碰撞判定
解决人物攻击后,敌人不扣血的问题
由于野猪对象绑定了两种碰撞盒,Layer Override Priority
优先级相同,所以无法进行碰撞判定
受伤判定的碰撞盒,为胶囊碰撞盒(Capsule Collider 2D
)。因此,将它的优先级设置为最高
如果上述无效还有一种可能性
因为OnTriggerStay2D
有个休眠时间,它被触发一段时间后自动停止。要想再次触发该函数需要稍微移动其中一个碰撞盒,也就是玩家需要移动到不同位置攻击野猪它才会掉血。后面的课程会让野猪动起来,这样这个问题就不存在了。当然也可以修改OnTriggerStay2D
的休眠时间,使之变长,这样即使在原地攻击野猪它也会持续掉血。修改OnTriggerStay2D的休眠时间方法:点击Edit -> Project Settings
,然后选择Physics 2D
,如下图所示,在General Settings
中将Time To Sleep
修改为一个较大的值,如10000(默认情况下是0.5)
解决任务攻击时还能移动的问题
在PlayerController中,FixedUpdate()
方法内,添加isAttack
的判断
private void FixedUpdate()
{
if(!isHurt && !isAttack)
{
Move();
}
}
此时发现还是能够移动,并没有彻底解决问题
因为人物现在使用的材质是光滑材质,此前为了解决碰墙无法下落的问题所使用的
创建一个新的材质,并将原来的材质更名为Wall
创建的新的材质,将摩擦力(Friction)
修改为正常的0.4
将有摩擦力的材质拖入人物Capsule Collider 2D的Material
中
此时能够发现已经能有效控制人物的移动,如果不想要每一段攻击后人物向前位移的效果,参考下面所述的方法来解决
处理人物每一段攻击后向前位移的动作
打开AttackFinish文件,在OnStateEnter()
方法中,添加以下代码,将isAttack
置为true
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.GetComponent<PlayerController>().isAttack = true;
}
动态切换人物材质
在PlayerController
中,添加两个变量,用以初始化材质
[Header("物理材质")]
// 带有摩擦力的普通材质
public PhysicsMaterial2D normal;
// 不带有摩擦力的光滑材质
public PhysicsMaterial2D wall;
编写CheckState()
方法,根据情况赋予材质
// 根据人物解除地面或者墙体,动态更改人物的材质
private void CheckState()
{
capsuleCollider.sharedMaterial = physicsCheck.isGround ? normal : wall;
}
然后在Update()
方法中调用
private void Update()
{
CheckState();
}
最后在Player的Player Controller
中拖入创建好的材质。这样才能在运行后自动赋予Player材质