Unity UGUI通過(guò)搖桿控制角色移動(dòng)
本文實(shí)例為大家分享了Unity UGUI通過(guò)搖桿控制角色移動(dòng)的具體代碼,供大家參考,具體內(nèi)容如下
簡(jiǎn)單版:控制方塊的移動(dòng)。

進(jìn)階版:控制人物的移動(dòng)

知識(shí)鋪墊:
首先我們必須要知道,在Unity的UGUI中,對(duì)UI的操作有八個(gè)回調(diào),分別需要實(shí)現(xiàn)八個(gè)接口。分別是:
鼠標(biāo)進(jìn)入,鼠標(biāo)離開,鼠標(biāo)點(diǎn)下,鼠標(biāo)抬起,鼠標(biāo)開始拖拽,鼠標(biāo)拖拽中,拖拽結(jié)束
如下所示:

我們可以先對(duì)這幾個(gè)接口方法進(jìn)行一下測(cè)試:
測(cè)試結(jié)束后,大家就會(huì)對(duì)這些接口方法有一些初步的了解。
using UnityEngine;
using UnityEngine.EventSystems;
// UGUI提供了一些用來(lái)操作控件的一些方法, 這些方法是以回調(diào)的形式提供的
// 通過(guò)接口回調(diào)來(lái)實(shí)現(xiàn)的
/*
* IPointerEnterHandler void OnPointerEnter(PointerEventData eventData)
* IPointerExitHandler void OnPointerExit(PointerEventData eventData)
*
* IPointerDownHandler void OnPointerDown(PointerEventData eventData)
* IPointerUpHandler void OnPointerUp(PointerEventData eventData)
* IPointerClickHandler void OnPointerClick(PointerEventData eventData)
*
* IBeginDragHandler void OnBeginDrag(PointerEventData eventData)
* IDragHandler void OnDrag(PointerEventData eventData)
* IEndDragHandler void OnEndDrag(PointerEventData eventData)
*/
public class UGUICallBack : MonoBehaviour,
IPointerEnterHandler, IPointerExitHandler,
IPointerDownHandler, IPointerUpHandler, IPointerClickHandler,
IBeginDragHandler, IDragHandler, IEndDragHandler
{
/// <summary>
/// 當(dāng)鼠標(biāo)滑入控件的范圍
/// </summary>
/// <param name="eventData"></param>
public void OnPointerEnter(PointerEventData eventData) {
Debug.Log("鼠標(biāo)劃入");
}
/// <summary>
/// 當(dāng)鼠標(biāo)離開控件的范圍
/// </summary>
/// <param name="eventData"></param>
public void OnPointerExit(PointerEventData eventData) {
Debug.Log("鼠標(biāo)離開");
}
/// <summary>
/// 當(dāng)鼠標(biāo)在控件范圍內(nèi)按下
/// </summary>
/// <param name="eventData"></param>
public void OnPointerDown(PointerEventData eventData) {
Debug.Log("鼠標(biāo)按下");
}
/// <summary>
/// 當(dāng)鼠標(biāo)在控件范圍內(nèi)抬起
/// </summary>
/// <param name="eventData"></param>
public void OnPointerUp(PointerEventData eventData) {
Debug.Log("鼠標(biāo)抬起");
}
/// <summary>
/// 當(dāng)鼠標(biāo)在控件范圍內(nèi)點(diǎn)擊
/// </summary>
/// <param name="eventData"></param>
public void OnPointerClick(PointerEventData eventData) {
Debug.Log("鼠標(biāo)點(diǎn)擊");
}
/// <summary>
/// 當(dāng)鼠標(biāo)開始拖拽
/// </summary>
/// <param name="eventData"></param>
public void OnBeginDrag(PointerEventData eventData) {
Debug.Log("開始拖拽");
}
/// <summary>
/// 當(dāng)鼠標(biāo)拖拽過(guò)程中
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData) {
Debug.Log("拖拽中");
}
/// <summary>
/// 當(dāng)拖拽完成
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData) {
Debug.Log("拖拽完成");
}
}
下面開始講解案例:
第一步:實(shí)現(xiàn)對(duì)遙感按鈕的操作, 從上面的八大接口方法可以了解到,如果想實(shí)現(xiàn)遙感的方法我們需要實(shí)現(xiàn)有關(guān)拖拽的回調(diào):UI過(guò)拽中, UI拖拽結(jié)束


