Unity学习笔记——虚拟摇杆实现笔记(事件触发器的使用、UGUI 坐标转换)

虚拟摇杆实现笔记(事件触发器的使用、UGUI 坐标转换)

一、核心逻辑

通过 EventTrigger 监听摇杆的拖拽/结束拖拽事件,控制摇杆位置,再将摇杆偏移量转为玩家移动方向,实现虚拟摇杆控制角色移动。

主要学习:事件触发器的使用、UGUI 坐标转换

二、代码结构与注释

1. 摇杆事件注册

csharp 复制代码
//从外部获取摇杆物体上的EventTrigger组件
public EventTrigger et;

// 为摇杆添加拖拽事件
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.Drag; // 拖拽事件ID(枚举类型)
entry.callback.AddListener(JoyDrag);   // 绑定拖拽回调方法
et.triggers.Add(entry);

// 为摇杆添加结束拖拽事件
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.EndDrag; // 结束拖拽事件ID
entry.callback.AddListener(EndJoyDrag);   // 绑定结束拖拽回调方法
et.triggers.Add(entry);

2. 拖拽事件回调(控制摇杆位置+玩家移动)

csharp 复制代码
// 摇杆拖拽时执行
private void JoyDrag(BaseEventData data)
{
    // 把基础事件数据转为指针事件数据(获取拖拽相关信息)
    PointerEventData eventData = data as PointerEventData;

    // 旧方法:通过当前摇杆位置 + 拖拽偏移量更新位置
    // 缺点:受UI相机、Canvas模式影响,多分辨率适配较差
    // imgJoy.position += new Vector3(eventData.delta.x, eventData.delta.y, 0);

    // 新方法:使用RectTransformUtility完成屏幕坐标转UI局部坐标,适配性更强
    Vector2 nowPos;
    // 将鼠标/触摸屏幕坐标,转换为摇杆父物体下的局部坐标
    RectTransformUtility.ScreenPointToLocalPointInRectangle(
        imgJoy.parent as RectTransform,  // 目标父物体RectTransform
        eventData.position,              // 原始屏幕坐标
        eventData.enterEventCamera,       // 渲染UI的相机
        out nowPos                        // 输出转换后的局部坐标
    );
    // 赋值局部坐标,实现摇杆精准跟随拖拽点
    imgJoy.localPosition = nowPos;

    // 防止摇杆超出范围:限制摇杆的锚点偏移量最大为110
    if (imgJoy.anchoredPosition.magnitude > 110)
    {
        // 将摇杆位置归一化(保持方向不变),再乘以最大范围,拉回临界位置
        imgJoy.anchoredPosition = imgJoy.anchoredPosition.normalized * 110;
    }

    // 调用玩家移动方法,传入摇杆当前偏移量作为移动方向
    player.Move(imgJoy.anchoredPosition);
}

3. 结束拖拽回调(摇杆复位+玩家停止移动)

csharp 复制代码
// 摇杆拖拽结束时执行
private void EndJoyDrag(BaseEventData data)
{
    // 摇杆锚点位置回归中心点(Vector2.zero)
    imgJoy.anchoredPosition = Vector2.zero;
    // 传入零向量,让玩家停止移动
    player.Move(Vector2.zero);
}

4. 玩家移动控制(Update 帧更新)

csharp 复制代码
void Update()
{
    // 如果当前移动方向不为零(摇杆被拖动)
    if (nowMoveDir != Vector3.zero)
    {
        // 角色沿自身前方移动,速度由 moveSpeed 控制,乘以 Time.deltaTime 保证帧率无关
        this.transform.Translate(Vector3.forward * (moveSpeed * Time.deltaTime));
        // 角色平滑转向目标方向(Slerp实现缓动效果,rotateSpeed控制转向速度)
        this.transform.rotation = Quaternion.Slerp(
            this.transform.rotation, 
            Quaternion.LookRotation(nowMoveDir), 
            rotateSpeed * Time.deltaTime
        );
    }
}

5. 移动方向设置(供摇杆调用)

csharp 复制代码
// 外部调用:将摇杆二维偏移量转为角色三维移动方向
public void Move(Vector2 dir)
{
    nowMoveDir.x = dir.x;   // 摇杆X偏移量 → 角色水平方向
    nowMoveDir.y = 0;       // Y轴(竖直方向)固定为0,不影响高度
    nowMoveDir.z = dir.y;   // 摇杆Y偏移量 → 角色前后方向
}

三、关键知识点

1. EventTrigger 事件绑定(标准四步流程)

a. EventTrigger.Entry entry = new EventTrigger.Entry(); 创建事件条目

b. entry.eventID = EventTriggerType.Drag; 绑定事件枚举类型

c. entry.callback.AddListener(JoyDrag); 绑定拖拽回调方法

d. et.triggers.Add(entry); 把事件添加到EventTrigger组件,事件正式生效

2. 两种摇杆位置更新方式对比

  • 旧方案position + delta 偏移叠加

    直接累加拖拽增量,逻辑简单,但依赖屏幕空间,不同Canvas渲染模式、分辨率下容易错位。

  • 新方案RectTransformUtility.ScreenPointToLocalPointInRectangle 坐标转换

    将屏幕坐标转为UI父物体局部坐标,适配所有UI模式,拖拽跟随更精准,是UGUI拖拽通用写法。

    参数说明:目标父物体RectTransform、屏幕坐标、UI相机、输出局部坐标。

3. 摇杆范围限制

  • anchoredPosition:UI元素相对于锚点的偏移量,适合做摇杆位置控制
  • magnitude:向量长度,用于判断摇杆是否超出最大范围
  • normalized:向量归一化,保持方向不变,仅缩放长度到1,再乘以最大范围实现"拉回"限位

4. 方向转换逻辑

  • 摇杆的二维 Vector2 偏移量 → 角色三维 Vector3 移动方向(X→水平,Y→前后,Y轴固定为0)
  • Quaternion.LookRotation:根据方向向量生成目标旋转
  • Quaternion.Slerp:实现平滑转向,避免角色瞬间转头

5. 帧率无关移动

  • 所有移动/旋转逻辑乘以 Time.deltaTime,保证不同帧率下移动速度保持一致
相关推荐
LinXunFeng4 小时前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
通信小呆呆4 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick4 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee4 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn864 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e4 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨4 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
闪闪发亮的小星星4 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq5 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan5 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析