DragPoint.cs 6.6 KB

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