马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Unity3D 利用代码在动画片断中添加变乱
在 Unity 中,动画片断(AnimationClip)可以通过添加变乱(AnimationEvent)来在特定时间点触发自界说函数。这种方式非常恰当在动画播放过程中实行一些逻辑利用,比方播放音效、触发粒子结果、大概控制游戏逻辑。
本文将具体先容怎样利用代码在动画片断中添加变乱,并提供完备的示例代码和优化发起。
通例的在动画中添加变乱的方式:
1. 动画变乱
动画变乱(AnimationEvent)是 Unity 中用于在动画播放过程中触发特定函数的一种机制。你可以在动画片断中的恣意时间点添加变乱,并指定变乱触发时要调用的函数名称。变乱可以携带参数,而且可以在动画编辑器中可视化地编辑。
2. 利用代码添加动画变乱
- 获取动画片断:通过 Animator 组件获取对应的动画片断。
- 创建动画变乱:创建一个 AnimationEvent 实例,并设置其触发时间和函数名称。
- 将变乱添加到动画片断:将创建的变乱添加到动画片断的变乱列表中。
2.1 获取动画片断
我们须要从 Animator 组件中获取对应的动画片断。可以通过遍历 AnimatorController 中的 animationClips 来找到指定名称的动画片断。- public static AnimationClip GetClipFromAnimator(Animator animator, string stateName)
- {
- if (animator == null)
- {
- Debug.LogError("Animator is null!");
- return null;
- }
- var animatorController = animator.runtimeAnimatorController;
- if (animatorController == null)
- {
- Debug.LogError("Animator Controller is null!");
- return null;
- }
- foreach (var clip in animatorController.animationClips)
- {
- if (clip.name == stateName)
- {
- return clip;
- }
- }
- Debug.Log($"没有找到名为 {stateName} 的动画片段!");
- return null;
- }
复制代码 2.2 创建并添加动画变乱
接下来,我们可以创建一个 AnimationEvent 实例,并将其添加到动画片断中。我们可以选择利用时间(秒)或帧数来指定变乱的触发时间。- public static void AddEventToClip(AnimationClip clip, float time, string functionName, bool useFrames = false)
- {
- if (clip == null)
- {
- Debug.LogError("AnimationClip is null!");
- return;
- }
- float fps = clip.frameRate > 0 ? clip.frameRate : 60f; // 默认 60fps
- if (useFrames)
- {
- time = time / fps; // 将帧数转换为秒数
- }
- if (time < 0f)
- {
- time = 0f;
- }
- if (time > clip.length)
- {
- time = clip.length;
- }
- AnimationEvent animationEvent = new AnimationEvent
- {
- time = time,
- functionName = functionName
- };
- clip.AddEvent(animationEvent);
- }
复制代码 2.3 清空或删除动画变乱
偶然候我们须要清空或删除动画片断中的特定变乱。可以通过以下方法实现:- public static void ClearAllEventsFromClip(AnimationClip clip)
- {
- if (clip == null)
- {
- Debug.LogError("ClearAllEventsFromClip: AnimationClip is null!");
- return;
- }
- clip.events = new AnimationEvent[0];
- Debug.Log($"ClearAllEventsFromClip: All events cleared from clip '{clip.name}'.");
- }
- public static void RemoveEventFromClip(AnimationClip clip, string functionName)
- {
- if (clip == null)
- {
- Debug.LogError("RemoveEventFromClip: AnimationClip is null!");
- return;
- }
- if (string.IsNullOrEmpty(functionName))
- {
- Debug.LogError("RemoveEventFromClip: Function name is null or empty!");
- return;
- }
- AnimationEvent[] events = clip.events;
- var filteredEvents = new System.Collections.Generic.List<AnimationEvent>();
- foreach (var evt in events)
- {
- if (evt.functionName != functionName)
- {
- filteredEvents.Add(evt);
- }
- }
- clip.events = filteredEvents.ToArray();
- }
复制代码 3. 示例代码
代码
利用的示例,展示了如安在动画片断中添加变乱,并在变乱触发时实行自界说逻辑。
将这个脚本挂在在带有Animator 组件的物体上然后就可以在动态添加变乱了。- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class ObjAni : MonoBehaviour
- {
- private Animator animator;
- private void Start()
- {
- animator = gameObject.GetComponent<Animator>();
- var clip = AnimationHelper.GetClipFromAnimator(animator, "DoRotate");
- // 在第30帧添加事件
- AnimationHelper.AddEventToClip(clip, 30, nameof(AnimatorEventAdd), true);
- animator.SetBool("work", true);
- Invoke(nameof(RemoveEventClip), 3.0f);
- }
- private void AnimatorEventAdd()
- {
- animator.SetBool("work", false);
- Debug.Log("AnimatorEventAdd");
- }
- void RemoveEventClip()
- {
- var clip = AnimationHelper.GetClipFromAnimator(animator, "DoRotate");
- AnimationHelper.RemoveEventFromClip(clip, nameof(AnimatorEventAdd));
- animator.SetBool("work", true);
- }
- }
复制代码
- Start 方法:在游戏开始时,获取 Animator 组件和对应的动画片断 DoRotate,并在第30帧添加一个变乱,变乱触发时调用 AnimatorEventAdd 方法。
- AnimatorEventAdd 方法:当变乱触发时,克制动画播放,并输出日记信息。
- RemoveEventClip 方法:在3秒后移除动画片断中的变乱,并重新开始动画播放。
Unity3D动画设置
- 创建一个空的状态
- 添加一个切换条件,范例为bool范例,默认是false
- 添加自己要实行的动画,并修改名称为DoRotate
- 添加切换条件:new State -true-> DoRotate , DoRotate -false->new State
- 将这个动画状态机给到上面的Animator 组件
4. 其他发起
- 性能优化:频仍地添加和删除变乱大概会影响性能,发起在游戏初始化时一次性添加全部变乱,并在须要时举行更新。
- 变乱参数:AnimationEvent 可以携带参数(如 int、float、string 等),可以根据须要转达更多信息给变乱处置处罚函数。
- 没有动画:确认导入的模子上有动画,勾选inport Animation
5.完备的添加变乱代码
|