UGUI實現虛擬手柄功能

用Uniyt自帶的UGUI實現虛擬搖桿功能,使用搖桿控制物體移動

首先新建一個unity工程,建一個畫布,兩張Image 父子關係,像這樣:


建好之後把準備好的素材拉上去,素材在最後上傳,效果圖如下:


然後新建兩個C#腳本


JoyStick:控制虛擬手柄的拖動腳本

JoyStick3D:控制物體移動腳本

代碼如下:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;
/// 
/// 搖桿的控制 需要UGUI的兩個Image父子關係子節點作爲控制父節點作爲顯示
/// 
public class JoyStick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
    /// 
    /// 搖桿最大半徑
    /// 以像素爲單位
    /// 
    public float JoyStickRadius = 50;
    /// 
    /// 搖桿重置所訴
    /// 
    public float JoyStickResetSpeed = 5.0f;
    /// 
    /// 當前物體的Transform組件
    /// 
    private RectTransform selfTransform;
    /// 
    /// 是否觸摸了虛擬搖桿
    /// 
    private bool isTouched = false;
    /// 
    /// 虛擬搖桿的默認位置
    /// 
    private Vector2 originPosition;
    /// 
    /// 虛擬搖桿的移動方向
    /// 
    private Vector2 touchedAxis;
    public Vector2 TouchedAxis
    {
        get
        {
            if (touchedAxis.magnitude < JoyStickRadius)
                return touchedAxis.normalized / JoyStickRadius;
            return touchedAxis.normalized;
        }
    }
    /// 
    /// 定義觸摸開始事件委託
    /// 
    public delegate void JoyStickTouchBegin(Vector2 vec);
    /// 
    /// 定義觸摸過程事件委託
    /// 
    /// 虛擬搖桿的移動方向
    public delegate void JoyStickTouchMove(Vector2 vec);
    /// 
    /// 定義觸摸結束事件委託
    /// 
    public delegate void JoyStickTouchEnd();
    /// 
    /// 註冊觸摸開始事件
    /// 
    public event JoyStickTouchBegin OnJoyStickTouchBegin;
    /// 
    /// 註冊觸摸過程事件
    /// 
    public event JoyStickTouchMove OnJoyStickTouchMove;
    /// 
    /// 註冊觸摸結束事件
    /// 
    public event JoyStickTouchEnd OnJoyStickTouchEnd;
    void Start()
    {
        //初始化虛擬搖桿的默認方向
        selfTransform = this.GetComponent();
        originPosition = selfTransform.anchoredPosition;
    }
    public void OnPointerDown(PointerEventData eventData)
    {
        isTouched = true;
        touchedAxis = GetJoyStickAxis(eventData);
        if (this.OnJoyStickTouchBegin != null)
            this.OnJoyStickTouchBegin(TouchedAxis);
    }
    public void OnPointerUp(PointerEventData eventData)
    {
        isTouched = false;
        selfTransform.anchoredPosition = originPosition;
        touchedAxis = Vector2.zero;
        if (this.OnJoyStickTouchEnd != null)
            this.OnJoyStickTouchEnd();
    }
    public void OnDrag(PointerEventData eventData)
    {
        touchedAxis = GetJoyStickAxis(eventData);
        if (this.OnJoyStickTouchMove != null)
            this.OnJoyStickTouchMove(TouchedAxis);
    }
    void Update()
    {
        //當虛擬搖桿移動到最大半徑時搖桿無法拖動
        //爲了確保被控制物體可以繼續移動
        //在這裏手動觸發OnJoyStickTouchMove事件
        if (isTouched && touchedAxis.magnitude >= JoyStickRadius)
        {
            if (this.OnJoyStickTouchMove != null)
                this.OnJoyStickTouchMove(TouchedAxis);
        }
        //鬆開虛擬搖桿後讓虛擬搖桿回到默認位置
        if (selfTransform.anchoredPosition.magnitude > originPosition.magnitude)
            selfTransform.anchoredPosition -= TouchedAxis * Time.deltaTime * JoyStickResetSpeed;
    }
    /// 
    /// 返回虛擬搖桿的偏移量
    /// 
    /// The joy stick axis.
    /// Event data.
    private Vector2 GetJoyStickAxis(PointerEventData eventData)
    {
        //獲取手指位置的世界座標
        Vector3 worldPosition;
        if (RectTransformUtility.ScreenPointToWorldPointInRectangle(selfTransform,
                 eventData.position, eventData.pressEventCamera, out worldPosition))
            selfTransform.position = worldPosition;
        //獲取搖桿的偏移量
        Vector2 touchAxis = selfTransform.anchoredPosition - originPosition;
        //搖桿偏移量限制
        if (touchAxis.magnitude >= JoyStickRadius)
        {
            touchAxis = touchAxis.normalized * JoyStickRadius;
            selfTransform.anchoredPosition = touchAxis;
        }
        return touchAxis;
    }
}using UnityEngine;
using System.Collections;
/// 
/// 搖桿需要控制的物體腳本 綁定到需要控制的物體上
/// 
public class JoyStick3D : MonoBehaviour
{
    private JoyStick js;
    void Start()
    {
        js = GameObject.FindObjectOfType();
        js.OnJoyStickTouchBegin += OnJoyStickBegin;
        js.OnJoyStickTouchMove += OnJoyStickMove;
        js.OnJoyStickTouchEnd += OnJoyStickEnd;
    }
    void OnJoyStickBegin(Vector2 vec)
    {
        Debug.Log("開始觸摸虛擬搖桿");
    }
    void OnJoyStickMove(Vector2 vec)
    {
        Debug.Log("正在移動虛擬搖桿");
        //設置角色朝向
        Quaternion q = Quaternion.LookRotation(new Vector3(vec.x, 0, vec.y));
        transform.rotation = q;
        //移動角色並播放奔跑動畫
        transform.Translate(Vector3.forward * 5f * Time.deltaTime);
       // animation.CrossFade("Run");
    }
    void OnJoyStickEnd()
    {
        Debug.Log("觸摸移動搖桿結束");
        //播放默認待機動畫
        //animation.CrossFade("idle");
    }
    void OnGUI()
    {
        GUI.Label(new Rect(30, 30, 200, 30), "3D模式下的虛擬搖桿測試");
    }
}

將JoyStick腳本綁定到子節點上

建一個方塊 將JoyStick3D腳本綁定到該物體上 接下來就成功了!

下面是搖桿素材


大功告成!

發佈了22 篇原創文章 · 獲贊 24 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章