using UnityEngine; using System.Collections; [ExecuteInEditMode] public class Joystick : MonoBehaviour { public bool Relative = false; public float BaseJoystickRadius; public float StickRadius; public Texture2D circleImage; private Rect baseRect; private Rect stickRect; private Vector2 basePosition; private bool pressed = false; private Vector2 pressPosition; private Vector2 stickOffset; private Vector2 stickPosition; public Material Mat; public Color BaseColor; public Color StickColor; private int fingerId = -1; private float angle; public ScreenSpacePosition ScreenPosition; // Use this for initialization void Start () { } public float Angle{ get{ return angle; } } public bool Pressed{ get{ return pressed; } } public float Value{ get{ return pressed ? Mathf.Clamp01(stickOffset.magnitude / BaseJoystickRadius) : 0; } } public float ValueX{ get{ return pressed ? Mathf.Clamp((stickPosition.x - basePosition.x) / BaseJoystickRadius, -1, 1) : 0; } } public float ValueY{ get{ return pressed ? Mathf.Clamp((stickPosition.y - basePosition.y) / BaseJoystickRadius, -1, 1) : 0; } } public Vector2 Direction{ get{ return pressed ? stickOffset.normalized : Vector2.zero; } } bool InsideDefaultStick(Vector2 position){ Vector2 diff = position - basePosition; return diff.magnitude <= StickRadius; } bool GetPressPosition(ref Vector2 position){ #if !UNITY_WP8 || UNITY_EDITOR if (Input.GetKeyDown (KeyCode.Mouse0)) { position = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y); return InsideDefaultStick(position); } return false; #else for (var i = 0; i < Input.touchCount; ++i) { var tap = Input.GetTouch(i); if(tap.phase == TouchPhase.Began){ position = new Vector2(tap.position.x, Screen.height - tap.position.y); if(InsideDefaultStick(position)){ fingerId = tap.fingerId; return true; } } } return false; #endif } bool FindTouch(int finger, ref Touch t){ foreach (var touch in Input.touches) { if(touch.fingerId == finger){ t = touch; return true; } } return false; } bool Released(){ #if !UNITY_WP8 || UNITY_EDITOR return Input.GetKeyUp (KeyCode.Mouse0); #else Touch t = new Touch(); if(!FindTouch(fingerId, ref t)){ return true; } return (t.phase == TouchPhase.Ended) || (t.phase == TouchPhase.Canceled); #endif } Vector2 GetMovePosition(){ #if !UNITY_WP8 || UNITY_EDITOR return new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y); #else Touch t = new Touch(); FindTouch(fingerId, ref t); return new Vector2(t.position.x, Screen.height - t.position.y); #endif } // Update is called once per frame void Update () { basePosition = ScreenPosition.PixelPosition; stickPosition = basePosition; baseRect = new Rect ( basePosition.x - BaseJoystickRadius, basePosition.y - BaseJoystickRadius, BaseJoystickRadius * 2.0f, BaseJoystickRadius * 2.0f); if (!pressed) { if (GetPressPosition(ref pressPosition)) { pressed = true; } } else { if (Released()) { pressed = false; stickOffset = Vector2.zero; angle = 0; }else{ Vector2 touchPosition = GetMovePosition(); stickOffset = touchPosition - pressPosition; if (stickOffset.magnitude > BaseJoystickRadius) { stickPosition = basePosition + stickOffset.normalized * BaseJoystickRadius; } else { stickPosition = basePosition + stickOffset; } Vector2 joyDir = Direction; angle = Mathf.Atan2(joyDir.x, joyDir.y); angle = (Mathf.PI - Mathf.Abs(angle)) * Mathf.Sign(angle); } } stickRect = new Rect ( stickPosition.x - StickRadius, stickPosition.y - StickRadius, StickRadius * 2.0f, StickRadius * 2.0f); } void OnGUI(){ //GUI.DrawTexture (stickRect, circleImage); if (Event.current.type == EventType.Repaint) { Mat.SetColor("_TintColor", BaseColor); Graphics.DrawTexture (baseRect, circleImage, Mat); Mat.SetColor("_TintColor", StickColor); Graphics.DrawTexture (stickRect, circleImage, Mat); } GUI.Label(new Rect ( baseRect.x, baseRect.y - 40, baseRect.width , 20), (ValueY).ToString("##.###")); } }