Unity3D 官方Joystick改为C#版本

using UnityEngine;
using System.Collections;

public class JoystickC : MonoBehaviour {
    
    private Vector2 min = Vector2.zero;
    private Vector2 max = Vector2.zero;

    static private JoystickC[] joysticks;                    // A static collection of all joysticks
    static private bool enumeratedJoysticks = false;
    static private float tapTimeDelta = 0.3f;                // Time allowed between taps
    
    public bool touchPad;                                     // Is this a TouchPad?
    public Rect touchZone;
    public float deadZone = 0;                                    // Control when position is output
    public bool normalize = false;                             // Normalize output after the dead-zone?
    public Vector2 position;                                     // [-1, 1] in x,y
    public int tapCount;                                            // Current tap count
    
    
    private int lastFingerId = -1;                                // Finger last used for this joystick
    private float tapTimeWindow;                            // How much time there is left for a tap to occur
    private Vector2 fingerDownPos;
    private float fingerDownTime;
    private float firstDeltaTime = 0.5f;
    
    private GUITexture gui;                                // Joystick graphic
    private Rect defaultRect;                                // Default position / extents of the joystick graphic
                // Boundary for joystick graphic
    private Vector2 guiTouchOffset;                        // Offset to apply to touch input
    private Vector2 guiCenter;                            // Center of joystick
    
    
    void Awake ()
    {
        //gameObject.SetActive(false);
    }
    
    // Use this for initialization
    void Start () {
            // Cache this component at startup instead of looking up every frame
        gui = GetComponent<GUITexture> ();

        // Store the default rect for the gui, so we can snap back to it
        defaultRect = gui.pixelInset;

        defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;
        defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;

        transform.position = new Vector3(0, 0, transform.position.z);

        if (touchPad) {
        // If a texture has been assigned, then use the rect ferom the gui as our touchZone
            if (gui.texture)
                touchZone = defaultRect;
        }
        else {
            // This is an offset for touch input to match with the top left
            // corner of the GUI
            guiTouchOffset.x = defaultRect.width * 0.5F;
            guiTouchOffset.y = defaultRect.height * 0.5F;

        // Cache the center of the GUI, since it doesn't change
            guiCenter.x = defaultRect.x + guiTouchOffset.x;
            guiCenter.y = defaultRect.y + guiTouchOffset.y;

            // Let's build the GUI boundary, so we can clamp joystick movement
            min.x = defaultRect.x - guiTouchOffset.x;
            max.x = defaultRect.x + guiTouchOffset.x;
            min.y = defaultRect.y - guiTouchOffset.y;
            max.y = defaultRect.y + guiTouchOffset.y;
        }
    }
    
    void Disable () {
        gameObject.SetActive (false);
        enumeratedJoysticks = false;
    }
    
    void ResetJoystick () {
        // Release the finger control and set the joystick back to the default position
        gui.pixelInset = defaultRect;
        lastFingerId = -1;
        position = Vector2.zero;
        fingerDownPos = Vector2.zero;

        if (touchPad){
            Color c = gui.color;
            c.a = 0.025f;
            gui.color = c;
        }
    }
    
    bool IsFingerDown () {
        return (lastFingerId != -1);
    }
    
    void LatchedFinger (int fingerId) {
        // If another joystick has latched this finger, then we must release it
        if (lastFingerId == fingerId)
            ResetJoystick ();
}

    void Update () {
        if (!enumeratedJoysticks) {
        // Collect all joysticks in the game, so we can relay finger latching messages
            joysticks = FindObjectsOfType (typeof(JoystickC)) as JoystickC[];
            enumeratedJoysticks = true;
        }

        int count = Input.touchCount;

    // Adjust the tap time window while it still available
        if (tapTimeWindow > 0)
            tapTimeWindow -= Time.deltaTime;
        else
            tapCount = 0;

        if (count == 0) {
            ResetJoystick ();
        }
        else {
            for (int i = 0; i < count; i++) {
                Touch touch = Input.GetTouch (i);
                Vector2 guiTouchPos = touch.position - guiTouchOffset;

                bool shouldLatchFinger = false;
                if (touchPad) {
                    if (touchZone.Contains (touch.position))
                        shouldLatchFinger = true;
                }
                else if (gui.HitTest (touch.position)) {
                    shouldLatchFinger = true;
                }

            // Latch the finger if this is a new touch
            if (shouldLatchFinger && (lastFingerId == -1 || lastFingerId != touch.fingerId)) {

                if (touchPad) {
                        Color c = gui.color;
                        c.a = 0.15f;
                        gui.color = c;

                        lastFingerId = touch.fingerId;
                        fingerDownPos = touch.position;
                        fingerDownTime = Time.time;
                    }

                    lastFingerId = touch.fingerId;

                // Accumulate taps if it is within the time window
                    if (tapTimeWindow > 0) {
                        tapCount++;
                    }
                    else {
                        tapCount = 1;
                        tapTimeWindow = tapTimeDelta;
                    }

                // Tell other joysticks we've latched this finger
                foreach (JoystickC j in joysticks) {
                    if (j != null && j != this)
                        {
                            j.LatchedFinger (touch.fingerId);
                        }
                }
            }

            if (lastFingerId == touch.fingerId) {
                // Override the tap count with what the iPhone SDK reports if it is greater
                // This is a workaround, since the iPhone SDK does not currently track taps
                // for multiple touches
                if (touch.tapCount > tapCount)
                    tapCount = touch.tapCount;

                if (touchPad) {
                    // For a touchpad, let's just set the position directly based on distance from initial touchdown
                    position.x = Mathf.Clamp ((touch.position.x - fingerDownPos.x) / (touchZone.width / 2), -1, 1);
                    position.y = Mathf.Clamp ((touch.position.y - fingerDownPos.y) / (touchZone.height / 2), -1, 1);
                }
                else {
                    // Change the location of the joystick graphic to match where the touch is
                    position.x = (touch.position.x - guiCenter.x) / guiTouchOffset.x;
                    position.y = (touch.position.y - guiCenter.y) / guiTouchOffset.y;
                }

                if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
                    ResetJoystick ();
            }
        }
    }

    // Calculate the length. This involves a squareroot operation,
    // so it's slightly expensive. We re-use this length for multiple
    // things below to avoid doing the square-root more than one.
    float length = position.magnitude;


    if (length < deadZone) {
        // If the length of the vector is smaller than the deadZone radius,
        // set the position to the origin.
        position = Vector2.zero;
    }
    else {
        if (length > 1) {
            // Normalize the vector if its length was greater than 1.
            // Use the already calculated length instead of using Normalize().
            position = position / length;
        }
        else if (normalize) {
            // Normalize the vector and multiply it with the length adjusted
            // to compensate for the deadZone radius.
            // This prevents the position from snapping from zero to the deadZone radius.
            position = position / length * Mathf.InverseLerp (length, deadZone, 1);
        }
    }

    if (!touchPad) {
        // Change the location of the joystick graphic to match the position
        float xx = (position.x - 1) * guiTouchOffset.x + guiCenter.x;
        float yy = (position.y - 1) * guiTouchOffset.y + guiCenter.y;
        gui.pixelInset = new Rect(xx, yy, gui.pixelInset.width, gui.pixelInset.height);
    }
}

}
原文地址:https://www.cnblogs.com/vital/p/3564962.html