Unity Spine帧事件

SpinePro中添加事件帧

首先 选中右上角的层级树 然后选择事件选项

最后在右下角看到 新建 点击它 新建一个事件


点击左上角的设置按钮 弹出编辑窗口


编辑窗口

在右上角 动画栏 可以切换对应的动画

点坐边的那个小灰点来切换 亮点代表当前动画

选中帧

添加事件 点击对应事件的🔑图标 在当前帧添加事件

添加成功后 点击左下角播放按钮 可以看到 人物身边有对应事件的文本弹出 表示添加成功

Unity监听Spine帧事件

面板上添加

可以一个事件 添加多个监听

代码中动态添加

一个事件可以添加多个监听

源码

csharp 复制代码
using System.Collections.Generic;
using UnityEngine;
using Spine.Unity;
using Spine;
using System;
using UnityEngine.Events;

public class SpineEventHelper : MonoBehaviour
{

    [Serializable]
    public class SpineFrameKey
    {
        [SpineEvent] public string key;
        public UnityEvent handler;
    }
    [SerializeField] private List<SpineFrameKey> handlers;
    private Dictionary<string, UnityEvent> keyFrameEventDict = new Dictionary<string, UnityEvent>( );
    public const string START_EVENT = "START_EVENT", END_EVENT = "END_EVENT";
    private SkeletonAnimation skeletonAnimation;
    private void Start( )
    {
        Bind( );
    }
    private void Bind( )
    {
        skeletonAnimation = GetComponent<SkeletonAnimation>( );
        if ( skeletonAnimation == null ) return;
        skeletonAnimation.AnimationState.Event += HandleEvent;
        skeletonAnimation.AnimationState.Start += delegate ( TrackEntry trackEntry )
        {
            if ( keyFrameEventDict.TryGetValue( START_EVENT, out UnityEvent @event ) )
            {
                @event.Invoke( );
            }
        };
        skeletonAnimation.AnimationState.End += delegate
        {
            if ( keyFrameEventDict.TryGetValue( END_EVENT, out UnityEvent @event ) )
            {
                @event.Invoke( );
            }
        };
        foreach ( var handler in handlers )
        {
            keyFrameEventDict[ handler.key ] = handler.handler;
        }
    }
    /// <summary>
    /// 添加自定义的帧事件
    /// </summary>
    /// <param name="key"> 帧名称 </param>
    /// <param name="handler"> 处理的方法 </param>
    public void AddCustomEventHandler( string key, UnityAction handler )
    {
        if ( keyFrameEventDict.TryGetValue( key, out UnityEvent ev ) )
        {
            ev.AddListener( handler );
        }
        else
        {
            var ue = new UnityEvent( );
            ue.AddListener( handler );
            keyFrameEventDict.Add( key, ue );
        }
    }
    /// 移除自定义的帧事件
    /// </summary>
    /// <param name="key"> 指定帧名称 </param>
    /// <param name="handler"> 处理的方法 如果忽略则移除key的所有帧事件 </param>
    public void RemoveCustomEventHandler( string key, UnityAction handler = null )
    {
        if ( keyFrameEventDict.TryGetValue( key, out UnityEvent ev ) )
        {
            if ( handler == null )
            {
                ev.RemoveAllListeners( );
            }
            else
            {
                ev.RemoveListener( handler );
            }
        }
    }
    /// <summary>
    /// 添加动画开始事件
    /// </summary>
    /// <param name="handler"> 开始处理事件的方法 </param>
    public void AddStartEventHandler( UnityAction handler )
    {
        if ( keyFrameEventDict.TryGetValue( START_EVENT, out UnityEvent ev ) )
        {
            ev.AddListener( handler );
        }
        else
        {
            var ue = new UnityEvent( );
            ue.AddListener( handler );
            keyFrameEventDict.Add( START_EVENT, ue );
        }
    }
    /// <summary>
    /// 移除开始帧事件
    /// </summary>
    /// <param name="handler"></param>
    public void RemoveStartEventHandler( UnityAction handler )
    {
        if ( keyFrameEventDict.TryGetValue( START_EVENT, out UnityEvent ev ) )
        {
            ev.RemoveListener( handler );
        }
    }
    /// <summary>
    /// 添加结束帧事件
    /// </summary>
    /// <param name="handler"></param>
    public void AddEndEventHandler( UnityAction handler )
    {
        if ( keyFrameEventDict.TryGetValue( END_EVENT, out UnityEvent ev ) )
        {
            ev.AddListener( handler );
        }
        else
        {
            var ue = new UnityEvent( );
            ue.AddListener( handler );
            keyFrameEventDict.Add( END_EVENT, ue );
        }
    }
    /// <summary>
    /// 移除结束帧事件
    /// </summary>
    /// <param name="handler"></param>
    public void RemoveEndEventHandler( UnityAction handler )
    {
        if ( keyFrameEventDict.TryGetValue( END_EVENT, out UnityEvent ev ) )
        {
            ev.RemoveListener( handler );
        }
    }
    private void HandleEvent( TrackEntry trackEntry, Spine.Event e )
    {
        if ( keyFrameEventDict.TryGetValue( e.Data.Name, out UnityEvent @event ) )
        {
            @event.Invoke( );
        }
    }
    /// <summary>
    /// 清理所有帧事件 
    /// </summary>
    public void Clear( )
    {
        keyFrameEventDict.Clear( );
    }
    private void OnDestroy( )
    {
        Clear( );    
    }
}
相关推荐
Solange__8 小时前
在线3D预览器、Blender和游戏引擎怎么选?按5类任务比较格式、隐私与编辑性
人工智能·游戏·3d·游戏引擎·blender·1024程序员节·关卡设计
peter676810 小时前
unity2d游戏开发经验总结
unity
郝学胜-神的一滴10 小时前
游戏设计:原型与开发 19:U3D工位布置与性格说明书
人工智能·算法·unity·unreal engine·游戏策划·游戏设计
Aman198420 小时前
Claude Code做Unity项目移植(二): 自动执行只读操作,告别频繁的
unity·游戏开发·vibe coding·claude code
暴走约伯1 天前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
郝学胜-神的一滴1 天前
游戏设计:原型与开发 18:Unity入门的第一课
人工智能·程序人生·游戏·ui·unity·游戏引擎
淡海水1 天前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
Solange__1 天前
AI世界模型、3D场景生成和游戏引擎怎么选?按5类任务比较交互、物理与导出
开发语言·人工智能·游戏·平面·3d·自然语言处理·游戏引擎
LF男男1 天前
Flower Defense—UIFacade
unity
呆呆敲代码的小Y2 天前
【实战精选面试题】Unity精选面试题详细解答,按模块整理汇总
人工智能·游戏·unity·游戏引擎