ModelContainer.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. using DG.Tweening;
  2. using PublicTools.Unity;
  3. using SC.XR.Unity.Module_InputSystem;
  4. using ShadowStudio.Tool;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using UnityEngine;
  10. using XRTool.Util;
  11. namespace ShadowStudio.Model
  12. {
  13. /// <summary>
  14. /// 模型容器
  15. /// 一个简易模型或者其他的模型资源的容器
  16. /// 自动计算包围盒,大小位置中心等等,支持模型打组编辑(多个模型合为一个模型进行编辑)
  17. /// 拖拽移动缩放组件
  18. /// </summary>
  19. public class ModelContainer : GoodsContainer
  20. {
  21. public GameObject ChooseKuang;
  22. private BoxCollider colliderBody;
  23. private Transform modelRoot;
  24. //private NearInterationGrabbable nearInteration;
  25. public Vector3 offset = Vector3.one * 0.1f;
  26. private bool isInit;
  27. private Renderer[] modelRenderers;
  28. /// <summary>
  29. /// 初始化模型的辅助工具
  30. /// 仅在计算模型Bound时使用,用完即销毁
  31. /// </summary>
  32. private GameObject containerHelper;
  33. private GameObject downInfo;
  34. private TextMesh processLabel;
  35. public override void Start()
  36. {
  37. base.Start();
  38. CalculateRendererBounds();
  39. TimerMgr.Instance.CreateTimer(
  40. PlayEffect, 0);
  41. }
  42. public BoxCollider ColliderBody
  43. {
  44. get
  45. {
  46. if (!colliderBody)
  47. {
  48. colliderBody = UnityUtil.GetBreadthChild<BoxCollider>(transform, "ColliderBody");
  49. }
  50. return colliderBody;
  51. }
  52. }
  53. public Transform ModelRoot
  54. {
  55. get
  56. {
  57. if (!modelRoot)
  58. {
  59. modelRoot = UnityUtil.GetBreadthChild<Transform>(transform, "ModelRoot");
  60. }
  61. return modelRoot;
  62. }
  63. }
  64. //private void Awake()
  65. //{
  66. // ToggleComponent(false);
  67. // //if (Transfer && Transfer.Box)
  68. // //{
  69. // //}
  70. //}
  71. //public override void OnStopScale()
  72. //{
  73. // base.OnStopScale();
  74. // while (ColliderBody.size.magnitude * transform.localScale.x < (Vector3.one * 0.1f).magnitude / 2)
  75. // {
  76. // transform.localScale *= 1.5f;
  77. // }
  78. //}
  79. public override void OnZoomTransfer(TransferState state)
  80. {
  81. base.OnZoomTransfer(state);
  82. if (state == TransferState.Stop)
  83. {
  84. while (ColliderBody.size.magnitude * transform.localScale.x < (Vector3.one * 0.1f).magnitude)
  85. {
  86. transform.localScale *= 1.5f;
  87. }
  88. SendTransfer(2, (int)state);
  89. }
  90. }
  91. public void CalculateRendererBounds()
  92. {
  93. if (ModelRoot.childCount < 1)
  94. {
  95. DownInfo.SetActive(true);
  96. return;
  97. }
  98. DownInfo.SetActive(false);
  99. ChooseKuang.SetActive(false);
  100. //transform.DOKill(true);
  101. if (ModelRenderers == null || ModelRenderers.Length < 1)
  102. ModelRenderers = ModelRoot.GetComponentsInChildren<Renderer>();
  103. Vector3 center = Vector3.zero;
  104. Vector3 curScale = transform.localScale;
  105. Vector3 curPos = transform.position;
  106. Quaternion curRot = transform.rotation;
  107. transform.localScale = Vector3.one;
  108. transform.position = Vector3.zero;
  109. transform.rotation = Quaternion.identity;
  110. ModelRoot.localScale = Vector3.one;
  111. ModelRoot.localPosition = Vector3.zero;
  112. ModelRoot.localRotation = Quaternion.identity;
  113. for (int i = 0; i < ModelRenderers.Length; i++)
  114. {
  115. Renderer rend = ModelRenderers[i];
  116. var collider = rend.GetComponent<Collider>();
  117. if (collider)
  118. {
  119. DestroyImmediate(collider);
  120. }
  121. Vector3 tmpCenter = rend.bounds.center;
  122. center += tmpCenter;
  123. }
  124. //ModelRoot.gameObject.SetActive(false);
  125. Vector3 bScale = transform.lossyScale;
  126. Vector3 bPos = center / ModelRenderers.Length - ModelRoot.transform.position;
  127. bPos.x /= bScale.x;
  128. bPos.y /= bScale.y;
  129. bPos.z /= bScale.z;
  130. ModelRoot.transform.localPosition = bPos;
  131. Bounds bounds = new Bounds(ModelRoot.transform.position, Vector3.zero);
  132. for (int i = 0; i < ModelRenderers.Length; i++)
  133. {
  134. bounds.Encapsulate(ModelRenderers[i].bounds);
  135. }
  136. Vector3 bsize = bounds.size;
  137. bsize.x /= bScale.x;
  138. bsize.y /= bScale.y;
  139. bsize.z /= bScale.z;
  140. ColliderBody.size = bsize;
  141. //if(!this.GetComponentInChildren<ArtTaskAction>()&&!this.GetComponentInChildren<ArtTaskChild>())
  142. //{
  143. while (ColliderBody.size.magnitude > (Vector3.one * 0.2f).magnitude)
  144. {
  145. ColliderBody.size /= 2;
  146. ModelRoot.transform.localScale /= 2;
  147. ModelRoot.transform.localPosition /= 2;
  148. // yield return new WaitForFixedUpdate();
  149. }
  150. // 根据ColliderBody设置包围盒大小
  151. GetComponent<BoxCollider>().size = transform.Find("ColliderBody").GetComponent<BoxCollider>().size;
  152. //}
  153. while (ColliderBody.size.magnitude < (Vector3.one * 0.1f).magnitude)
  154. {
  155. ColliderBody.size *= 2;
  156. ModelRoot.transform.localScale *= 2;
  157. ModelRoot.transform.localPosition *= 2;
  158. //yield return new WaitForFixedUpdate();
  159. }
  160. ModelRoot.transform.localPosition = -ModelRoot.transform.localPosition;
  161. ColliderBody.size += offset;
  162. //ModelRoot.gameObject.SetActive(true);
  163. transform.position = curPos;
  164. transform.rotation = curRot;
  165. transform.localScale = curScale;
  166. Transfer.RemoveBound();
  167. //PlayEffect();
  168. //TimerMgr.Instance.CreateTimer(() =>
  169. //{
  170. // //yield return new WaitForSeconds(1f);
  171. // //transform.DOKill(true);
  172. // //ToggleComponent(true);
  173. // Transfer.RemoveBound();
  174. // //yield return new WaitForEndOfFrame();
  175. // //Transfer.SetBoundActive(false);
  176. // ResetEditorPosition();
  177. //}, 1.05f);
  178. }
  179. public void AddModel(Transform body)
  180. {
  181. if (ModelRoot)
  182. {
  183. UnityUtil.SetParent(ModelRoot, body);
  184. if (Transfer && Transfer.IsInit)
  185. {
  186. CalculateRendererBounds();
  187. }
  188. //body.SetParent(ModelRoot.transform);
  189. //body.transform.localPosition = Vector3.zero;
  190. //body.localRotation = Quaternion.identity;
  191. //body.transform.localScale = Vector3.one;
  192. }
  193. }
  194. //private void Update()
  195. //{
  196. // if (Input.GetKeyDown(KeyCode.O))
  197. // {
  198. // CalculateRendererBounds();
  199. // }
  200. //}
  201. /// <summary>
  202. /// 添加到容器
  203. /// </summary>
  204. /// <param name="art"></param>
  205. public override void AddToContainer(UnityEngine.Object art, ArtInfo info)
  206. {
  207. base.AddToContainer(art, info);
  208. if (art is GameObject)
  209. {
  210. GameObject obj = art as GameObject;
  211. AddModel(obj.transform);
  212. }
  213. }
  214. public Renderer[] ModelRenderers { get => modelRenderers; set => modelRenderers = value; }
  215. public GameObject DownInfo
  216. {
  217. get
  218. {
  219. if (!downInfo)
  220. {
  221. downInfo = UnityUtil.GetBreadthChild(transform, "DownInfo");
  222. }
  223. return downInfo;
  224. }
  225. }
  226. public TextMesh ProcessLabel
  227. {
  228. get
  229. {
  230. if (!processLabel && DownInfo)
  231. {
  232. processLabel = UnityUtil.GetBreadthChild<TextMesh>(DownInfo.transform, "ProcessLabel");
  233. }
  234. return processLabel;
  235. }
  236. }
  237. /// <summary>
  238. /// 更新下载进度
  239. /// </summary>
  240. /// <param name="process"></param>
  241. public override void UpdateProcess(float process)
  242. {
  243. if (ProcessLabel)
  244. {
  245. ProcessLabel.text = process.ToString("P1");
  246. if (process > 0.99f)
  247. {
  248. ProcessLabel.text = 99 + "%";
  249. }
  250. }
  251. }
  252. }
  253. }