using System; using System.Collections; using System.Reflection; using System.Collections.Generic; using UnityEngine; // 执行帧事件 [DisallowMultipleComponent] public partial class TimelineEventProxy { #if UNITY_EDITOR // ActionTool里 private static GameObject m_Root_Particles; public static GameObject Root_Particles { get { if (m_Root_Particles == null) m_Root_Particles = new GameObject("Root_Particles"); return m_Root_Particles; } } private static GameObject m_Root_Projectiles; public static GameObject Root_Projectiles { get { if (m_Root_Projectiles == null) m_Root_Projectiles = new GameObject("Root_Projectiles"); return m_Root_Projectiles; } } public bool isInEditMode; public delegate void RegisterProjectileHandle(Projectile projectile); public RegisterProjectileHandle registerProjectile; public delegate void RegisterParticleSystemHandle(FxClear vfx); public RegisterParticleSystemHandle registerParticleSystem; #endif public enum EEventType { EventCamera_Zoom, // 相机聚焦 EventCamera_Shake, // 相机晃动 EventCamera_Blur, // 相机模糊 EventCamera_WhiteOut, // 相机白屏 EventMesh_AfterImage, // 角色残像 EventMesh_FadeIn, // 角色透明度 EventMesh_FadeOut, // 角色透明度 EventMesh_Gloss, // 角色泛光 EventEnv_Dark, EventEnv_Exposure, EventUI_Drift, // EventUI_Blur, // EventProjectile, // 发射体 EventEffect, // 特效 EventSound, // 音效 EventBulletTime, // 子弹时间 } public const int kMaxEventsPerFrame = 10; public const int FPS = 30; // timeline 每秒采样30次 private int m_PrevFrame = -1; private Transform m_Root; private UnitController m_Owner; private UnitAnimation m_UnitAnimation { get { return m_Owner.unitAnimation; } } private AnimationData m_PrevAnimationData; public TimelineEventProxy(Transform root, UnitController owner = null) { m_Root = root; m_Owner = owner; m_PrevAnimationData = null; } public static Type GetTypeByName(string name) { Type type = Type.GetType(name); return type; } public void ExecuteAnimationEvents(AnimationData animData, float animFrame) { if (animData == null) return; int frame = (int)animFrame; if (m_PrevAnimationData != animData) { m_PrevFrame = frame; m_PrevAnimationData = animData; } if (frame != m_PrevFrame) { for (int i = m_PrevFrame + 1; i <= frame; i++) { List framesHasEvent = animData.GetAnimationEventFrameIndices(); if (framesHasEvent.Contains(i)) { List events = animData.GetAnimationEventsAtFrame(i); ExecuteEvents(events); ListPool.Release(events); } ListPool.Release(framesHasEvent); } } m_PrevFrame = frame; } #region Event Handles void ExecuteEvents(List events) { if (events == null || events.Count == 0) return; foreach (var e in events) { string name = e.type.ToString(); MethodInfo method = GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(AnimationEventBase) }, null); if (method != null) { object[] param = new object[] { e }; method.Invoke(this, param); } } } void EventEffect(AnimationEventBase animEvent) { EventEffect effect = animEvent as EventEffect; if (effect == null) return; string path = effect.effectPath; GameObject prefab = ResourceManager.Instance.LoadAsset(path); if (prefab != null) { GameObject root = new GameObject(); GameObject go = GameObject.Instantiate(prefab); go.transform.SetParent(root.transform); FxClear onClear = root.AddComponent(); onClear.gameObject.name = prefab.name + "(Clone)"; onClear.Initialize(new PlayEffectInfo(path, EffectPlayTypes.Oneshot, m_Root, effect.position, effect.rotation, effect.scale, 0, false)); #if UNITY_EDITOR if (isInEditMode && registerParticleSystem != null) { registerParticleSystem(onClear); } onClear.gameObject.transform.SetParent(Root_Particles.transform); #endif } } void EventCamera_Shake(AnimationEventBase animEvent) { } void EventProjectile(AnimationEventBase animEvent) { EventProjectile e = animEvent as EventProjectile; if (e == null) return; string projectilePath = e.projectilePath; GameObject prefab = ResourceManager.Instance.LoadAsset(projectilePath); if(prefab == null) { LogHelper.LogError("缺少对应的projectile, " + projectilePath); return; } if(prefab.GetComponent() == null) { LogHelper.LogError("没有projectile脚本"); return; } GameObject obj = GameObject.Instantiate(prefab); Projectile projectile = obj.GetComponent(); ProjectileInfo info = new ProjectileInfo(); info.owner = m_Owner; info.position = m_Root.transform.position + e.posOffset; info.rotation = e.rotation; info.scale = e.scale; info.direction = Vector3.right; info.velocity = Vector3.right * 10f; info.lifetime = 5; info.sparkPath = e.sparkPath; projectile.Initialize(info); #if UNITY_EDITOR if(isInEditMode && registerProjectile != null) { registerProjectile(projectile); } obj.transform.SetParent(Root_Projectiles.transform); #endif } #endregion }