我们用触发器的方法实现攻击,接下来我们来实装一下Player的攻击方法
首先我们先来看一下Player的动画
在Animation窗口,查看人物的每一帧动画,我们会发先前三帧并不会产生攻击效果,在第四帧的时候,我们可以看到人物的剑影甩出来的时候,我们执行攻击的判断,然后就停止攻击了,三段攻击都是同样的方法
我们只要在剑影这个位置来播放一下他的攻击效果就可以了,我们需要一个Trigger的方式来触发,所以我们要添加碰撞体,我们不能在Player身上添加太多碰撞体,所以我们来学习一个方法
我们在Player的下面创建一个子集物体,点击Create Empty,命名为Attack Area
然后我们在这个新创建的文件夹下,点击Create Empty,来创建三段攻击,取名为Attack1,2,3;这样三段攻击就都有了
我们首先来看一下第一段攻击,第一段攻击的时候,我们在Attack1中添加一个碰撞体,作为一个触发器,添加一个PolyGon Collider2D(多边形碰撞体)勾选上Tigger
然后我们在时间轴上查看一下动画,我们希望他在0:03这一帧的时候来播放,判断的范围就是我们剑影大概的范围,我们点击编辑,将碰撞体的框子拖拽到这些点位上,来形成我们碰撞检测的范围(改碰撞体范围时,两条线之间,点按一下可以添加多一个判断的点)
那我们怎么做攻击的动画呢,我们要一直让他启动吗,我们知道我们会用Tigger的方法,那么我们只在一帧里判断的话,就执行单次,那我们就会使用关闭和启动的方式(比如说我们在攻击的时候,我们要选择这个物体的编辑,我们在不攻击的时候,我们就把这个物体关闭,他就不显示了)
我们要在动画播放到0:03的位置的时候,启动这个Attack1的碰撞体,这时候我们就执行了一帧的判断
我们可以在我们的动画当中来添加这个关键帧,在Animation窗口选择Add Property--Attack Area--Attack1--Game Object.is Active--" + "
这个就是控制Inspector窗口上面的物体是否启动这个项目,在0:03这一帧,确定启动
我们来修改一下他在时间轴上的变量,首先我们将这个物体关闭 ,在时间轴上也把他关闭,
到我们想到的帧,我们把它启动,这时候就添加了一个关键帧点,
我们在下一帧把它关闭
最后一帧也是关闭状态
Animation窗口运行一下看效果,在0:03帧的时候出现碰撞体框,这样就实现了我们想要的效果
接下来,我们要计算攻击的伤害,我们就在Attack1这一物体上,添加Attack脚本
在这个脚本当中,我们可以定义第一段攻击的伤害,Damage=10
第三段是一个暴击,可以设置为20
每段攻击都可以设置单独的数值
接下来来做Attack2,第一帧有,第二帧无,第三帧无
接下来做Attack3,第三帧有,其他帧无
添加完之后在Animation窗口中预览一下
这样我们就成功编辑好了三段的攻击
我们是用OnTrigger的方法,我们打开Attack代码查看一下
只要是在Tigger范围之内,不管对方是什么,我们都会执行他身上的TakeDamage,原因就是因为Enemy和Player都用了共用的方法,所以没有办法在上面限制,对方是Player或者Enemy,我们才会执行下面的这个命令,这就导致了一个问题,第三段的攻击的时候,我们的AttackArea会和我们的人物有交集,就会导致我们人物自己也会伤到自己
我们在Tigger的范围之内,我们来选择一下,找到Polygon Collider 2D,打开我们的Layer Overrides,在这里面,我们只选择我们的Contect Capture Layer,只勾选Enemy,这样的话,整个的Polygon Collider只和敌人发生碰撞关系,不会与Player本身发生碰撞
三个Attack都修改一下
这样我们就设置好了这三段攻击,保存项目,测试一下
点击运行
我们注意观察野猪的血量变化,野猪血量变化有问题
野猪的身上有两个碰撞体,BoxCollider和CapsuleCollider,我们计算的时候希望以CapsuleCollider为准,我们要留意他们两个的Layer Override Priority都为0(这个是我们判断碰撞的优先级),我们希望优先以CapsuleCollider的Tigger范围作为判断标准,所以我们把CapsuleCollider的Layer Override Priority改为10 ,让他优先进行判断
保存项目,注意野猪,避免它在触发的时候会连续的进行判断,我们要把他的受伤的无敌时间,标记一下,设置invulnerableDuration为1S
接下来我们来测试一下
我们发现人物走过去触碰到野猪,也会导致野猪血量降低,人物边走边攻击还可以受伤,这些不是我们想要的效果,另外由于野猪现在是不动的状态,如果原地不动的持续攻击,可能不会有伤害,转身再转回来攻击,或者跳起来再回来攻击的话,他就会有受伤的效果。当我们的野猪可以正常移动的时候,我们也会给他添加受到的伤害,然后被击退的效果,他会继续冲向Player,然后触发下一步攻击
我们先来解决在攻击状态下,还能移动的问题,在这个项目中,由于人物攻击脚下没有过多的移动的动画,所以我们设置在这个项目当中攻击的时候,玩家不能移动。
我们到PlayerCollider代码当中,修改一下代码
我们再次找到移动的代码Move;我们在FixedUpdate当中执行的就是非受伤状态,我们可以移动,在这里我们再加上另外一个条件在非攻击状态人物可以移动
private void FixedUpdate()
{
if(!isHurt && !isAttack)
Move();
}
我们还要留意一下isAttack这个代码在什么时候变为true,什么时候变为false;true的情况下就是我们执行攻击这个动画。在PlayerAttack当中isAttack为true;在我们添加的state behavior当中,只有在这个状态退出的时候,他就变成了false。但是我们留意每一个动画,每一段攻击结束的时候他都会变为false,这就会让我们的人物,有一个中间的间歇性的空挡,人物可能会稍微往前窜一点。如果需要这样的位移,可以使用他。
保存代码,返回unity,
我们点击Play播放,我们人物在一边攻击,一边移动的时候,我们会发现他还是会有一段距离的位移,原因是因为我们现在使用的是一个光滑的材质,
其实这个光滑的材质,只有在我们跳起来撞墙的时候,我们才愿意使用这种光滑的材质,在地上的话,我们还是希望可以使用正常的有摩擦力的材质,
这种没有摩擦力的,我们将这个材质改名为Wall
我们再创建一个新的材质,叫做Normal,Normal的状态应该是有摩擦力,正常是0.4
选择Player,把它改为有摩擦力的,再次运行游戏
边点攻击边点移动,还是会有一小段的位移,因为在Attack1到Attack2的动画播放过程中,他会有一段小的时间导致这个isAttack变为false,所以我们可以通过修改Attack Finish这个代码,让这个每一段状态进入的时候,我们再次更新一下,让isAttack变为true,这样就很好的约束了我们攻击的间歇
保存代码,返回unity,测试一下
现在攻击的时候,人物就不会再产生位移了
如果我们想要人物攻击时,稍微往前窜一点,我们就可以把刚才的OnStateEnter中的代码取消了。这样我们就实现了攻击
还有一个问题,就是我们的材质问题,跳起来的时候,我们希望切换到Wall材质;落地的时候,我们切换到正常的材质。
我们到代码当中来修改添加我们的这个材质,打开PlayerController代码当中,我们来添加这个变量来获得这两个材质,2D的物理材质,一个是normal,一个是wall
[Header("物理材质")]
public PhysicsMaterial2D normal;
public PhysicsMaterial2D wall;
我们通过跳起的状态来判断什么时候用normal和wall,跳起来用wall,落地用normal
这也需要持续不断的检测,在Update当中要检测我们当前的状态,如果在地面,我们就要切换一下材质,如果不是地面就要变回去
首先,先来创建一个新的函数,命名为CheckState(检查我们现在的状态)
在这里面我们可以有很多的检测方法,首先就是我们会修改我们碰撞体当中的材质,这个是非常重要的,我们搜索coll.sharedMaterial,等于normal或者wall;判断是否在地面上,来选择等于normal或者wall;(在这里面我们学习一个三元运算符,在这里面加上一个判断,如果physcisCheck.isGround?是的话,在地面使用normal:否则使用wall)
private void CheckState()
{
coll.sharedMaterial = physicsCheck.isGround ? normal : wall;
}
还需要将函数在Update当中调用
private void Update()
{
inputDirection = inputControl.Gameplay.Move.ReadValue<Vector2>();
CheckState();
}
保存地面,返回unity,
我们创建了变量要先来赋值,找到PlayerController,将这两个物理材质添加进来,一个是Normal,一个是wall
我们点击运行,注意查看Capsule Collider 2D中Material材质的变化,在地上为Normal,在空中为Wall,这样的话我们也不会出现贴着墙的时候没有办法下降;在地上的时候,我们也有正常的摩擦力,保持我们在攻击的时候不会向前滑太远