Created
March 11, 2020 02:31
-
-
Save stilllisisi/aa0e2a1f92eb13aa3e9c1df06799e7a5 to your computer and use it in GitHub Desktop.
【游戏-unity】Unity Toggle 关联动画事件。Unity GUI 里的 Button 可以通过更改 Transition 类型为动画来关联动画事件,Toggle 组件也可以,但是这些动画事件不是 Toggle 值变化时的通知事件,所以需要专门的通知动画事件
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//下面就来看看Toggle关联动画事件的实现。 | |
//主要是编辑器部分借鉴使用 SelectableEditor 的代码: | |
using UnityEngine; | |
using UnityEngine.UI; | |
[RequireComponent(typeof(Toggle))] | |
[RequireComponent(typeof(Animator))] | |
public class ToggleAnimatorTrigger : MonoBehaviour | |
{ | |
private const string kDefaultOnAnimName = "On"; | |
private const string kDefaultOffAnimName = "Off"; | |
[SerializeField] | |
private string m_OnTrigger = kDefaultOnAnimName; | |
[SerializeField] | |
private string m_OffTrigger = kDefaultOffAnimName; | |
private Animator m_Animator; | |
private Toggle m_Toggle; | |
void Awake() | |
{ | |
m_Animator = GetComponent<Animator>(); | |
m_Toggle = GetComponent<Toggle>(); | |
m_Toggle.onValueChanged.AddListener(OnToggleValueChanged); | |
} | |
private void OnToggleValueChanged(bool on) | |
{ | |
m_Animator.ResetTrigger(m_OnTrigger); | |
m_Animator.ResetTrigger(m_OffTrigger); | |
m_Animator.SetTrigger(on ? m_OnTrigger : m_OffTrigger); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//编辑器代码: | |
using UnityEngine; | |
using UnityEditor; | |
using UnityEditor.Animations; | |
[CustomEditor(typeof(ToggleAnimatorTrigger))] | |
public class ToggleAnimatorTriggerEditor : Editor | |
{ | |
SerializedProperty m_OnTriggerProperty; | |
SerializedProperty m_OffTriggerProperty; | |
void OnEnable() | |
{ | |
m_OnTriggerProperty = serializedObject.FindProperty("m_OnTrigger"); | |
m_OffTriggerProperty = serializedObject.FindProperty("m_OffTrigger"); | |
} | |
public override void OnInspectorGUI() | |
{ | |
serializedObject.Update(); | |
var go = (target as ToggleAnimatorTrigger).gameObject; | |
var animator = go.GetComponent<Animator>(); | |
EditorGUILayout.LabelField("Transition", "Animation"); | |
++EditorGUI.indentLevel; | |
{ | |
EditorGUILayout.PropertyField(m_OnTriggerProperty); | |
EditorGUILayout.PropertyField(m_OffTriggerProperty); | |
if (animator == null || animator.runtimeAnimatorController == null) | |
{ | |
Rect buttonRect = EditorGUILayout.GetControlRect(); | |
buttonRect.xMin += EditorGUIUtility.labelWidth; | |
if (GUI.Button(buttonRect, "Auto Generate Animation", EditorStyles.miniButton)) | |
{ | |
var controller = GenerateSelectableAnimatorContoller(m_OnTriggerProperty.stringValue, | |
m_OffTriggerProperty.stringValue , go); | |
if (controller != null) | |
{ | |
if (animator == null) | |
animator = go.AddComponent<Animator>(); | |
AnimatorController.SetAnimatorController(animator, controller); | |
} | |
} | |
} | |
} | |
--EditorGUI.indentLevel; | |
serializedObject.ApplyModifiedProperties(); | |
} | |
private static AnimatorController GenerateSelectableAnimatorContoller(string onTrigger, string offTrigger, GameObject target) | |
{ | |
if (target == null) | |
return null; | |
// Where should we create the controller? | |
var path = GetSaveControllerPath(target); | |
if (string.IsNullOrEmpty(path)) | |
return null; | |
// Create controller and hook up transitions. | |
var controller = AnimatorController.CreateAnimatorControllerAtPath(path); | |
GenerateTriggerableTransition(onTrigger, controller); | |
GenerateTriggerableTransition(offTrigger, controller); | |
AssetDatabase.ImportAsset(path); | |
return controller; | |
} | |
private static string GetSaveControllerPath(GameObject target) | |
{ | |
var defaultName = target.gameObject.name; | |
var message = string.Format("Create a new animator for the game object '{0}':", defaultName); | |
return EditorUtility.SaveFilePanelInProject("New Animation Contoller", defaultName, "controller", message); | |
} | |
private static AnimationClip GenerateTriggerableTransition(string name, AnimatorController controller) | |
{ | |
// Create the clip | |
var clip = AnimatorController.AllocateAnimatorClip(name); | |
AssetDatabase.AddObjectToAsset(clip, controller); | |
// Create a state in the animatior controller for this clip | |
var state = controller.AddMotion(clip); | |
// Add a transition property | |
controller.AddParameter(name, AnimatorControllerParameterType.Trigger); | |
// Add an any state transition | |
var stateMachine = controller.layers[0].stateMachine; | |
var transition = stateMachine.AddAnyStateTransition(state); | |
transition.AddCondition(AnimatorConditionMode.If, 0, name); | |
transition.exitTime = 1f; | |
transition.duration = 0f; | |
return clip; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://gameinstitute.qq.com/community/detail/128753