CustomGizmo.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. using System;
  2. using System.Reflection;
  3. using UnityEngine;
  4. namespace COM3D2.MeidoPhotoStudio.Plugin
  5. {
  6. internal class CustomGizmo : GizmoRender
  7. {
  8. private static Camera camera = GameMain.Instance.MainCamera.camera;
  9. private Transform target;
  10. private FieldInfo beSelectedType = Utility.GetFieldInfo<GizmoRender>("beSelectedType");
  11. private int SelectedType => (int)beSelectedType.GetValue(this);
  12. private static FieldInfo is_drag_ = Utility.GetFieldInfo<GizmoRender>("is_drag_");
  13. public static bool IsDrag
  14. {
  15. get => (bool)is_drag_.GetValue(null);
  16. private set => is_drag_.SetValue(null, value);
  17. }
  18. private Vector3 positionOld = Vector3.zero;
  19. private Vector3 deltaPosition = Vector3.zero;
  20. private Vector3 localPositionOld = Vector3.zero;
  21. private Vector3 deltaLocalPosition = Vector3.zero;
  22. private Quaternion rotationOld = Quaternion.identity;
  23. private Quaternion deltaRotation = Quaternion.identity;
  24. private Quaternion deltaLocalRotation = Quaternion.identity;
  25. private Vector3 deltaScale = Vector3.zero;
  26. private Vector3 scaleOld = Vector3.one;
  27. private GizmoType gizmoTypeOld;
  28. private GizmoType gizmoType;
  29. public GizmoType CurrentGizmoType
  30. {
  31. get => gizmoType;
  32. set
  33. {
  34. gizmoType = value;
  35. if (gizmoTypeOld != gizmoType) SetGizmoType(gizmoType);
  36. gizmoTypeOld = gizmoType;
  37. }
  38. }
  39. public bool IsGizmoDrag => GizmoVisible && IsDrag && SelectedType != 0;
  40. public bool GizmoVisible
  41. {
  42. get => base.Visible;
  43. set
  44. {
  45. if (value && IsDrag) IsDrag = false;
  46. base.Visible = value;
  47. }
  48. }
  49. public GizmoMode gizmoMode = GizmoMode.Local;
  50. public event EventHandler GizmoDrag;
  51. public enum GizmoType
  52. {
  53. Rotate, Move, Scale, None
  54. }
  55. public enum GizmoMode
  56. {
  57. Local, World, Global
  58. }
  59. public static CustomGizmo Make(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
  60. {
  61. GameObject gizmoGo = new GameObject("[MPS Gizmo]");
  62. gizmoGo.transform.SetParent(target);
  63. CustomGizmo gizmo = gizmoGo.AddComponent<CustomGizmo>();
  64. gizmo.target = target;
  65. gizmo.lineRSelectedThick = 0.25f;
  66. gizmo.offsetScale = scale;
  67. gizmo.gizmoMode = mode;
  68. gizmo.CurrentGizmoType = GizmoType.Rotate;
  69. return gizmo;
  70. }
  71. public override void Update()
  72. {
  73. BeginUpdate();
  74. base.Update();
  75. if (IsGizmoDrag) SetTargetTransform();
  76. SetTransform();
  77. EndUpdate();
  78. }
  79. private void BeginUpdate()
  80. {
  81. deltaPosition = transform.position - positionOld;
  82. deltaRotation = transform.rotation * Quaternion.Inverse(rotationOld);
  83. deltaLocalPosition = transform.InverseTransformVector(deltaPosition);
  84. deltaLocalRotation = Quaternion.Inverse(rotationOld) * transform.rotation;
  85. deltaScale = transform.localScale - scaleOld;
  86. }
  87. private void EndUpdate()
  88. {
  89. positionOld = transform.position;
  90. rotationOld = transform.rotation;
  91. scaleOld = transform.localScale;
  92. }
  93. private void SetTargetTransform()
  94. {
  95. bool dragged = false;
  96. switch (gizmoMode)
  97. {
  98. case GizmoMode.Local:
  99. target.transform.position += target.transform.TransformVector(deltaLocalPosition).normalized
  100. * deltaLocalPosition.magnitude;
  101. target.transform.rotation = target.transform.rotation * deltaLocalRotation;
  102. target.transform.localScale += deltaScale;
  103. if (deltaLocalRotation != Quaternion.identity || deltaLocalPosition != Vector3.zero
  104. || deltaScale != Vector3.zero
  105. ) dragged = true;
  106. break;
  107. case GizmoMode.World:
  108. case GizmoMode.Global:
  109. target.transform.position += deltaPosition;
  110. target.transform.rotation = deltaRotation * target.transform.rotation;
  111. if (deltaRotation != Quaternion.identity || deltaPosition != Vector3.zero) dragged = true;
  112. break;
  113. }
  114. if (dragged) OnGizmoDrag();
  115. }
  116. private void SetTransform()
  117. {
  118. switch (gizmoMode)
  119. {
  120. case GizmoMode.Local:
  121. transform.position = target.transform.position;
  122. transform.rotation = target.transform.rotation;
  123. break;
  124. case GizmoMode.World:
  125. transform.position = target.transform.position;
  126. transform.rotation = Quaternion.identity;
  127. break;
  128. case GizmoMode.Global:
  129. transform.position = target.transform.position;
  130. transform.rotation = Quaternion.LookRotation(
  131. transform.position - camera.transform.position, transform.up
  132. );
  133. break;
  134. }
  135. transform.localScale = Vector3.one;
  136. }
  137. private void SetGizmoType(GizmoType gizmoType)
  138. {
  139. switch (gizmoType)
  140. {
  141. case GizmoType.Move:
  142. this.eAxis = true;
  143. this.eRotate = false;
  144. this.eScal = false;
  145. break;
  146. case GizmoType.Rotate:
  147. this.eAxis = false;
  148. this.eRotate = true;
  149. this.eScal = false;
  150. break;
  151. case GizmoType.Scale:
  152. this.eAxis = false;
  153. this.eRotate = false;
  154. this.eScal = true;
  155. break;
  156. case GizmoType.None:
  157. this.eAxis = false;
  158. this.eRotate = false;
  159. this.eScal = false;
  160. break;
  161. }
  162. }
  163. private void OnGizmoDrag()
  164. {
  165. GizmoDrag?.Invoke(this, EventArgs.Empty);
  166. }
  167. }
  168. }