對(duì)遙感的操作代碼如下(非移動(dòng)完整版,下面有移動(dòng)完整版EasyTouchMove):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class EasyTouchMove : MonoBehaviour, IDragHandler,IEndDragHandler{
//圖標(biāo)移動(dòng)最大半徑
public float maxRadius = 100;
//初始化背景圖標(biāo)位置
private Vector2 moveBackPos;
// Use this for initialization
void Start () {
//初始化背景圖標(biāo)位置
moveBackPos = transform.parent.transform.position;
}
/// <summary>
/// 當(dāng)鼠標(biāo)開始拖拽時(shí)
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData) {
//獲取鼠標(biāo)位置與初始位置之間的向量
Vector2 oppsitionVec = eventData.position - moveBackPos;
//獲取向量的長(zhǎng)度
float distance = Vector3.Magnitude(oppsitionVec);
//最小值與最大值之間取半徑
float radius = Mathf.Clamp(distance, 0, maxRadius);
//限制半徑長(zhǎng)度
transform.position = moveBackPos + oppsitionVec.normalized * radius;
}
/// <summary>
/// 當(dāng)鼠標(biāo)停止拖拽時(shí)
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData) {
transform.position = moveBackPos;
}
}
如何控制木塊的移動(dòng)呢:
初學(xué)者一般在學(xué)習(xí)Unity的時(shí)候都是WSAD控制移動(dòng)的,遙感控制移動(dòng)只需要更改一個(gè)很小的地方即可:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Cube : MonoBehaviour {
public EasyTouchMove touch;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
//獲取horizontal 和 vertical 的值,其值位遙感的localPosition
float hor = touch.Horizontal;
float ver = touch.Vertical;
Vector3 direction = new Vector3(hor, 0, ver);
if(direction!= Vector3.zero) {
//控制轉(zhuǎn)向
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(direction),Time.deltaTime*10);
//向前移動(dòng)
transform.Translate(Vector3.forward * Time.deltaTime * 5);
}
}
}
木塊版本遙感操作代碼:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class EasyTouchMove : MonoBehaviour, IDragHandler,IEndDragHandler{
//圖標(biāo)移動(dòng)最大半徑
public float maxRadius = 100;
//初始化背景圖標(biāo)位置
private Vector2 moveBackPos;
//hor,ver的屬性訪問(wèn)器
private float horizontal=0;
private float vertical=0;
public float Horizontal {
get { return horizontal; }
}
public float Vertical {
get { return vertical; }
}
// Use this for initialization
void Start () {
//初始化背景圖標(biāo)位置
moveBackPos = transform.parent.transform.position;
}
// Update is called once per frame
void Update () {
horizontal = transform.localPosition.x;
vertical = transform.localPosition.y;
}
/// <summary>
/// 當(dāng)鼠標(biāo)開始拖拽時(shí)
/// </summary>
/// <param name="eventData"></param>
public void OnDrag(PointerEventData eventData) {
//獲取鼠標(biāo)位置與初始位置之間的向量
Vector2 oppsitionVec = eventData.position - moveBackPos;
//獲取向量的長(zhǎng)度
float distance = Vector3.Magnitude(oppsitionVec);
//最小值與最大值之間取半徑
float radius = Mathf.Clamp(distance, 0, maxRadius);
//限制半徑長(zhǎng)度
transform.position = moveBackPos + oppsitionVec.normalized * radius;
}
/// <summary>
/// 當(dāng)鼠標(biāo)停止拖拽時(shí)
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData) {
transform.position = moveBackPos;
transform.localPosition = Vector3.zero;
}
}
如何用遙感控制角色的移動(dòng),這里我們通過(guò)動(dòng)畫的位移來(lái)控制移動(dòng)。只需當(dāng)director!=vector3.zero 的時(shí)候更改動(dòng)畫控制器里的Float即可:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
//獲取動(dòng)畫控制器
private Animator ani;
//獲取遙感腳本
public EasyTouchMove touch;
void Start () {
ani = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
//hor = 遙感腳本中的localPosition.x
float hor = touch.Horizontal;
//hor = 遙感腳本中的localPosition.y
float ver = touch.Vertical;
Vector3 direction = new Vector3(hor, 0, ver);
if (direction != Vector3.zero) {
//控制移動(dòng)
float newSpeed = Mathf.Lerp(ani.GetFloat("Speed"), 3, Time.deltaTime * 5);
ani.SetFloat("Speed", newSpeed);
//控制旋轉(zhuǎn)
transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(direction), Time.deltaTime * 10);
}else {
//停止移動(dòng)
float newSpeed = Mathf.Lerp(ani.GetFloat("Speed"), 0, Time.deltaTime * 5);
ani.SetFloat("Speed", 0);
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解C#設(shè)置Excel數(shù)據(jù)自適應(yīng)行高、列寬的2種情況
這篇文章主要介紹了C#設(shè)置Excel數(shù)據(jù)自適應(yīng)行高、列寬的2種情況,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
C#實(shí)現(xiàn)獲取文本文件的編碼的一個(gè)類(區(qū)分GB2312和UTF8)
這篇文章主要介紹了C#實(shí)現(xiàn)獲取文本文件的編碼一個(gè)類,本文給出類可以自動(dòng)區(qū)分GB2312和UTF8,并同時(shí)給出了使用方法,需要的朋友可以參考下2014-09-09
c#訪問(wèn)this關(guān)鍵字和base關(guān)鍵字示例
this關(guān)鍵字引用類的當(dāng)前實(shí)例。靜態(tài)成員方法中不能使用this關(guān)鍵字,this關(guān)鍵字只能在實(shí)例構(gòu)造函數(shù)、實(shí)例方法或?qū)嵗L問(wèn)器中使用。base關(guān)鍵字用于從派生類中訪問(wèn)基類的成員。下面學(xué)習(xí)一下這二個(gè)關(guān)鍵字的使用方法2014-01-01
C# IQueryable<T>揭開表達(dá)式樹的神秘面紗
這篇文章主要介紹了C# IQueryable<T>表達(dá)式樹,對(duì)IQueryable<T>感興趣的同學(xué),必須要仔細(xì)看一下2021-04-04
C#編程實(shí)現(xiàn)帶有Aero效果的窗體示例
這篇文章主要介紹了C#編程實(shí)現(xiàn)帶有Aero效果的窗體,涉及C#調(diào)用動(dòng)態(tài)鏈接庫(kù)針對(duì)窗體屬性的相關(guān)操作技巧,需要的朋友可以參考下2017-07-07
可替代log4j日志的c#簡(jiǎn)單日志類隊(duì)列實(shí)現(xiàn)類代碼分享
簡(jiǎn)單日志類隊(duì)列實(shí)現(xiàn)??砂刺熘茉履甏笮》指钗募?珊?jiǎn)單替代log4j2013-12-12

