using System; using UnityEngine; namespace COM3D2.MeidoPhotoStudio.Plugin { using static CustomGizmo; // TODO: Finalize dragpopint scaling public abstract class BaseDrag : MonoBehaviour { private const float doubleClickSensitivity = 0.3f; protected const int upperArm = 0; protected const int foreArm = 1; protected const int hand = 2; protected const int upperArmRot = 0; protected const int handRot = 1; private GameObject gizmoGo; protected Maid maid; protected Meido meido; protected Func position; protected Func rotation; protected Renderer dragPointRenderer; protected Collider dragPointCollider; protected Vector3 worldPoint; protected Vector3 mousePos; private DragType dragType = DragType.None; protected DragType CurrentDragType { get => dragType; set { dragType = value; reInitDrag = dragType != dragTypeOld; dragTypeOld = dragType; } } protected DragType dragTypeOld; protected float doubleClickStart = 0f; protected bool reInitDrag = false; protected bool isPlaying; protected CustomGizmo gizmo; protected GizmoType CurrentGizmoType { get => gizmo?.CurrentGizmoType ?? GizmoType.None; set { if (gizmo != null) { if (GizmoActive) gizmo.CurrentGizmoType = value; } } } public Vector3 BaseScale { get; private set; } public Vector3 DragPointScale { get => transform.localScale; set { transform.localScale = value; } } public bool IsBone { get; set; } public bool GizmoVisible { get => gizmo?.Visible ?? false; set { if (gizmo != null) gizmo.Visible = value; } } private bool gizmoActive = false; public bool GizmoActive { get => gizmoActive; set { if (gizmoGo != null) { gizmoActive = value; gizmoGo.SetActive(gizmoActive); GizmoVisible = gizmoActive; } } } private bool dragPointVisible; public bool DragPointVisible { get => dragPointVisible; set { dragPointVisible = value; dragPointRenderer.enabled = dragPointVisible; } } private bool dragPointActive; public bool DragPointActive { get => dragPointActive; set { dragPointActive = value; dragPointCollider.enabled = dragPointActive; } } public event EventHandler DragEvent; protected enum DragType { None, Select, MoveXZ, MoveY, RotLocalXZ, RotY, RotLocalY, Scale } public static Material LightBlue = new Material(Shader.Find("Transparent/Diffuse")) { color = new Color(0.4f, 0.4f, 1f, 0.3f) }; public static Material Blue = new Material(Shader.Find("Transparent/Diffuse")) { color = new Color(0.5f, 0.5f, 1f, 0.8f) }; public static GameObject MakeDragPoint(PrimitiveType primitiveType, Vector3 scale, Material material) { GameObject dragPoint = GameObject.CreatePrimitive(primitiveType); dragPoint.transform.localScale = scale; dragPoint.GetComponent().material = material; dragPoint.layer = 8; return dragPoint; } public BaseDrag Initialize(Meido meido, Func position, Func rotation) { this.InitializeDragPoint(position, rotation); this.meido = meido; this.maid = meido.Maid; isPlaying = !meido.IsStop; return this; } protected void InitializeDragPoint(Func position, Func rotation) { this.BaseScale = transform.localScale; this.position = position; this.rotation = rotation; this.dragPointRenderer = GetComponent(); this.dragPointCollider = GetComponent(); this.DragPointVisible = true; } protected void InitializeGizmo(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local) { gizmoGo = CustomGizmo.MakeGizmo(target, scale, mode); gizmo = gizmoGo.GetComponent(); if (meido != null) { gizmo.GizmoDrag += (s, a) => { meido.IsStop = true; isPlaying = false; }; } GizmoActive = false; GizmoVisible = false; } public void SetDragProp(bool gizmoActive, bool dragPointActive, bool dragPointVisible) { this.GizmoActive = gizmoActive; this.DragPointActive = dragPointActive; this.DragPointVisible = dragPointVisible; } protected virtual void InitializeDrag() { worldPoint = Camera.main.WorldToScreenPoint(transform.position); mousePos = Input.mousePosition; isPlaying = !meido?.IsStop ?? false; } protected virtual void DoubleClick() { } protected abstract void Drag(); protected abstract void GetDragType(); protected virtual void OnMouseUp() { if ((Time.time - doubleClickStart) < doubleClickSensitivity) { doubleClickStart = -1; DoubleClick(); } else { doubleClickStart = Time.time; } } protected virtual void Update() { GetDragType(); transform.position = position(); transform.eulerAngles = rotation(); } protected virtual void OnMouseDown() { InitializeDrag(); } protected virtual void OnMouseDrag() { if (CurrentDragType == DragType.Select) return; if (reInitDrag) { reInitDrag = false; InitializeDrag(); } if (mousePos != Input.mousePosition) Drag(); } private void OnEnable() { if (position != null) { transform.position = position(); transform.eulerAngles = rotation(); } } private void OnDestroy() { GameObject.Destroy(gizmo); } protected void OnDragEvent() { DragEvent?.Invoke(null, EventArgs.Empty); } } }