用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腳本綁定到該物體上 接下來就成功了!
下面是搖桿素材
大功告成!