using System; using UnityEngine; namespace COM3D2.MeidoPhotoStudio.Plugin { using static CustomGizmo; using Input = InputManager; public abstract class DragPointGeneral : DragPoint { public const float smallCube = 0.5f; private float currentScale; private bool scaling; private Quaternion currentRotation; public Quaternion DefaultRotation { get; set; } = Quaternion.identity; public Vector3 DefaultPosition { get; set; } = Vector3.zero; public Vector3 DefaultScale { get; set; } = Vector3.one; public float ScaleFactor { get; set; } = 1f; public bool ConstantScale { get; set; } public static readonly Color moveColour = new Color(0.2f, 0.5f, 0.95f, defaultAlpha); public static readonly Color rotateColour = new Color(0.2f, 0.75f, 0.3f, defaultAlpha); public static readonly Color scaleColour = new Color(0.8f, 0.7f, 0.3f, defaultAlpha); public static readonly Color selectColour = new Color(0.9f, 0.5f, 1f, defaultAlpha); public static readonly Color deleteColour = new Color(1f, 0.1f, 0.1f, defaultAlpha); public event EventHandler Move; public event EventHandler Rotate; public event EventHandler Scale; public event EventHandler EndScale; public event EventHandler Delete; public event EventHandler Select; public override void AddGizmo(float scale = 0.35f, GizmoMode mode = GizmoMode.Local) { base.AddGizmo(scale, mode); Gizmo.GizmoDrag += (s, a) => { if (Gizmo.CurrentGizmoType == GizmoType.Rotate) OnRotate(); }; } protected virtual void ApplyColours() { Color colour = moveColour; if (Rotating) colour = rotateColour; else if (Scaling) colour = scaleColour; else if (Selecting) colour = selectColour; else if (Deleting) colour = deleteColour; ApplyColour(colour); } protected override void Update() { base.Update(); if (ConstantScale) { float distance = Vector3.Distance(camera.transform.position, transform.position); transform.localScale = Vector3.one * (0.4f * BaseScale.x * DragPointScale * distance); } } protected override void UpdateDragType() { bool shift = Input.Shift; if (Input.GetKey(MpsKey.DragSelect)) { CurrentDragType = DragType.Select; } else if (Input.GetKey(MpsKey.DragDelete)) { CurrentDragType = DragType.Delete; } else if (Input.GetKey(MpsKey.DragMove)) { if (Input.Control) CurrentDragType = DragType.MoveY; else CurrentDragType = shift ? DragType.RotY : DragType.MoveXZ; } else if (Input.GetKey(MpsKey.DragRotate)) { CurrentDragType = shift ? DragType.RotLocalY : DragType.RotLocalXZ; } else if (Input.GetKey(MpsKey.DragScale)) { CurrentDragType = DragType.Scale; } else { CurrentDragType = DragType.None; } } protected override void OnMouseDown() { if (Deleting) { OnDelete(); return; } if (Selecting) { OnSelect(); return; } base.OnMouseDown(); currentScale = MyObject.localScale.x; currentRotation = MyObject.rotation; } protected override void OnDoubleClick() { if (Scaling) { MyObject.localScale = DefaultScale; OnScale(); OnEndScale(); } if (Rotating) { ResetRotation(); OnRotate(); } if (Moving) { ResetPosition(); OnMove(); } } protected virtual void ResetPosition() => MyObject.position = DefaultPosition; protected virtual void ResetRotation() => MyObject.rotation = DefaultRotation; protected override void OnMouseUp() { base.OnMouseUp(); if (scaling) { scaling = false; OnScale(); OnEndScale(); } } protected override void Drag() { if (CurrentDragType == DragType.Select || CurrentDragType == DragType.Delete) return; Vector3 cursorPosition = CursorPosition(); Vector3 mouseDelta = MouseDelta(); if (CurrentDragType == DragType.MoveXZ) { MyObject.position = new Vector3(cursorPosition.x, MyObject.position.y, cursorPosition.z); OnMove(); } if (CurrentDragType == DragType.MoveY) { MyObject.position = new Vector3( MyObject.position.x, cursorPosition.y, MyObject.position.z ); OnMove(); } if (CurrentDragType == DragType.RotY) { MyObject.rotation = currentRotation; MyObject.Rotate(Vector3.up, -mouseDelta.x / 3f, Space.World); OnRotate(); } if (CurrentDragType == DragType.RotLocalXZ) { MyObject.rotation = currentRotation; Vector3 forward = camera.transform.forward; Vector3 right = camera.transform.right; forward.y = 0f; right.y = 0f; MyObject.Rotate(forward, -mouseDelta.x / 6f, Space.World); MyObject.Rotate(right, mouseDelta.y / 4f, Space.World); OnRotate(); } if (CurrentDragType == DragType.RotLocalY) { MyObject.rotation = currentRotation; MyObject.Rotate(Vector3.up * -mouseDelta.x / 2.2f); OnRotate(); } if (CurrentDragType == DragType.Scale) { scaling = true; float scale = currentScale + (mouseDelta.y / 200f * ScaleFactor); if (scale < 0.1f) scale = 0.1f; MyObject.localScale = new Vector3(scale, scale, scale); OnScale(); } } protected virtual void OnEndScale() => OnEvent(EndScale); protected virtual void OnScale() => OnEvent(Scale); protected virtual void OnMove() => OnEvent(Move); protected virtual void OnRotate() => OnEvent(Rotate); protected virtual void OnSelect() => OnEvent(Select); protected virtual void OnDelete() => OnEvent(Delete); private void OnEvent(EventHandler handler) => handler?.Invoke(this, EventArgs.Empty); } }