wangguan
2020-12-29 452c75675679c44cc39b04bdb7d330d7c5c14d5c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
 
namespace MoreMountains.NiceVibrations
{
    [RequireComponent(typeof(Rect))]
    public class MMKnob : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
    {
        public RenderMode ParentCanvasRenderMode { get; protected set; }
 
        [Header("Bindings")]
        public Camera TargetCamera;
 
        [Header("Settings")]
        public float MinimumAngle = 45f;
        public float MaximumAngle = -225f;
        public float MaximumDistance = 50f;
        public Color ActiveColor;
        public Color InactiveColor;
 
        [Header("Output")]
        public bool Dragging = false;
        public float Value = 0f;
        public bool Active = true;
 
        public Image _image;
        protected PointerEventData _pointerEventData;
        protected float _distance;
        public RectTransform _rectTransform;
        protected Vector3 _rotation = Vector3.zero;
        protected Canvas _canvas;
        protected Vector2 _workPosition;
 
        protected virtual void Awake()
        {
            _image = this.gameObject.GetComponent<Image>();
            _canvas = GetComponentInParent<Canvas>();
            ParentCanvasRenderMode = GetComponentInParent<Canvas>().renderMode;
            _rectTransform = this.GetComponent<RectTransform>();
            SetRotation(MinimumAngle);
        }
 
        protected virtual void Update()
        {
            if (!Active)
            {
                Dragging = false;
                _image.color = InactiveColor;
                return;
            }
            else
            {
                _image.color = ActiveColor;
            }
 
            if (!Dragging)
            {
                return;
            }
 
            Vector2 v1 = Vector2.down;
            Vector2 v2 = this.transform.position - GetWorldPosition(_pointerEventData.position);
            
            float angle = Vector2.SignedAngle(v1, v2);
 
            angle = Mathf.Clamp(angle, -130f, 130f);
 
            _rotation.z = NiceVibrationsDemoHelpers.Remap(angle, -130f, 130f, MaximumAngle, MinimumAngle);
            _rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
 
            Value = NiceVibrationsDemoHelpers.Remap(angle, -130f, 130f, 1f, 0f);
        }
 
        protected virtual void SetRotation(float angle)
        {
            angle = Mathf.Clamp(angle, MaximumAngle, MinimumAngle);
            _rotation.z = angle;
            _rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
        }
 
        public virtual void SetActive(bool status)
        {
            Active = status;
        }
 
        public virtual void SetValue(float value)
        {
            SetRotation(MinimumAngle);
            Value = value;
            float angle = NiceVibrationsDemoHelpers.Remap(value, 0f, 1f, MinimumAngle, MaximumAngle);
 
            _rotation.z = angle;
            _rectTransform.SetPositionAndRotation(this.transform.position, Quaternion.Euler(_rotation));
        }
 
        public void OnPointerDown(PointerEventData eventData)
        {
            _pointerEventData = eventData;
            Dragging = true;
        }
 
        public void OnPointerUp(PointerEventData eventData)
        {
            _pointerEventData = null;
            Dragging = false;
        }
        protected virtual Vector3 GetWorldPosition(Vector3 testPosition)
        {
            if (ParentCanvasRenderMode == RenderMode.ScreenSpaceCamera)
            {
                RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvas.transform as RectTransform, testPosition, _canvas.worldCamera, out _workPosition);
                return _canvas.transform.TransformPoint(_workPosition);
            }
            else
            {
                return testPosition;
            }
        }
    }
}