news 2026/4/15 7:38:56

Animation控制单条动画播放(手动设置起始帧、结束帧)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Animation控制单条动画播放(手动设置起始帧、结束帧)

代码如下:

using System.Collections; using UnityEngine; // 强制挂载Animation组件,避免忘记添加 [RequireComponent(typeof(Animation))] public class Test : MonoBehaviour { private Animation _anim; // 自身的Animation组件 private AnimationState _animState;// 要控制的单条动画状态(核心控制对象) public string animClipName = ""; // 要控制的动画片段名(和Animation组件中一致,空则用默认片段) public float animFrameRate = 30f; // 【配置】动画帧率(Animation窗口查看的数值) private float _startTime; // 实时计算的起始时间(秒) private float _stopTime; // 实时计算的停止时间(秒) private bool _isPlaying = false; // 动画播放状态标记 void Start() { // 初始化组件和动画状态(只执行一次,无需重复初始化) _anim = GetComponent<Animation>(); InitAnimState(); // 初始化动画为单次播放 if (_animState != null) _animState.wrapMode = WrapMode.Once; // 【调用示例1】立即播放:从0帧开始,30帧停止(无延时) // StartCoroutine(PlayAnimFromSpecifiedFrame(0, 30)); // 【调用示例2】延时播放:延时2秒,从5帧开始,40帧停止 StartCoroutine(PlayAnimFromSpecifiedFrame(450, 500, 2f)); } void Update() { // 动画正在播放时,逐帧检测是否到达停止帧(逻辑不变,复用实时计算的_stopTime) if (_isPlaying && _animState != null) { if (_animState.time >= _stopTime) { PauseAnim(); Debug.Log($"动画已在{Mathf.Round(_stopTime * animFrameRate)}帧停止"); } } } #region 初始化AnimationState(逻辑完全不变) private void InitAnimState() { if (_anim == null || _anim.GetClipCount() == 0) { Debug.LogError("请先给Animation组件添加动画片段!", gameObject); return; } if (string.IsNullOrEmpty(animClipName)) { animClipName = _anim.clip.name; _animState = _anim[animClipName]; } else { _animState = _anim[animClipName]; if (_animState == null) { Debug.LogError($"Animation组件中未找到名为{animClipName}的动画片段!", gameObject); } } } #endregion #region 核心改造:协程版 - 带延时+实时帧参数 播放动画 /// <summary> /// 协程版:指定帧区间播放动画,支持延时调用,实时传帧参数 /// </summary> /// <param name="startFrame">本次播放的起始帧(实时传参)</param> /// <param name="stopFrame">本次播放的停止帧(实时传参)</param> /// <param name="delay">延时播放时间(秒),默认0=立即播放</param> /// <returns>协程迭代器</returns> public IEnumerator PlayAnimFromSpecifiedFrame(int startFrame, int stopFrame, float delay = 0f) { // 前置校验:动画状态为空/帧参数非法,直接退出 if (_animState == null) yield break; if (startFrame < 0 || stopFrame < 0) { Debug.LogError("帧参数不能为负数!", gameObject); yield break; } if (startFrame > stopFrame) { Debug.LogError("起始帧不能大于停止帧!", gameObject); yield break; } // 第一步:延时逻辑(delay>0时等待,默认0则直接执行) if (delay > 0f) { Debug.Log($"动画将延时{delay}秒播放,区间:{startFrame}帧 → {stopFrame}帧"); yield return new WaitForSeconds(delay); } // 第二步:实时计算帧对应的时间(核心:不再依赖Inspector配置,随参数变化) _startTime = startFrame / animFrameRate; _stopTime = stopFrame / animFrameRate; // 第三步:停止其他动画,重置并播放当前动画(重复调用自动重置) _anim.Play(animClipName, PlayMode.StopAll); // 停止其他动画,避免冲突 _animState.time = _startTime; // 跳转到实时传入的起始帧 _animState.speed = 1f; // 恢复播放速度 _isPlaying = true; // 更新播放状态 Debug.Log($"动画{animClipName}开始播放,区间:{startFrame}帧 → {stopFrame}帧"); } #endregion #region 手动控制:播放/暂停/重新播放(逻辑完全不变,可正常使用) public void PauseAnim() { if (_animState == null || !_isPlaying) return; _animState.speed = 0f; _isPlaying = false; } public void ResumeAnim() { if (_animState == null || _isPlaying) return; _animState.speed = 1f; _isPlaying = true; } /// <summary> /// 重新播放指定帧区间(封装协程调用,方便外部直接调用) /// </summary> /// <param name="startFrame">起始帧</param> /// <param name="stopFrame">停止帧</param> /// <param name="delay">延时时间</param> public void ReplayAnim(int startFrame, int stopFrame, float delay = 0f) { StartCoroutine(PlayAnimFromSpecifiedFrame(startFrame, stopFrame, delay)); } #endregion #region 辅助方法(帧转时间,备用) private float FrameToTime(int frame) { return frame / animFrameRate; } #endregion // 编辑器调试:实时显示当前播放帧(适配实时传参的帧区间) void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position + Vector3.up * 2, 0.5f); float currentFrame = _animState == null ? 0 : Mathf.Round(_animState.time * animFrameRate); UnityEditor.Handles.Label(transform.position + Vector3.up * 3, $"当前帧:{currentFrame}\n本次停止帧:{Mathf.Round(_stopTime * animFrameRate)}"); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/3 20:40:27

