DragPoint.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. using System;
  2. using UnityEngine;
  3. namespace COM3D2.MeidoPhotoStudio.Plugin
  4. {
  5. using static CustomGizmo;
  6. internal abstract class DragPoint : MonoBehaviour
  7. {
  8. public const float defaultAlpha = 0.75f;
  9. private static GameObject dragPointParent = new GameObject("[MPS DragPoint Parent]");
  10. private const float doubleClickSensitivity = 0.3f;
  11. private Func<Vector3> position;
  12. private Func<Vector3> rotation;
  13. private Collider collider;
  14. private Renderer renderer;
  15. private bool reinitializeDrag;
  16. protected bool Transforming => CurrentDragType >= DragType.MoveXZ;
  17. protected bool Special => CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete;
  18. protected bool Moving => CurrentDragType == DragType.MoveXZ || CurrentDragType == DragType.MoveY;
  19. protected bool Rotating => CurrentDragType >= DragType.RotLocalXZ && CurrentDragType <= DragType.RotLocalY;
  20. protected bool Scaling => CurrentDragType == DragType.Scale;
  21. protected bool Selecting => CurrentDragType == DragType.Select;
  22. protected bool Deleting => CurrentDragType == DragType.Delete;
  23. private Vector3 startMousePosition;
  24. protected static Camera camera = GameMain.Instance.MainCamera.camera;
  25. public enum DragType
  26. {
  27. None, Ignore, Select, Delete,
  28. MoveXZ, MoveY,
  29. RotLocalXZ, RotY, RotLocalY,
  30. Scale
  31. }
  32. public Transform MyObject { get; protected set; }
  33. public GameObject MyGameObject => MyObject.gameObject;
  34. private float startDoubleClick;
  35. private Vector3 screenPoint;
  36. private Vector3 startOffset;
  37. private Vector3 newOffset;
  38. public static Material dragPointMaterial = new Material(Shader.Find("CM3D2/Trans_AbsoluteFront"));
  39. public static readonly Color defaultColour = new Color(0f, 0f, 0f, defaultAlpha);
  40. public Vector3 BaseScale { get; private set; }
  41. private float dragPointScale = 1f;
  42. public float DragPointScale
  43. {
  44. get => dragPointScale;
  45. set
  46. {
  47. dragPointScale = value;
  48. transform.localScale = BaseScale * dragPointScale;
  49. }
  50. }
  51. public GameObject GizmoGo { get; protected set; }
  52. public CustomGizmo Gizmo { get; protected set; }
  53. private DragType oldDragType;
  54. private DragType currentDragType;
  55. protected DragType CurrentDragType
  56. {
  57. get => currentDragType;
  58. set
  59. {
  60. if (value != oldDragType)
  61. {
  62. currentDragType = value;
  63. reinitializeDrag = true;
  64. oldDragType = currentDragType;
  65. ApplyDragType();
  66. }
  67. }
  68. }
  69. private bool dragPointEnabled = true;
  70. public bool DragPointEnabled
  71. {
  72. get => dragPointEnabled;
  73. set
  74. {
  75. if (dragPointEnabled == value) return;
  76. dragPointEnabled = value;
  77. ApplyDragType();
  78. }
  79. }
  80. private bool gizmoEnabled = true;
  81. public bool GizmoEnabled
  82. {
  83. get => GizmoGo != null && gizmoEnabled;
  84. set
  85. {
  86. if (GizmoGo == null || (GizmoGo != null && gizmoEnabled == value)) return;
  87. gizmoEnabled = value;
  88. ApplyDragType();
  89. }
  90. }
  91. private void Awake()
  92. {
  93. this.BaseScale = transform.localScale;
  94. this.collider = GetComponent<Collider>();
  95. this.renderer = GetComponent<Renderer>();
  96. ApplyDragType();
  97. }
  98. public static T Make<T>(PrimitiveType primitiveType, Vector3 scale) where T : DragPoint
  99. {
  100. GameObject dragPointGo = GameObject.CreatePrimitive(primitiveType);
  101. dragPointGo.transform.SetParent(dragPointParent.transform, false);
  102. dragPointGo.transform.localScale = scale;
  103. dragPointGo.layer = 8;
  104. T dragPoint = dragPointGo.AddComponent<T>();
  105. dragPoint.renderer.material = dragPointMaterial;
  106. dragPoint.renderer.material.color = defaultColour;
  107. return dragPoint;
  108. }
  109. public virtual void Initialize(Func<Vector3> position, Func<Vector3> rotation)
  110. {
  111. this.position = position;
  112. this.rotation = rotation;
  113. }
  114. public virtual void Set(Transform myObject)
  115. {
  116. this.MyObject = myObject;
  117. this.gameObject.name = $"[MPS DragPoint: {this.MyObject.name}]";
  118. }
  119. public virtual void AddGizmo(float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
  120. {
  121. Gizmo = CustomGizmo.Make(this.MyObject, scale, mode);
  122. GizmoGo = Gizmo.gameObject;
  123. Gizmo.GizmoVisible = false;
  124. ApplyDragType();
  125. }
  126. protected virtual void ApplyDragType() { }
  127. public void ApplyProperties(bool active = false, bool visible = false, bool gizmo = false)
  128. {
  129. this.collider.enabled = active;
  130. this.renderer.enabled = visible;
  131. if (this.Gizmo != null) this.Gizmo.GizmoVisible = gizmo;
  132. }
  133. protected void ApplyColour(Color colour) => this.renderer.material.color = colour;
  134. protected void ApplyColour(float r, float g, float b, float a = defaultAlpha)
  135. {
  136. ApplyColour(new Color(r, g, b, a));
  137. }
  138. protected Vector3 MouseDelta() => Input.mousePosition - startMousePosition;
  139. protected bool OtherDragType()
  140. {
  141. return Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.D)
  142. || Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C);
  143. }
  144. protected Vector3 CursorPosition()
  145. {
  146. Vector3 mousePosition = Input.mousePosition;
  147. return camera.ScreenToWorldPoint(
  148. new Vector3(mousePosition.x, mousePosition.y, screenPoint.z)
  149. ) + startOffset - newOffset;
  150. }
  151. protected virtual void Update()
  152. {
  153. transform.position = position();
  154. transform.eulerAngles = rotation();
  155. UpdateDragType();
  156. }
  157. protected virtual void OnMouseDown()
  158. {
  159. screenPoint = camera.WorldToScreenPoint(transform.position);
  160. startMousePosition = Input.mousePosition;
  161. startOffset = transform.position - camera.ScreenToWorldPoint(
  162. new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z)
  163. );
  164. newOffset = transform.position - MyObject.position;
  165. }
  166. protected virtual void OnMouseDrag()
  167. {
  168. if (reinitializeDrag)
  169. {
  170. reinitializeDrag = false;
  171. OnMouseDown();
  172. }
  173. if (collider.enabled && Input.mousePosition != startMousePosition) Drag();
  174. }
  175. protected abstract void UpdateDragType();
  176. protected abstract void Drag();
  177. protected virtual void OnMouseUp()
  178. {
  179. if ((Time.time - startDoubleClick) < doubleClickSensitivity)
  180. {
  181. startDoubleClick = -1f;
  182. OnDoubleClick();
  183. }
  184. else
  185. {
  186. startDoubleClick = Time.time;
  187. }
  188. }
  189. protected virtual void OnDoubleClick() { }
  190. private void OnEnable()
  191. {
  192. if (position != null)
  193. {
  194. transform.position = position();
  195. transform.eulerAngles = rotation();
  196. }
  197. if (GizmoGo != null) GizmoGo.SetActive(true);
  198. ApplyDragType();
  199. }
  200. private void OnDisable()
  201. {
  202. if (GizmoGo != null) GizmoGo.SetActive(false);
  203. }
  204. protected virtual void OnDestroy() => GameObject.Destroy(GizmoGo);
  205. }
  206. }