实现方式一:通过EventTrigger实现
自定义点击区域
制作按钮
在区域内点击触发事件
点击显示,抬起隐藏
旋钮的拖拽
点击触发事件如何实现?
有很多种实现方法,这里我采用了EventTrigger组件,通过拖拽函数的方式触发事件。
值得注意的是:拖拽的脚本必须是已经挂载在游戏对象上的脚本。
另外一种方法。
这里也可以采用通过拖拽获得EventTrigger,在通过代码去添加事件的方式来触发事件。
拖拽的难点
我没有使用拖拽函数,而是在Update中判断。
只有点击时拖拽才能够执行Update里面的内容,所以有一个布尔值CanDrag表示,按下才能够拖拽,抬起就不能够拖拽了。
private void Update()
{
if (canControl)
ControlJoyStick();
}
private void ControlJoyStick()
{
Vector2 dir = Mouse.current.position.ReadValue()- clickPos;
float moveRadius = dir.magnitude;
// 最终呈现在屏幕上的大小 = 原来的大小 乘以 缩放比例
float maxRaidus = joystickOutline.rect.width / 2 * canvasScaleX;
moveRadius = Mathf.Min(moveRadius, maxRaidus);
move = dir.normalized * moveRadius;
joysticknob.position = clickPos + move;
// 旧版输入系统
//if(Input.GetMouseButtonUp(0))
// Hide();
if(Mouse.current.leftButton.wasReleasedThisFrame)
{
Hide();
}
}
完整代码
using UnityEngine;
using UnityEngine.InputSystem;
namespace DY
{
/// <summary>
/// 需要使用新输入系统
/// 1. 允许玩家在自定义的区域内点击
/// 2. 开始时隐藏,点击后显示
/// 3. 控制旋钮
/// 4. 返回一个方向,以控制玩家
/// </summary>
public class MobileJoystick : MonoBehaviour
{
[SerializeField] RectTransform joystickOutline;
[SerializeField] RectTransform joysticknob;
private float canvasScaleX;
private Vector2 clickPos;
private bool canControl;
private Vector2 move;
private void Start()
{
Hide();
canvasScaleX = GetComponentInParent<Canvas>().GetComponent<RectTransform>().localScale.x;
}
private void Update()
{
if (canControl)
ControlJoyStick();
}
private void ControlJoyStick()
{
Vector2 dir = Mouse.current.position.ReadValue()- clickPos;
float moveRadius = dir.magnitude;
// 最终呈现在屏幕上的大小 = 原来的大小 乘以 缩放比例
float maxRaidus = joystickOutline.rect.width / 2 * canvasScaleX;
moveRadius = Mathf.Min(moveRadius, maxRaidus);
move = dir.normalized * moveRadius;
joysticknob.position = clickPos + move;
// 旧版输入系统
//if(Input.GetMouseButtonUp(0))
// Hide();
if(Mouse.current.leftButton.wasReleasedThisFrame)
{
Hide();
}
}
private void Show()
{
joystickOutline.gameObject.SetActive(true);
canControl = true;
}
private void Hide()
{
joystickOutline.gameObject.SetActive(false);
canControl = false;
}
/// <summary>
/// 在自定义的区域内点击,触发的回调函数
/// </summary>
public void ClickedOnJoystickZoneCallback()
{
clickPos = Mouse.current.position.ReadValue();
joystickOutline.position = clickPos;
Show();
}
public Vector3 GetMoveDir()
{
return move.normalized;
}
}
}
实现方式二:通过UGUI的事件函数实现
using UnityEngine;
using UnityEngine.EventSystems;
public class DragController : MonoBehaviour,
IPointerDownHandler, IPointerUpHandler,
IDragHandler
{
public GameObject DragBar;
public Transform Bar;
//可移动区域的最远距离
public float R;
private void Start()
{
//DragBar.SetActive(false);
}
public void OnPointerDown(PointerEventData eventData)
{
//1.需要在UI上设定一个点击区域,点击后,摇杆出现,抬起后,摇杆消失
//DragBar.SetActive(true);
//2.根据点击位置移动整个摇杆
Vector2 localPos;
RectTransformUtility.ScreenPointToLocalPointInRectangle(
transform as RectTransform,//获取DragArea的Transform,底座在Area上
eventData.position,//屏幕坐标系下触摸的点
eventData.pressEventCamera,//触发事件的相机
out localPos//获得的本地坐标系下的点
);
DragBar.transform.localPosition = localPos;
}
public void OnPointerUp(PointerEventData eventData)
{
//DragBar.SetActive(false);
Bar.localPosition = Vector3.zero;
}
public void OnDrag(PointerEventData eventData)
{
Vector2 localPos;
//3.拖拽时,将杆的位置进行移动
RectTransformUtility.ScreenPointToLocalPointInRectangle(
DragBar.transform as RectTransform,//获取DragBar的Transform,因为Bar是DragBar的子物体
eventData.position,//屏幕坐标系下触摸的点
eventData.pressEventCamera,//触发事件的相机
out localPos//获得的本地坐标系下的点
);
//4.限制摇杆距离
//越界了
if (localPos.magnitude > R)
{
//拖拽点标准化*R
localPos = localPos.normalized * R;
}
Bar.localPosition = localPos;
}
}
评论区