CustomGizmo.cs 6.1 KB

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