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 = GameObject.Find("Root_Particles"); 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 { m_Root_Projectiles = GameObject.Find("Root_Projectiles"); 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 { EventGame_TimeScale, // 缩放时间 EventCamera_Zoom, // 相机聚焦 EventCamera_Shake, // 相机晃动 EventCamera_Blur, // 相机模糊 EventCamera_WhiteOut, // 相机白屏 EventMesh_AfterImage, // 角色残像 EventMesh_AfterImageStop, // 角色残像停止事件 EventMesh_FadeIn, // 角色透明度 EventMesh_FadeOut, // 角色透明度 EventMesh_Gloss, // 角色泛光 EventEnv_Dark, EventEnv_Exposure, EventUI_Drift, // EventUI_Blur, // EventProjectile, // 发射体 EventEffect, // 特效 EventSound, // 音效 EventBulletTime, // 子弹时间 } public const int FPS = 30; // timeline 每秒采样30次 private int m_PrevFrame = -1; private Transform m_Root; public UnitController owner { get; private set; } private UnitAnimation m_UnitAnimation { get { return owner.unitAnimation; } } private AnimationData m_PrevAnimationData; public TimelineEventProxy(Transform root, UnitController owner = null) { m_Root = root; this.owner = owner; m_PrevAnimationData = null; } public static Type GetTypeByName(string name) { Type type = Type.GetType(name); return type; } public void ResetPrevAnimationData() { m_PrevAnimationData = null; } 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; } 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); if(owner != null) owner.onTimelineEvent(e); } } } #region Event Handles void EventEffect(AnimationEventBase animEvent) { EventEffect effect = animEvent as EventEffect; if (effect == null) return; string path = effect.effectPath; if (path == null || path == "") return; 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)"; if(owner != null) { Quaternion rot = owner.transform.rotation * Quaternion.Euler(effect.rotation); onClear.Initialize(new PlayEffectInfo(path, EffectPlayTypes.Oneshot, m_Root, effect.position, rot.eulerAngles, effect.scale, 0, false)); } else { 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; if (projectilePath == null || projectilePath == "") return; 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.name = e.name; info.tag = e.tag; info.moveType = e.moveType; info.owner = owner; info.position = m_Root.transform.position + e.posOffset; info.rotation = e.rotation; info.scale = e.scale; if (owner) { info.velocity = owner.transform.rotation * e.velocity; } else { info.velocity = e.velocity; } info.acceleration = e.acceleration; info.lifetime = e.lifeTime; info.sparkPath = e.sparkPath; projectile.Initialize(info); #if UNITY_EDITOR if(isInEditMode && registerProjectile != null) { registerProjectile(projectile); } obj.transform.SetParent(Root_Projectiles.transform); #endif } void EventMesh_AfterImage(AnimationEventBase animEvent) { EventMesh_AfterImage afterImage = animEvent as EventMesh_AfterImage; if (afterImage == null) return ; } #endregion }