重力适应:2026太空“测试场”上的女性破壁者

一、 挑战之壁&#xff1a;重力缺失下的“系统”脆弱性 太空微重力环境&#xff0c;是对人体这一精密“生物系统”的极端压力测试。失重导致肌肉萎缩、骨质流失、心血管功能紊乱、前庭系统失调&#xff08;空间运动病&#xff09;等问题&#xff0c;长期威胁航天员健康与任务执…

作者头像 李华
网站建设 2026/4/8 12:28:23

从文献梳理到论文定稿:2026 全流程 AI 写作软件深度推荐

2026年AI写作已从单一功能升级为**全流程闭环**&#xff0c;**PaperRed**&#xff08;99分&#xff09;、**毕业之家**&#xff08;98分&#xff09;稳居前列&#xff0c;覆盖**文献梳理→选题构思→初稿撰写→修改润色→格式排版→查重降重→答辩准备**全链路&#xff0c;适配…

作者头像 李华
网站建设 2026/4/10 13:04:46

价值投资者如何看待并购和分拆

价值投资者如何看待并购和分拆 关键词:价值投资、并购、分拆、企业估值、资本配置、股东价值、投资策略 摘要:本文深入探讨价值投资者如何分析和评估企业并购与分拆活动。我们将从价值投资的基本原则出发,详细解析并购和分拆对企业内在价值的影响机制,提供系统的分析框架和…

作者头像 李华
网站建设 2026/4/10 14:43:06

蜗轮梯形丝杆升降机的有哪些优势与弊端

蜗轮梯形丝杆升降机是蜗轮蜗杆减速机构 梯形丝杆副的经典组合&#xff0c;也是丝杆升降机中应用最广泛的机型之一&#xff0c;其优势集中在安全自锁、成本低廉、结构耐造等方面&#xff0c;弊端则源于双重滑动摩擦带来的效率、温升、速度限制&#xff0c;整体适配中小负载、低…

作者头像 李华
网站建设 2026/4/8 9:11:13

【GitHub项目推荐--Nanobot:超轻量级个人AI助手】

简介 Nanobot​ 是一个由HKUDS团队开发的开源超轻量级个人AI助手项目&#xff0c;灵感来源于Clawdbot但代码量大幅精简。该项目采用Python编写&#xff0c;核心代码仅约4,000行&#xff0c;相比Clawdbot的430,000行代码减少了99%。Nanobot专注于提供核心AI助手功能&#xff0c…

作者头像 李华
网站建设 2026/4/10 1:44:16

为什么只有镜像视界,能让普通视频具备三维空间判断能力

为什么只有镜像视界&#xff0c;能让普通视频具备三维空间判断能力这是一个技术层级很高、但必须说清楚的问题。答案不在于“算法更强”&#xff0c;而在于是否从一开始就站在“空间事实”的角度构建整套体系。绝大多数厂商是在二维视频之上“叠加三维效果”&#xff0c;而镜像…

作者头像 李华