Unity知识记录--添加人物攻击动作
彩紫睨羽
2021年03月01日 23:30
收录于文集
共120篇

紧接上期的内容,人物只能够跑到单位的面前,但不会有任何的动作,接下来将人物的攻击动作添加上。


我们先找到攻击的动作,这里总共是两个攻击动画,可以根据自己的需求进行选择,这里我都选择作为一个普通攻击的动画,也就是人物在攻击时会随机播放一个攻击动作。

打开我们人物的Animator,准备将两个攻击动画片段添加到Animator中。

拖入之后,我们要制作动画机了,设计上是人物从移动状态退出后,直接进入到某一个攻击动画中,也就是说我们要用到随机的功能。

自己重命名一下,方便看。

我们设置一下用到的变量,一个用来传入随机数值,一个用来触发普通攻击,来达到随机播放攻击动画的目的。

接下来,填入切换动画的条件,移动系统->普通攻击1;我们希望的效果是攻击动作能够随时打断移动系统中的动作,不需要等待移动动作完成。

首先取消Has Exit Time的勾选,也就意味着我们可以随时打断移动动画,transition duration设置为0,表示我们不需要过渡动画。添加的切换条件是 普通攻击的Trigger触发,以及普通攻击的随机,也就是当触发攻击并根据随机数的值播放动画。

从攻击动画返回移动系统,只需要将过渡时间点和持续时间设置为0,Exit Time设置为1即可,因为我们只需要播放完动画返回移动系统即可。

对于 普通攻击0 来说与 普通攻击1 的条件相似,仅仅是传入的随机数不同,自行完成设置。


设置好之后,我们需要开始编写代码,打开 玩家角色控制.cs。

我们要在导航代理之后,添加给动画机赋值的内容。

只需要这两行就可以完成攻击动作了。

这样攻击动作的问题解决了,但是新的问题又出现了,当我们之后我们点击攻击时,点击一次,角色会攻击两下。

那这个问题是出在哪呢?我们在 移动攻击目标协程 这个函数里面添加一个 打印。

你会在控制台发现,一次单击,却打印了3次,也就是说执行了3次协程,设想上只有在鼠标左键按下才会进行移动,也就是说我们Input System的设置上有瑕疵,将在下一期专栏和视频中进行更新。


彩紫睨羽

玩家角色控制.cs :

using System;

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.AI;

public class 玩家角色控制 : MonoBehaviour

{

    private NavMeshAgent 导航代理;

    private Animator 动画机;

    private GameObject 当前攻击目标;

    private float 当前攻击速度;

    private float 攻击间隔计时器;

    void Awake()

    {

        导航代理 = GetComponent<NavMeshAgent>();

        动画机 = GetComponent<Animator>();

    }

    void Start()

    {

        鼠标控制器.单例.当鼠标点击时 += 移动到目标点;

        鼠标控制器.单例.当鼠标点击敌人时 += 移动攻击目标;

    }

    void Update()

    {

        动画切换();

    }

    void 动画切换()

    {

        动画机.SetFloat("移动速度&#​34;, 导航代理.velocity.sqrMagnitude);

    }

    public void 移动到目标点(Vector3 目标点位置)

    {

        StopAllCoroutines();

        导航代理.isStopped = false;

        导航代理.destination = 目标点位置;

    }

    private void 移动攻击目标(GameObject 敌方单位)

    {

        if (敌方单位 != null)

        {

            当前攻击目标 = 敌方单位;

            StartCoroutine(移动攻击目标协程());

        }

    }

    IEnumerator 移动攻击目标协程()

    {

        导航代理.isStopped = false;

        transform.LookAt(当前攻击目标.transform.position);

        while (Vector3.Distance(当前攻击目标.transform.position, transform.position) > 1)

        {

            导航代理.destination = 当前攻击目标.transform.position;

            yield return null;

        }

        导航代理.isStopped = true;

        动画机.SetInteger("普通攻击动画随机数&#​34;, UnityEngine.Random.Range(0, 2));

        动画机.SetTrigger("普通攻击&#​34;);

    }

}