UnityAnimationDataCreator.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using ChivaXR;
  5. using Sirenix.OdinInspector;
  6. using System.Linq;
  7. using System.Text.RegularExpressions;
  8. using UnityEngine.Events;
  9. /// <summary>
  10. /// UnityAnimation动画片段创建器
  11. /// </summary>
  12. public class UnityAnimationDataCreator : SerializedMonoBehaviour
  13. {
  14. public Animation targetAnimation;
  15. [TableList(MaxScrollViewHeight = 300, ShowPaging = true, NumberOfItemsPerPage = 10)]
  16. public List<AniDataContainer> animationDatas = new List<AniDataContainer>();
  17. /// <summary>
  18. /// 临时存储动画片段名称
  19. /// </summary>
  20. private List<string> tempData = new List<string>();
  21. public UnityAction<AniData> EnterCurrentAniData;
  22. [ShowIf("IsCreatData")]
  23. [Button("创建当前Animation的Data列表")]
  24. public void CreatorAnimationDatas()
  25. {
  26. tempData.Clear();
  27. foreach (AnimationState state in targetAnimation)
  28. {
  29. tempData.Add(state.name);
  30. }
  31. IOrderedEnumerable<string> recordDataEnumerables = tempData.OrderBy(
  32. x => float.Parse(Regex.Match(x, "\\d+(\\.?\\d?)").Value));
  33. foreach (var item in recordDataEnumerables)
  34. {
  35. AniData tempData = new GameObject("").AddComponent<AniData>();
  36. tempData.transform.parent = this.transform;
  37. AniDriver_UnityAnimation tempAniDriver = new AniDriver_UnityAnimation();
  38. tempAniDriver.animation = targetAnimation;
  39. tempAniDriver.aniName = item;
  40. tempAniDriver.animationSequence = AnimationSequence.waitFinished;
  41. tempData.AnimationDriverDatas.Add(tempAniDriver);
  42. tempData.aniName = targetAnimation.name + "/" + item;
  43. tempData.aniDescriptioin = "播放动画" + tempData.aniName;
  44. tempData.gameObject.name = tempData.aniName;
  45. animationDatas.Add(new AniDataContainer(tempData));
  46. }
  47. }
  48. public bool IsCreatData()
  49. {
  50. return animationDatas.Count == 0;
  51. }
  52. /// <summary>
  53. /// 播放
  54. /// </summary>
  55. /// <param name="aniDataName"></param>
  56. public void SetAniDataState(string aniDataName, Animation_State aniState)
  57. {
  58. if (animationDatas.Where(s => s.AniDataName == aniDataName).Count() > 0)
  59. {
  60. AniDataContainer tempAniData = animationDatas.Where(s => s.AniDataName == aniDataName).First();
  61. switch (aniState)
  62. {
  63. case Animation_State.initState:
  64. tempAniData.aniData.SetInitState();
  65. break;
  66. case Animation_State.finishedState:
  67. tempAniData.aniData.SetFinishedState();
  68. break;
  69. }
  70. }
  71. else
  72. {
  73. Debug.LogError("无该动画片段--->" + aniDataName);
  74. }
  75. }
  76. private IEnumerable GetAnimationDataNames()
  77. {
  78. return animationDatas.Select(s => new ValueDropdownItem(s.AniDataName, s.AniDataName));
  79. }
  80. #region AnimationStateController
  81. /// <summary>
  82. /// 当前步骤在List中的索引(从0开始)
  83. /// </summary>
  84. public int CurrentListID
  85. {
  86. get
  87. {
  88. if ((currentStepID - 1) >= 0 && ((currentStepID - 1) < CurrentListsCount))
  89. {
  90. return currentStepID - 1;
  91. }
  92. Debug.LogError("当前步骤超出List范围");
  93. return 0;
  94. }
  95. }
  96. /// <summary>
  97. /// 当前List步骤数量
  98. /// </summary>
  99. public int CurrentListsCount
  100. {
  101. get
  102. {
  103. return animationDatas.Count;
  104. }
  105. }
  106. [HorizontalGroup("JumpState")]
  107. [Button("上一步")]
  108. public void PreProcess()
  109. {
  110. JumpProcess(currentStepID - 1);
  111. }
  112. [HorizontalGroup("JumpState")]
  113. [Button("下一步")]
  114. public void EnterNextProcess()
  115. {
  116. JumpProcess(currentStepID + 1);
  117. }
  118. [HorizontalGroup("JumpState")]
  119. [Button("初始化动画组")]
  120. /// <summary>
  121. ///初始化步骤状态
  122. /// </summary>
  123. public void InitStepState()
  124. {
  125. for (int i = animationDatas.Count - 1; i >= 0; i--)
  126. {
  127. SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState);
  128. }
  129. Debug.Log("初始化跳转至第一步");
  130. currentStepID = 1;
  131. RefreshAniData();
  132. }
  133. [Button("播放当前动画")]
  134. public void PlayCurrentAniData()
  135. {
  136. animationDatas[CurrentListID].aniData.PlayData();
  137. }
  138. [HorizontalGroup("JumpAni")]
  139. [ValueDropdown("GetProcessAniDataNames")]
  140. public string jumpTargetAnimation;
  141. private IEnumerable GetProcessAniDataNames()
  142. {
  143. return animationDatas.Select(s => new ValueDropdownItem(s.AniDataName, s.AniDataName));
  144. }
  145. [HorizontalGroup("JumpAni")]
  146. [Button("跳转到对应动画")]
  147. public void JumpToTargetAnimation()
  148. {
  149. JumpProcess(jumpTargetAnimation);
  150. }
  151. [BoxGroup("目前动画信息")]
  152. [GUIColor(0.7f, 1, 0.7f)]
  153. public GameObject currentAniDataContainer;
  154. [BoxGroup("目前动画信息")]
  155. [GUIColor(0.7f, 1, 0.7f)]
  156. [ReadOnly]
  157. /// <summary>
  158. /// 当前步骤(从1开始)
  159. /// </summary>
  160. public int currentStepID = 1;
  161. [BoxGroup("目前动画信息")]
  162. public string currentAniClipName;
  163. [BoxGroup("目前动画信息")]
  164. [Range(0, 1)]
  165. [OnValueChanged("AniDataProcessChange")]
  166. public float currentAniDataProcess;
  167. [BoxGroup("目前动画信息")]
  168. [ReadOnly]
  169. public int currentAniFrame;
  170. public void AniDataProcessChange()
  171. {
  172. if (targetAnimation == null) return;
  173. AnimationState aniState = targetAnimation[currentAniClipName];
  174. aniState.enabled = true;
  175. aniState.speed = 0;
  176. aniState.weight = 1;
  177. aniState.normalizedTime = currentAniDataProcess;
  178. targetAnimation.Sample();
  179. aniState.enabled = false;
  180. float totalFrame = aniState.length / (1 / aniState.clip.frameRate);
  181. currentAniFrame = Mathf.RoundToInt((totalFrame * aniState.normalizedTime) % totalFrame);
  182. }
  183. /// <summary>
  184. /// 刷新当前播放信息
  185. /// </summary>
  186. private void RefreshAniData()
  187. {
  188. currentAniDataContainer = GameObject.Find(animationDatas[currentStepID - 1].AniDataName);
  189. currentAniClipName = animationDatas[currentStepID - 1].AniDataName.Split('/')[1];
  190. currentAniDataProcess = 0;
  191. currentAniFrame = 0;
  192. }
  193. /// <summary>
  194. /// 跳步
  195. /// </summary>
  196. public void JumpProcess(int targetStepID)
  197. {
  198. //步骤错误
  199. if (targetStepID < 1 || targetStepID > CurrentListsCount)
  200. {
  201. Debug.LogError("流程跳转:无目标步骤");
  202. return;
  203. }
  204. if (targetStepID == currentStepID)
  205. {
  206. SetAniDataState(animationDatas[CurrentListID].AniDataName, Animation_State.initState);
  207. }
  208. //向前跳步
  209. else if (targetStepID < currentStepID)
  210. {
  211. for (int i = currentStepID - 1; i >= targetStepID - 1; i--)
  212. {
  213. SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState);
  214. }
  215. }
  216. //向后跳步
  217. else
  218. {
  219. for (int i = currentStepID - 1; i <= targetStepID - 1; i++)
  220. {
  221. if (i.Equals(targetStepID - 1))
  222. {
  223. SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState);
  224. }
  225. else
  226. {
  227. SetAniDataState(animationDatas[i].AniDataName, Animation_State.finishedState);
  228. }
  229. }
  230. }
  231. currentStepID = targetStepID;
  232. RefreshAniData();
  233. EnterCurrentAniData?.Invoke(animationDatas[CurrentListID].aniData);
  234. }
  235. /// <summary>
  236. /// 跳步
  237. /// </summary>
  238. /// <param name="targetStepID">目标步骤ID</param>
  239. /// <param name="editorMode">是否在编辑器状态下</param>
  240. /// <param name="enter">是否执行当前步骤</param>
  241. public void JumpProcess(string aniName)
  242. {
  243. int targetStepID = 0;
  244. if (animationDatas.Where(s => s.AniDataName == aniName).Count() > 0)
  245. {
  246. AniDataContainer tempAniData = animationDatas.Where(s => s.AniDataName == aniName).First();
  247. targetStepID = animationDatas.IndexOf(tempAniData)+1;
  248. }
  249. else
  250. {
  251. return;
  252. }
  253. //步骤错误
  254. if (targetStepID < 1 || targetStepID > CurrentListsCount)
  255. {
  256. Debug.LogError("流程跳转:无目标步骤");
  257. return;
  258. }
  259. if (targetStepID == currentStepID)
  260. {
  261. SetAniDataState(animationDatas[CurrentListID].AniDataName, Animation_State.initState);
  262. }
  263. //向前跳步
  264. else if (targetStepID < currentStepID)
  265. {
  266. for (int i = currentStepID - 1; i >= targetStepID - 1; i--)
  267. {
  268. SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState);
  269. }
  270. }
  271. //向后跳步
  272. else
  273. {
  274. for (int i = currentStepID - 1; i <= targetStepID - 1; i++)
  275. {
  276. if (i.Equals(targetStepID - 1))
  277. {
  278. SetAniDataState(animationDatas[i].AniDataName, Animation_State.initState);
  279. }
  280. else
  281. {
  282. SetAniDataState(animationDatas[i].AniDataName, Animation_State.finishedState);
  283. }
  284. }
  285. }
  286. currentStepID = targetStepID;
  287. RefreshAniData();
  288. EnterCurrentAniData?.Invoke(animationDatas[CurrentListID].aniData);
  289. }
  290. #endregion
  291. }