因为在制作动作的时候,希望能看到一些特效的配合,实时表现,所以诞生了这篇文章。 因为编辑器原本并不支持在编辑模式下,预览执行,添加的ActionNode,所以我自己拓展了一下,以便于开发。 首先找到ActionConfigAttribute脚本,添加字段,用来标识,这个ActionNode会在编辑器下运行 然后在ActionMachineHelper脚本下对GetActionHandler进行修改,在寻找ActionNode时,标识是否只获取在编辑器下运行的Node 最后找到ActionEditorSetting,添加UpdateExecuteInEditorActionNode方法,添加在这里 代码我就不进行讲解了,自己看吧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| private void UpdateExecuteInEditorActionNode() { foreach (var item in currentState.actions) { int beginFrame = 0; int endFrame = currentState.frames.Count; var action = ActionMachineHelper.GetActionHandler(item.GetType(), true); if (null != action) { if (item is IHoldFrames holdFrames) { beginFrame = holdFrames.GetBeginFrame(); endFrame = holdFrames.GetEndFrame(); }
ActionNode actionNode = ActionMachineHelper.CreateActionNode(); var actionMachineController = actionMachineTest.GetComponent<ActionMachineController>(); actionMachineController.actionMachine = new ActionMachine(); actionMachineController.actionMachine.controller = actionMachineController; actionNode.actionMachine = actionMachineController.actionMachine; actionNode.config = item; actionNode.SetUpdateCnt(frameSelectIndex - beginFrame); actionNode.handler = action;
if (frameSelectIndex >= beginFrame && frameSelectIndex <= endFrame) { if (beginFrame == frameSelectIndex) { actionNode.handler.Enter(actionNode); } actionNode.handler.Update(actionNode, setting.frameRate); if (endFrame == frameSelectIndex) { actionNode.handler.Exit(actionNode); } } } } }
|
最后应该会有一个报错,记得加个参数设置为false就好了
1
| actionNode.handler = ActionMachineHelper.GetActionHandler(action.GetType(), false);
|
现在应该就能在编辑模式下,执行我们自己添加的Node了,需要注意,Node中的Data我没有进行保存,有需要就自己改把,所以如果有需要的话编辑器下的代码要做区分。 这里再顺手贴一个基于帧变化的粒子控制节点,和动画节点,因为贴图制作时会特效不会和动画绑定在一起,而且当攻速发生变化的时候,动画和粒子也需要统一进行缩放变化,报错的话,自己删了改成常量就行了,根据自己项目需求来。
粒子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| using TFramework.ECS.MonoBehaviours; using TFramework.Extensions; using UnityEngine; using XMLib.AM;
[System.Serializable] [ActionConfig(typeof(ParticleSystemAction), true)] public class ParticleSystemActionConfig : HoldFrames { public string ParticleName; }
public class ParticleSystemAction : IActionHandler { public class Data { public ParticleSystem ParticleSystem; public ActionMachineComponent ActionMachineComponent; }
private ParticleSystem GetParticleSystem(ActionNode node) { ParticleSystem particleSystem; Data data = node.data as Data; if (null != data && null != data.ParticleSystem) { particleSystem = data.ParticleSystem; } else { ActionMachineController controller = (ActionMachineController)node.actionMachine.controller; var config = node.config as ParticleSystemActionConfig; particleSystem = controller.modelRoot.Find(config.ParticleName).GetComponent<ParticleSystem>(); if (null != data) { data.ParticleSystem = particleSystem; } } return particleSystem; }
private ActionMachineComponent GetActionMachineComponent(ActionNode node) { Data data = node.data as Data; if (null != data && null != data.ActionMachineComponent) { return data.ActionMachineComponent; } else { ActionMachineController controller = (ActionMachineController)node.actionMachine.controller; var entityView = controller.modelRoot.GetComponent<EntityView>(); if (null != entityView) { if (null != data) { data.ActionMachineComponent = entityView.Entity.GetComponent<ActionMachineComponent>(); return data.ActionMachineComponent; } } return null; } }
public void Enter(ActionNode node) { Data data = new Data(); node.data = data; var particleSystem = GetParticleSystem(node); if (null != particleSystem) { var mainModule = particleSystem.main; particleSystem.gameObject.SetActive(true); particleSystem.Play(); particleSystem.Simulate(0, true, true); particleSystem.time = 0; var actionMachineComponent = GetActionMachineComponent(node); mainModule.simulationSpeed = null == actionMachineComponent ? 1 : actionMachineComponent.Speed; #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } }
public void Update(ActionNode node, float deltaTime) { var particleSystem = GetParticleSystem(node); if (null != particleSystem) { var mainModule = particleSystem.main; bool rest = particleSystem.time >= mainModule.startLifetime.constantMax ? true : false; particleSystem.Simulate(deltaTime * node.updateCnt, true, rest); var actionMachineComponent = GetActionMachineComponent(node); mainModule.simulationSpeed = null == actionMachineComponent ? 1 : actionMachineComponent.Speed; #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } }
public void Exit(ActionNode node) { var particleSystem = GetParticleSystem(node); if (null != particleSystem) { var mainModule = particleSystem.main; mainModule.simulationSpeed = 1; particleSystem.Stop(); particleSystem.gameObject.SetActive(false); #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } } }
|
动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| using System; using TFramework.ECS.MonoBehaviours; using TFramework.Extensions; using UnityEngine; using XMLib.AM;
[System.Serializable] [ActionConfig(typeof(EffectAnimatorAction), true)] public class EffectAnimatorConfig : HoldFrames { public string PreafabName; public string EffectName; public Vector3 StartPosition; }
public class EffectAnimatorAction : IActionHandler { public class Data { public Animator Animator; public ActionMachineComponent ActionMachineComponent; }
private Animator GetAnimatorController(ActionNode node) { Data data = node.data as Data; if (null != data && null != data.Animator) { return data.Animator; } else { ActionMachineController controller = (ActionMachineController)node.actionMachine.controller; var config = node.config as EffectAnimatorConfig; var animator = controller.modelRoot.Find(config.PreafabName).GetComponent<Animator>(); if (null != data) { data.Animator = animator; } return animator; } }
private ActionMachineComponent GetActionMachineComponent(ActionNode node) { Data data = node.data as Data; if (null != data && null != data.ActionMachineComponent) { return data.ActionMachineComponent; } else { ActionMachineController controller = (ActionMachineController)node.actionMachine.controller; var entityView = controller.modelRoot.GetComponent<EntityView>(); if (null != entityView) { if (null != data) { data.ActionMachineComponent = entityView.Entity.GetComponent<ActionMachineComponent>(); return data.ActionMachineComponent; } } return null; } }
public void Enter(ActionNode node) { Data data = new Data(); node.data = data; var animator = GetAnimatorController(node); if (null != animator) { var config = node.config as EffectAnimatorConfig; animator.transform.localPosition = config.StartPosition; animator.gameObject.SetActive(true); var actionMachineComponent = GetActionMachineComponent(node); animator.speed = null == actionMachineComponent ? 1 : actionMachineComponent.Speed; animator.Play(config.EffectName, 0, 0); #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } }
public void Update(ActionNode node, float deltaTime) { var animator = GetAnimatorController(node); if (null != animator) { var actionMachineComponent = GetActionMachineComponent(node); animator.speed = null == actionMachineComponent ? 1 : actionMachineComponent.Speed; if (Application.isPlaying) { animator.Update(deltaTime); } else { float time = deltaTime * node.updateCnt; var config = node.config as EffectAnimatorConfig; GetCurrentAnimationClip(animator, config.EffectName).SampleAnimation(animator.gameObject, time); } #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } }
public AnimationClip GetCurrentAnimationClip(Animator animator, string state) { return Array.Find(animator.runtimeAnimatorController.animationClips, t => string.Compare(state, t.name) == 0); }
public void Exit(ActionNode node) { var animator = GetAnimatorController(node); if (null != animator) { animator.speed = 1; animator.gameObject.SetActive(false); #if UNITY_EDITOR UnityEditor.SceneView.RepaintAll(); #endif } } }
|
最后贴一下编辑器地址