CustomGizmo.cs 6.2 KB

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