unity3d 虚拟摇杆 ugui
程序员文章站
2023-12-27 10:22:09
...
网上找了好多都嫌麻烦,谷歌了一下,完美解决。
需要先建立 Canvas,如下:
代码拖拽到 backImage里:
JoyStick.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class JoyStick : MonoBehaviour,IDragHandler,IPointerUpHandler,IPointerDownHandler{
private Image outImage; // 摇杆背景
private Image inImage; // 摇杆
private Vector3 inputVector;
void Start() {
outImage = GetComponent<Image>();
inImage = transform.GetChild(0).GetComponent<Image>();
}
public virtual void OnDrag(PointerEventData ped)
{
Vector2 pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(outImage.rectTransform
,ped.position
,ped.pressEventCamera
,out pos)) {
pos.x = (pos.x / outImage.rectTransform.sizeDelta.x);
pos.y = (pos.y / outImage.rectTransform.sizeDelta.y);
inputVector = new Vector3(pos.x * 2 - 1, 0, pos.y * 2 - 1);
inputVector = (inputVector.magnitude > 1.0f) ? inputVector.normalized : inputVector;
Debug.Log(inputVector);
// Move inImage
inImage.rectTransform.anchoredPosition =
new Vector3(inputVector.x * (outImage.rectTransform.sizeDelta.x / 2)
, inputVector.z * (outImage.rectTransform.sizeDelta.y / 2));
}
}
// 按住摇杆
public virtual void OnPointerDown(PointerEventData ped) {
OnDrag(ped);
}
// 松开摇杆
public virtual void OnPointerUp(PointerEventData ped)
{
inputVector = Vector3.zero;
inImage.rectTransform.anchoredPosition = Vector3.zero;
}
// 外部调用的方法
public float Horizontal() {
if (inputVector.x != 0)
return inputVector.x;
else
return Input.GetAxis("Horizontal");
}
// 同上
public float Vertical()
{
if (inputVector.z != 0)
return inputVector.z;
else
return Input.GetAxis("Vertical");
}
public Vector3 getInputVector() {
return inputVector;
}
}
需要用的时候,直接拖拽backImage到Player里,然后调用:
...
public JoyStick joystick;
public JoyStick joystick2;
...
float h = joystick.Horizontal();
float v = joystick.Vertical();
附上一个角色子弹方向控制的脚本:
float x = joystick2.getInputVector().x;
float z = joystick2.getInputVector().z;
Quaternion newQuaternion = Quaternion.LookRotation(new Vector3(x,0,z));
playerRigidbody.MoveRotation(newQuaternion);
注意: anchor 设置的时候 需要调整new Vector3(pos.x * 2 - 1, 0, pos.y * 2 - 1);
中的 ‘1’ ,试下把,具体原理是判断UI的坐标,没深入研究,以后再看~
根据鼠标点击显示摇杆
// 按下摇杆
public virtual void OnPointerDown(PointerEventData ped)
{
isMoving = true;
// 改变out摇杆位置
Vector2 p_pos;
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_mask_limit.rectTransform
, ped.position
, ped.pressEventCamera
, out p_pos))
{
// 这里是为了调整位置
m_outImage.rectTransform.anchoredPosition = p_pos
+ new Vector2(0.5f * m_mask_limit.rectTransform.sizeDelta.x, 0.5f * m_mask_limit.rectTransform.sizeDelta.x);
}
// 显示按钮
m_outImage.gameObject.SetActive(true);
}
注意事项:
1、通过判断ugui位置时需要image是正方形 或者 圆
2、pivot要设置成 0.5 0.5