摇杆脚本
using UnityEngine; using System; [ExecuteInEditMode] public class Joystick : MonoBehaviour { public enum JoystickAnchor { None, UpperLeft, UpperCenter, UpperRight, MiddleLeft, MiddleCenter, MiddleRight, LowerLeft, LowerCenter, LowerRight }; public JoystickAnchor joyAnchor = JoystickAnchor.LowerLeft; public int guiDepth = 0; public Texture2D areaTexture; public Texture2D touchTexture; public Rect areaRect; public Rect touchRect; public Vector2 offset; public GameObject eventReceiver; public string functionName = "OnJoystickChanged"; public event Action<Vector2> OnJoystickChanged; private Vector2 anchorPosition; private Vector2 joystickCenter; private Vector2 touchPosition; private Vector2 last_touchPosition; private float areaRadius, areaRadiusSqr, touchRadius, touchRadiusSqr; private bool joystickDraging; void OnEnable() { ComputeJoystickAnchor(joyAnchor); } void Update() { if (Input.GetMouseButtonDown(0)) { CheckTouchPosition(); } else if (Input.GetMouseButtonUp(0)) { ResetJoystick(); } if (joystickDraging) { UpdateJoystick(); } if (null != OnJoystickChanged && last_touchPosition != touchPosition) { last_touchPosition.Set(touchPosition.x, touchPosition.y); OnJoystickChanged(last_touchPosition); } if (null != eventReceiver && !string.IsNullOrEmpty(functionName) && last_touchPosition != touchPosition) { last_touchPosition.Set(touchPosition.x, touchPosition.y); eventReceiver.SendMessage(functionName, last_touchPosition, SendMessageOptions.DontRequireReceiver); } } void CheckTouchPosition() { UpdateTouchPosition(); if (touchPosition.sqrMagnitude <= areaRadiusSqr) joystickDraging = true; } void UpdateTouchPosition() { touchPosition.x = Input.mousePosition.x; touchPosition.y = Screen.height - Input.mousePosition.y; touchPosition -= joystickCenter; } void UpdateJoystick() { UpdateTouchPosition(); ComputeJoystickAnchor(joyAnchor); } void ResetJoystick() { joystickDraging = false; touchPosition = Vector2.zero; ComputeJoystickAnchor(joyAnchor); } void OnGUI() { GUI.depth = guiDepth; if (null != areaTexture) { GUI.DrawTexture(areaRect, areaTexture, ScaleMode.StretchToFill, true); } if (null != touchTexture) { GUI.DrawTexture(touchRect, touchTexture, ScaleMode.StretchToFill, true); } } void ComputeJoystickAnchor(JoystickAnchor anchor) { // Anchor position switch (anchor) { case JoystickAnchor.UpperLeft: anchorPosition = Vector2.zero; break; case JoystickAnchor.UpperCenter: anchorPosition = new Vector2((Screen.width - areaRect.width) / 2, 0); break; case JoystickAnchor.UpperRight: anchorPosition = new Vector2(Screen.width - areaRect.width, 0); break; case JoystickAnchor.MiddleLeft: anchorPosition = new Vector2(0, (Screen.height - areaRect.height) / 2); break; case JoystickAnchor.MiddleCenter: anchorPosition = new Vector2((Screen.width - areaRect.width) / 2, (Screen.height - areaRect.height)/2 ); break; case JoystickAnchor.MiddleRight: anchorPosition = new Vector2(Screen.width - areaRect.width, (Screen.height - areaRect.height) / 2); break; case JoystickAnchor.LowerLeft: anchorPosition = new Vector2(0, Screen.height - areaRect.height); break; case JoystickAnchor.LowerCenter: anchorPosition = new Vector2( (Screen.width - areaRect.width)/2, Screen.height - areaRect.height); break; case JoystickAnchor.LowerRight: anchorPosition = new Vector2(Screen.width - areaRect.width, Screen.height - areaRect.height); break; case JoystickAnchor.None: anchorPosition = Vector2.zero; break; } anchorPosition.x += offset.x; anchorPosition.y += offset.y; if (touchPosition.sqrMagnitude > touchRadiusSqr) { touchPosition.Normalize(); touchPosition *= touchRadius; } //joystick rect areaRadius = areaRect.width / 2; areaRadiusSqr = areaRadius * areaRadius; touchRadius = areaRadius - touchRect.width / 2; touchRadiusSqr = touchRadius * touchRadius; joystickCenter.x = anchorPosition.x + areaRect.width / 2; joystickCenter.y = anchorPosition.y + areaRect.height / 2; areaRect.x = anchorPosition.x; areaRect.y = anchorPosition.y; touchRect.x = joystickCenter.x - touchRect.width / 2 + touchPosition.x; touchRect.y = joystickCenter.y - touchRect.height / 2 + touchPosition.y; touchRect.x = Mathf.Clamp(touchRect.x, areaRect.x, areaRect.x + areaRect.width - touchRect.width); touchRect.y = Mathf.Clamp(touchRect.y, areaRect.y, areaRect.y + areaRect.height - touchRect.height); } }
工程结构
运行效果
附上Demo源文件(360云盘)
https://yunpan.cn/cx6Nyj3EJZjb6 访问密码 3712