using ChivaXR; using Sirenix.OdinInspector; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; [ExecuteAlways] [ExecuteInEditMode] public class ToolAnimationItem : SerializedMonoBehaviour { #region 模型及工具锚点参数 [FoldoutGroup("模型及锚点", Order = -1)] [HorizontalGroup("模型及锚点/模型组")] [LabelText("模型")] [LabelWidth(30)] public GameObject model; [FoldoutGroup("模型及锚点", Order = -1)] [LabelText("锚点")] [LabelWidth(30)] [HorizontalGroup("模型及锚点/模型组")] public Transform modelAnchor; [FoldoutGroup("工具及锚点", Order = -1)] [LabelText("工具")] [LabelWidth(30)] [HorizontalGroup("工具及锚点/模型组")] public GameObject toolObj; [FoldoutGroup("工具及锚点", Order = -1)] [LabelText("锚点")] [LabelWidth(30)] [HorizontalGroup("工具及锚点/模型组")] public Transform toolAnchor; private GameObject toolPrefab; [FoldoutGroup("工具及锚点", Order = -1)] [InfoBox("工具预支物路径:Assets/ChivaFramework/Framework/SimulationToolDev/ToolManager/ToolModel")] [ValueDropdown("GetAllToolModel")] [ShowInInspector] [LabelText("加载模型预支物")] public GameObject ToolPrefab { get { return toolPrefab; } set { if (toolPrefab != value) { toolPrefab = value; if (toolObj != null) { DestroyImmediate(toolObj); } toolObj = GameObject.Instantiate(toolPrefab); if (modelAnchor != null) { if (toolAnchor == null) { toolAnchor = new GameObject("工具锚点(该锚点位置会强制刷新,若需调整请调整子级工具预支物相对位置)").transform; toolAnchor.transform.parent = modelAnchor.transform; toolAnchor.transform.localPosition = Vector3.zero; toolAnchor.transform.localRotation = Quaternion.identity; toolAnchor.transform.localScale = Vector3.one; } else { toolAnchor.name = "工具锚点(该锚点位置会强制刷新,若需调整请调整子级工具预支物相对位置)"; toolAnchor.transform.parent = modelAnchor.transform; toolAnchor.transform.localPosition = Vector3.zero; toolAnchor.transform.localRotation = Quaternion.identity; toolAnchor.transform.localScale = Vector3.one; } toolObj.transform.parent = toolAnchor.transform; toolObj.transform.localPosition = Vector3.zero; toolObj.transform.localRotation = Quaternion.identity; toolObj.transform.localScale = Vector3.one; } } } } #if UNITY_EDITOR private static IEnumerable GetAllToolModel() { var root = "Assets/ChivaFramework/Framework/SimulationToolDev/ToolManager/ToolModel"; return UnityEditor.AssetDatabase.GetAllAssetPaths() .Where(x => x.StartsWith(root)) .Select(x => x.Substring(root.Length)) .Select(x => new ValueDropdownItem(x, UnityEditor.AssetDatabase.LoadAssetAtPath(root + x))); } #endif public bool ToolActiveState { get { if (toolAnchor == null) { return false; } else { return toolAnchor.gameObject.activeSelf; } } } [FoldoutGroup("工具及锚点", Order = -1)] [Button("$ToolBtnName")] public void ToolActive() { if (toolAnchor != null) { toolAnchor.gameObject.SetActive(!toolAnchor.gameObject.activeSelf); } } public string ToolBtnName { get { if (ToolActiveState) { return "隐藏工具"; } else { return "显示工具"; } } } #endregion [SerializeField] [HideInInspector] private ToolAnimationBase toolAnimationBase; [BoxGroup("工具动画")] [HideLabel] [ShowInInspector] [TypeFilter("GetFilteredTypeList")] public ToolAnimationBase ToolAnimationBase { get { return toolAnimationBase; } set { if (toolAnimationBase != value) { toolAnimationBase = value; } } } public IEnumerable GetFilteredTypeList() { var q = typeof(ToolAnimationBase).Assembly.GetTypes() .Where(x => !x.IsAbstract) .Where(x => !x.IsGenericTypeDefinition) .Where(x => typeof(ToolAnimationBase).IsAssignableFrom(x)); return q; } public void SetInitState(bool reverse) { isPlaying = false; if (toolAnimationBase != null) { toolAnimationBase.InitState(this,reverse); } } public void SetFinishedState(bool reverse) { isPlaying = false; if (toolAnimationBase != null) { toolAnimationBase.FinishedState(this, reverse); } } public bool PlayToolAnimation(bool reverse) { if (toolAnimationBase != null) { toolAnimationBase.PlayUpdate(this, reverse); } return isPlaying; } void Awake() { if (toolAnchor.gameObject.activeSelf) { toolAnchor.gameObject.SetActive(false); } } public bool editorReverse = false; [Button("$PlayBtnName")] public void Play() { if (!isPlaying) { isPlaying = true; if (toolAnimationBase != null) { toolAnimationBase.PlayTrigger(this, editorReverse); } } else { isPlaying = false; if (toolAnimationBase != null) { toolAnimationBase.StopPlay(this, editorReverse); } } } public string PlayBtnName { get { if (isPlaying) { return "停止"; } else { return "播放"; } } } [HideInInspector] public bool isPlaying; public void Destroy(GameObject obj) { if (obj != null) { DestroyImmediate(obj); } } #if UNITY_EDITOR [FoldoutGroup("模型及锚点", Order = -1)] [Button("重置模型")] public void AddSelectObj() { if (Selection.gameObjects.Length == 0) return; model = Selection.activeGameObject; if (modelAnchor != null) { //DestroyImmediate(modelAnchor.gameObject); modelAnchor.name = "锚点_" + model.gameObject.name; modelAnchor.transform.parent = transform; modelAnchor.transform.position = model.transform.position; modelAnchor.transform.rotation = model.transform.rotation; } else { GameObject tmpItem = new GameObject("锚点_" + model.gameObject.name); tmpItem.transform.parent = transform; tmpItem.transform.position = model.transform.position; tmpItem.transform.rotation = model.transform.rotation; modelAnchor = tmpItem.transform; } } private void OnDrawGizmos() { if (ToolAnimationBase != null) { ToolAnimationBase.OnDrawGizmos(this); } } /// /// 销毁所有子级信息 /// /// private void DestroyChild(Transform item) { if (item.childCount == 0) return; for (int i = item.childCount - 1; i >= 0; i--) { DestroyImmediate(item.GetChild(i).gameObject); } } private void OnEnable() { EditorApplication.update += EditorUpdate; } private void OnDisable() { EditorApplication.update -= EditorUpdate; } private float timer = 0; void EditorUpdate() { if (!isPlaying|| Application.isPlaying) return; toolAnimationBase.EditorPlayUpdate(this, editorReverse); } #endif }