做unity游戲時(shí),如果是做手機(jī)端則需要加一個(gè)虛擬搖桿以便玩家控制角色移動(dòng)(做pc端則直接獲取鍵值即可較方便)。原理就是用Image制作一個(gè)大圓圈住一個(gè)Image小圓,玩家拖拽小圓控制角色移動(dòng)。中心思想是,以小圓中心為(0,0),獲取拖拽的偏移量即可。
首先將圖片資源拉入項(xiàng)目
在Hierarchy右鍵新建一個(gè)Canvas(UI → Canvas),并在其下新建一個(gè)Image作為搖桿背景(JoyStick-Backfround),在此搖桿背景下新建一Image作為搖桿(JoyStick)
要注意的是,JoyStick-Background的RectTransform應(yīng)設(shè)為左下,寬度和高度可按個(gè)人所需設(shè)定(我設(shè)了200*200)
也可打開Scene手動(dòng)調(diào)整虛擬搖桿在屏幕中的位置
將背景和搖桿圖片資源拉到JoyStick-Background和JoyStick的Image內(nèi)
新建一代碼(VJHandler)并添加給JoyStick-Background
#VJHanlder
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class VJHandler : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler{
private Image jsContainer;
private Image joystick;
public Vector3 InputDirection;
void Start()
{
jsContainer = GetComponent<Image>();
joystick = transform.GetChild(0).GetComponent<Image>(); //此處獲取了子對(duì)象即搖桿的Image引用
InputDirection = Vector3.zero;
}
public void OnDrag(PointerEventData ped)
{
Vector2 position = Vector2.zero;
//獲取輸入方向(該函數(shù)返回joystick當(dāng)前的坐標(biāo)值)
RectTransformUtility.ScreenPointToLocalPointInRectangle
(jsContainer.rectTransform,
ped.position,
ped.pressEventCamera,
out position); //該函數(shù)out為返回值,此處打印可得position為(x, y)即搖桿相對(duì)于中心(0, 0)的坐標(biāo)值
//限定JoyStick能移動(dòng)的區(qū)域
joystick.rectTransform.anchoredPosition = new Vector3(InputDirection.x * (jsContainer.rectTransform.sizeDelta.x) / 3,
InputDirection.y * (jsContainer.rectTransform.sizeDelta.y) / 3);
}
public void OnPointerDown(PointerEventData ped) //當(dāng)觸摸或點(diǎn)擊搖桿時(shí),立即觸發(fā)這個(gè)事件
{
OnDrag(ped);
}
public void OnPointerUp(PointerEventData ped) //重置搖桿的方向和初始位置
{
InputDirection = Vector3.zero;
joystick.rectTransform.anchoredPosition = Vector3.zero;
}
}
其實(shí)寫到屏幕坐標(biāo)轉(zhuǎn)成local坐標(biāo)這里就已經(jīng)實(shí)現(xiàn)了搖桿功能了,因?yàn)榇颂庉敵龅淖鴺?biāo)(代碼中out position)就是搖桿的坐標(biāo)
RectTransformUtility.ScreenPointToLocalPointInRectangle
(jsContainer.rectTransform,
ped.position,
ped.pressEventCamera,
out position);
print("out position:" + position);
加一行打印,然后運(yùn)行游戲,拖動(dòng)搖桿,能看到輸出了每一幀搖桿的坐標(biāo)值:
之后再根據(jù)你的人物移動(dòng)邏輯,根據(jù)已獲取搖桿的坐標(biāo)值,傳給動(dòng)畫器即可實(shí)現(xiàn)人物移動(dòng)。
如果你像我這樣用(-1,0)…設(shè)置人物東南西北的移動(dòng)動(dòng)畫
則在VJHandler內(nèi)加上坐標(biāo)轉(zhuǎn)換邏輯即可,先判斷搖桿在哪一個(gè)象限,然后判斷搖桿在x和y的方向上哪個(gè)偏移量更大。
if(position.x >= 0 && position.y >= 0) //搖桿位于第一象限
{
if (position.x > position.y)
{
position.x = 1;
position.y = 0;
}
else {
position.x = 0;
position.y = 1;
}
}
else if (position.x <= 0 && position.y > 0) //第二象限
{
if (Mathf.Abs(position.x) > position.y)
{
position.x = -1;
position.y = 0;
}
else
{
position.x = 0;
position.y = 1;
}
} else if(position.x <= 0 && position.y <= 0) //第三象限
{
if(Mathf.Abs(position.x) > Mathf.Abs(position.y))
{
position.x = -1;
position.y = 0;
}
else
{
position.x = 0;
position.y = -1;
}
}
else if (position.x >= 0 && position.y <= 0) //第四象限
{
if (position.x > Mathf.Abs(position.y))
{
position.x = 1;
position.y = 0;
}
else
{
position.x = 0;
position.y = -1;
}
}
InputDirection = new Vector3(position.x, position.y);
然后新建一個(gè)Script添加給PlayerObject,新建一個(gè)Vector3命名為movement接取VJHandler的InputDirection內(nèi)的坐標(biāo)值(即轉(zhuǎn)換好的虛擬搖桿的坐標(biāo)值),再用animator.SetFloat傳給unity內(nèi)的Animator即可(記得在unity內(nèi)的Animator設(shè)好變量,此處變量是xDir, yDir)文章來源:http://www.zghlxwxcb.cn/news/detail-663128.html
using System.Collections;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public float moveSpeed = 0.5f;
public VJHandler jsMovement;
Vector3 movement = new Vector3();
Animator animator;
Rigidbody2D rb2D;
private void Start()
{
animator = GetComponent<Animator>();
rb2D = GetComponent<Rigidbody2D>();
}
void Update()
{
UpdateState();
}
void FixedUpdate()
{
MoveCharacter();
}
private void MoveCharacter()
{
movement.x = jsMovement.InputDirection.x;
movement.y = jsMovement.InputDirection.y;
movement.Normalize(); //向量歸一化
rb2D.velocity = movement * moveSpeed; //rg2D實(shí)現(xiàn)移動(dòng)
}
private void UpdateState()
{
if(Mathf.Approximately(movement.x, 0) && Mathf.Approximately(movement.y, 0))
{
animator.SetBool("isWalking", false);
}
else
{
animator.SetBool("isWalking", true);
}
animator.SetFloat("xDir", movement.x);
animator.SetFloat("yDir", movement.y);
}
}
參考:https://blog.csdn.net/JianZuoGuang/article/details/88944777文章來源地址http://www.zghlxwxcb.cn/news/detail-663128.html
到了這里,關(guān)于unity開發(fā)筆記#230821-手搓一個(gè)虛擬搖桿的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!