2025年【Unity】动作游戏开发实战详细分析-07-连续技与组合技功能设计

【Unity】动作游戏开发实战详细分析-07-连续技与组合技功能设计Unity 动作游戏开发实战详细分析 07 连续技与组合技功能设计 基本思路 在一些动作游戏中 存在着连续技这一功能 具体来说就是连续按下规定的按键会触发能力的功能 或者是长按触发等等 实现解析 ComboCmd 这是命令结构体 它代表单个连续技命令 我们来逐一分析他的代码

大家好,我是讯享网,很高兴认识大家。

【Unity】动作游戏开发实战详细分析-07-连续技与组合技功能设计


基本思路

在一些动作游戏中,存在着连续技这一功能,具体来说就是连续按下规定的按键会触发能力的功能,或者是长按触发等等。

实现解析

ComboCmd

这是命令结构体,它代表单个连续技命令

我们来逐一分析他的代码,首先,我们要明确,我们对于命令的监听基于协程,因此该命令类需要有最基本的两个方法,那就是重置和更新。

重置方法很简单,就是重置长按倒计时与限制倒计时

public ComboCmd Reset()//重置 { mLimitTime_Timer = LimitTime; mHoldTime_Timer = HoldTime; return this; } 

讯享网

我们通过委托从外部输入检测条件以及时间帧长

我们来看重点的更新函数

首先他会输出一个整形变量state,用于表示当前的命令状况

每次更新时,默认初始值为等待值。如果监听条件成立,则进行时间判定,并减少长按时间,当长按时间归零,则赋予state变量成功值

这里还有一个限制时间的变量监听,它用于组合技的按键时间间隔限制

例如,目前具有组合技C+J触发行为,但是要求必须在0.2秒内完成输入。因此就需要限制时间的存在。如果连续技的两个单独命令的按键输入超过限制时间,则返回失败值

讯享网public ComboCmd Tick(out sbyte state)//每一次更新 { state = STATE_WAIT; if (Conditional())//监测条件是否成立 { if (mHoldTime_Timer > 0)//是否为长按 mHoldTime_Timer -= DeltaTime(); else//不为长按且条件进入,则命令完成 state = STATE_SUCCESS; } if (state != STATE_SUCCESS && mLimitTime_Timer > COUNTDOWN_INVALID)//更新限制时间 { mLimitTime_Timer -= DeltaTime();//更新倒计时 if (mLimitTime_Timer <= 0)//超过时间则失败 { state = STATE_FAILURE; mLimitTime_Timer = 0; } } return this; } 

完整代码


讯享网

