CustomGizmo.cs 6.3 KB

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