zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Unity笔记-17-02-枪械动画练习

动画笔记 Unity 练习 02 17
2023-09-11 14:22:30 时间

Unity笔记-17-02-枪械动画搭建练习

前排提醒:游戏资源来自Unity商店里的免费资源

整体分析

目前有多种枪械,需要实现:

  1. 按下鼠标左键,当前枪械播放射击动画以及音效,可以从任意状态切换到开火状态,且没有等待
  2. 按下R键,当前枪械播放换弹匣动画以及音效,可以从任意状态切换到换弹匣状态,且没有等待
  3. 按下移动键,当前枪械播放持枪移动动画以及音效,如在移动中开火或者换弹匣,应当优先播放对应的动画,且没有等待
  4. 无按下时,播放持枪站立动画
  5. 按下Q键时,切换为下一把枪械,并播放一次切换音效

动画控制器-Animator

在这里插入图片描述

图中的线比较乱,这里详细说明一下:

什么都没有按下的情况下,为常规动画;如果按下鼠标左键,则触发Fire切换到开火动画,这条线不勾选Has Exit Time因此可以在常规动画播放的时候立刻切换,换弹匣,跑步,走路也是同理,只不过触发参数为Reload

上述都是常规的,以下是特别的,在走路动画播放时,能够立刻切换到换弹匣,开火,跑步,因此需要都加上连接箭头;跑步也是同理;其次,在测试中,由于走路和跑步需要持续按下,这会导致触发参数被触发多次,导致在走路切换到跑步的时候会重新切回走路再切回跑步,这种效果会有一种及其生硬的停顿,因此需要加上IsRun参数去控制走路与跑步的切换条件,如果是跑步IsRun就设置为True,走路则为false,从走路直接切换到跑步这参数条件也设置为WalkIsRun-true;从跑步切回走路为,RunIsRun-true;另外从走路或者跑步切回常规需要StopMove来触发,因为走路和跑步是持续的不可能说播放一次动画就切回去,因此需要持续触发,而不能播一次切回去一次再播一次,这样也是体验很差的;

脚本组件

所有枪械的共同行为脚本:GunAction

public class GunAction : MonoBehaviour
{
    private Animator ani;
    private AudioSource audioSource;
    public AudioClip fireClip;
    public AudioClip reLoadClip;
    public AudioClip normalClip;

    private void Awake()
    {
        audioSource = GetComponent<AudioSource>();
        ani = GetComponent<Animator>();
    }
    public void OnEnable()
    {
        PlayClip(normalClip);
    }
    public void Fire()
    {
        ani.SetTrigger("Fire");
        Debug.Log("fire");
        PlayClip(fireClip);
    }
    public void ReLoad()
    {
        ani.SetTrigger("Reload");
        PlayClip(reLoadClip);

    }
    public void Run()
    {
        SetRun();
        ani.SetTrigger("Run");
    }
    public void walk()
    {
        SetWalk();
        ani.SetTrigger("Walk");
    }
    public void StopMove()
    {
        ani.SetTrigger("StopMove");
    }
    public void SetRun()
    {
        ani.SetBool("IsRun",true);
    }
    public void SetWalk()
    {
        ani.SetBool("IsRun", false);
    }
    private void PlayClip(AudioClip clip)
    {
        audioSource.clip = clip;
        audioSource.Play();
    }
}

枪械管理组件-GunManager

private GunAction[] weapens;
private GunAction currentWeapen;
private int currentindex;

首先需要定义枪行为数组,用于在初始化的时候储存所有的枪

并定义currentWeapen用于储存当前使用的枪

private void Awake()
{
    weapens = new GunAction[transform.childCount - 1];
    for(int i = 1; i < transform.childCount; i++)
    {
        weapens[i-1] = transform.GetChild(i).GetComponent<GunAction>();
        weapens[i - 1].gameObject.SetActive(false);
    }
    currentindex = 0;
    currentWeapen = weapens[currentindex];
    currentWeapen.gameObject.SetActive(true);
    currentWeapen.OnEnable();
}

初始化的时候,获取所有的枪械行为脚本,把所有的枪的激活状态设置为false,并把当前使用的枪置为true

并调用一次枪的初始音效

  private void Update()
    {
        if (Input.GetKeyDown(KeyCode.O))
        {
            currentWeapen.Fire();
        }
        else if (Input.GetKeyDown(KeyCode.R))
        {
            currentWeapen.ReLoad();
        }
        else if (Input.GetKeyDown(KeyCode.Q))
        {
            currentWeapen.gameObject.SetActive(false);
            //currentindex = (currentindex++) % (transform.childCount-1);
            currentindex++;
            if (currentindex == transform.childCount - 1)
            {
                currentindex = 0;
            }
            currentWeapen = weapens[currentindex];
            currentWeapen.gameObject.SetActive(true);
            currentWeapen.OnEnable();
        }
        else if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D))
        {
            if (!Input.GetKey(KeyCode.LeftShift))
            {
                currentWeapen.walk();
            }
            else
            {
                currentWeapen.Run();   
            }
        }
        else
        {
            currentWeapen.StopMove();
        }
    }

调用方法,逻辑相对简单,这里不再赘述