using System; using UnityEngine; namespace ACTBook { public struct ComboCmd { const sbyte COUNTDOWN_INVALID = -1;//无效倒计时 const sbyte STATE_SUCCESS = 1;//成功ID const sbyte STATE_FAILURE = -1;//失败ID const sbyte STATE_WAIT = 0;//等待ID float mLimitTime_Timer;//限制时间倒计时 float mHoldTime_Timer;//长按时间倒计时 public float LimitTime { get; set; }//限制时间 public float HoldTime { get; set; }//长按时间 public Func<bool> Conditional { get; set; }//检测条件(鼠标、键盘、手柄按下等) public Func<float> DeltaTime { get; set; }//两帧时间差 public ComboCmd Reset()//重置 { mLimitTime_Timer = LimitTime; mHoldTime_Timer = HoldTime; return this; } public ComboCmd Tick(out sbyte state)//每一次更新 { state = STATE_WAIT; if (Conditional())//监测条件是否成立 { if (mHoldTime_Timer > 0)//是否为长按 mHoldTime_Timer -= DeltaTime(); else//不为长按且条件进入,则命令完成 state = STATE_SUCCESS; } if (state != STATE_SUCCESS && mLimitTime_Timer > COUNTDOWN_INVALID)//更新限制时间 { mLimitTime_Timer -= DeltaTime();//更新倒计时 if (mLimitTime_Timer <= 0)//超过时间则失败 { state = STATE_FAILURE; mLimitTime_Timer = 0; } } return this; } } } 
WaitForComboInput

连续技命令监听类,我们需要通过协程来完成监听,因此该类需要实现IEnumerator接口

字段指令数组存储连续技指令

重点来看更新逻辑函数

首先初始化result与state

然后更新当前的命令(从index=0开始)

如果命令为失败值,则对所有命令进行重置

如果是成功值,则继续监听下一个命令,直到最后一个命令也成功时,result赋予false,表示协程暂停结束。

如果是等待值,则继续监听

讯享网bool IEnumerator.MoveNext()//更新逻辑 { var result = false; var state = STATE_FAILURE;//初始化状态 mCmdArray[mCurrentIndex] = mCmdArray[mCurrentIndex].Tick(out state);//更新命令 switch (state) { case STATE_FAILURE://失败的情况 mCurrentIndex = 0; for (int i = 0, iMax = mCmdArray.Length; i < iMax; i++) mCmdArray[i] = mCmdArray[i].Reset();//失败重置 result = true; break; case STATE_SUCCESS://成功的情况 mCurrentIndex++; if (mCurrentIndex == mCmdArray.Length) result = false;//若为最后一个指令协程结束 else result = true; break; case STATE_WAIT://继续等待 result = true; break; } return result;//若返回值为True则继续更新 } 

完整代码

using System.Collections; namespace ACTBook { public class WaitForComboInput : IEnumerator { const sbyte COUNTDOWN_INVALID = -1;//无效倒计时 const sbyte STATE_SUCCESS = 1;//成功ID const sbyte STATE_FAILURE = -1;//失败ID const sbyte STATE_WAIT = 0;//等待ID int mCurrentIndex;//当前指令索引 ComboCmd[] mCmdArray;//指令数组 public WaitForComboInput(ComboCmd[] comboCmdArray)//初始化 { mCmdArray = comboCmdArray; } object IEnumerator.Current { get { return null; } }//接口实现 void IEnumerator.Reset() { mCurrentIndex = 0; }//接口实现 bool IEnumerator.MoveNext()//更新逻辑 { var result = false; var state = STATE_FAILURE;//初始化状态 mCmdArray[mCurrentIndex] = mCmdArray[mCurrentIndex].Tick(out state);//更新命令 switch (state) { case STATE_FAILURE://失败的情况 mCurrentIndex = 0; for (int i = 0, iMax = mCmdArray.Length; i < iMax; i++) mCmdArray[i] = mCmdArray[i].Reset();//失败重置 result = true; break; case STATE_SUCCESS://成功的情况 mCurrentIndex++; if (mCurrentIndex == mCmdArray.Length) result = false;//若为最后一个指令协程结束 else result = true; break; case STATE_WAIT://继续等待 result = true; break; } return result;//若返回值为True则继续更新 } } } 

最后我们可以使用一个测试类,对功能进行测试

讯享网using System; using System.Collections; using UnityEngine; namespace ACTBook { class Foo : MonoBehaviour { IEnumerator Start() { while (true) { Func<float> deltaTime = () => Time.deltaTime;//时间间隔函数 yield return new WaitForComboInput(new ComboCmd[] { new ComboCmd(){Conditional=()=>Input.GetKey(KeyCode.X), DeltaTime=deltaTime, HoldTime=-1, LimitTime=0.2f },//0.2秒内按下x new ComboCmd(){Conditional=()=>Input.GetKey(KeyCode.Y), DeltaTime=deltaTime, HoldTime=-1, LimitTime=0.2f },//0.2秒内按下y }); Debug.Log("Triggered!");//触发 yield return null; } } void OnGUI() { GUILayout.Box("请在0.2秒内按下键盘'X'和'Y'按键,以触发日志打印"); } } } 
小讯
上一篇 2025-03-24 20:48
下一篇 2025-01-15 21:28

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/63067.html