本文实例为大家分享了Unity实现虚拟摇杆的具体代码,供大家参考,具体内容如下
面板上设置一些属性,比如摇杆拖拽的距离,是否始终可视,是否限制虚拟摇杆位置(我是把虚拟摇杆限制在了屏幕的左下区域)。
使用GetDirAndLength()方法去获得移动的方向和长度即可
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
using UnityEngine; /// <summary> /// 虚拟摇杆管理器 /// </summary> public class VirtualJoystickManager : MonoBehaviour { private static VirtualJoystickManager _instance; public static VirtualJoystickManager Instance { get { if (_instance == null ) { _instance = FindObjectOfType<VirtualJoystickManager>(); } return _instance; } } [Header( "是否始终可视" )] public bool alwaysVisible; //是否始终可视 [Header( "是否限制虚拟摇杆位置" )] public bool restrictVirtualJoystickPos; //是否限制虚拟摇杆位置 [Header( "虚拟摇杆物体" )] [Header( "==========" )] public GameObject virtualJoystick; //虚拟摇杆父物体 public GameObject inside; //内环 public GameObject outside; //外环 [Header( "最大拖拽距离" )] [Header( "==========" )] public float maxDragLength; //最大拖拽距离 private Vector3 virtualJoystickCenter; //虚拟轴中心 private void Update() { //如果限制虚拟轴位置并且虚拟轴位置超出了限制范围则不进行任何操作 if (restrictVirtualJoystickPos && JudgeIsValidRange() == false ) { return ; } //更新显示 UpdateShow(); //更新虚拟摇杆位置 if (Input.GetMouseButtonDown(0)) { UpdateVirtualJoystickPos(); } else if (Input.GetMouseButtonUp(0)) { inside.transform.position = virtualJoystickCenter; } //更新内环位置(限制拖拽范围) if (Input.GetMouseButton(0)) { UpdateInsidePos(); } } /// <summary> /// 更新显示 /// </summary> private void UpdateShow() { if (alwaysVisible) { inside.SetActive( true ); outside.SetActive( true ); } else if (alwaysVisible == false ) { if (Input.GetMouseButtonDown(0)) { inside.SetActive( true ); outside.SetActive( true ); } if (Input.GetMouseButtonUp(0)) { inside.SetActive( false ); outside.SetActive( false ); } } } /// <summary> /// 更新虚拟摇杆位置 /// </summary> private void UpdateVirtualJoystickPos() { //得到虚拟轴的中心位置 virtualJoystickCenter = ScreenToWorld(Input.mousePosition); //设置虚拟轴的位置 virtualJoystick.transform.position = virtualJoystickCenter; } /// <summary> /// 更新内环位置 /// </summary> private void UpdateInsidePos() { inside.transform.position = ScreenToWorld(Input.mousePosition); if (Vector3.Distance(inside.transform.position, virtualJoystickCenter) > maxDragLength) { Vector3 normalizedPos = (inside.transform.position - virtualJoystickCenter).normalized; inside.transform.position = normalizedPos * maxDragLength + virtualJoystickCenter; } } /// <summary> /// 判断是否为有效的范围 /// </summary> /// <returns>是否为有效的范围</returns> private bool JudgeIsValidRange() { if (inside.activeInHierarchy) { return true ; } Vector2 v = Input.mousePosition; if (v.x > Screen.width / 2 || v.x < 0) { return false ; } else if (v.y > Screen.height / 2 || v.y < 0) { return false ; } return true ; } /// <summary> /// 屏幕坐标转世界坐标 /// </summary> /// <param name="screenPos">屏幕坐标位置</param> /// <param name="camera">相机</param> /// <returns>转换后的世界坐标</returns> public static Vector3 ScreenToWorld(Vector3 screenPos, Camera camera = null ) { if (camera == null ) { camera = Camera.main; } Vector3 _screenPos = new Vector3(screenPos.x, screenPos.y, -camera.transform.position.z); Vector3 v = camera.ScreenToWorldPoint(_screenPos); return v; } /// <summary> /// 得到运动的方向和长度 /// </summary> /// <returns>方向和长度</returns> public Vector3 GetDirAndLength() { return inside.transform.position - virtualJoystickCenter; } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/LLLLL__/article/details/105485460