Unity2D 模拟手柄实现玩家移动
创作时间:
作者:
@小白创作中心
Unity2D 模拟手柄实现玩家移动
引用
CSDN
1.
https://m.blog.csdn.net/qq_43209531/article/details/138752307
本文介绍了一种在Unity2D游戏中实现虚拟手柄控制玩家移动的方法,包括按钮模式和摇杆模式的实现。虽然文章发布于2024年5月,但其基本原理和实现方法仍然具有参考价值。需要注意的是,Unity引擎的版本更新可能会影响某些API的使用,因此在实际开发中请根据具体情况进行调整。
1. 创建控制器UI
首先需要创建一个控制器UI,用于显示虚拟手柄的界面。这通常包括一个摇杆和一些方向按钮。
2. 挂载脚本
将编写好的脚本挂载到玩家游戏对象上,以便控制其移动。
3. 脚本编写
基本要素
[Tooltip("玩家游戏体")]
public Rigidbody2D player;
[Tooltip("玩家速度")]
public float speed = 1f;
[Tooltip("玩家动画")]
public Animator animator;
public enum Mode {
BUTTON,
ROCKER,
}
[Tooltip("模式")]
public Mode mode = Mode.ROCKER;
模式切换
在Start()
方法中根据mode
的值,设置相关物体的Active状态。
基本移动逻辑
因为需要不断的更新移动(长按不松开),而Update
方法每帧都在执行,所以在Update
方法中执行移动操作。
void Update()
{
doMove();
}
具体移动逻辑
private void doMove()
{
if (player == null) {
return;
}
// 获取方向
Vector2 dir = getDir();
if (dir == Vector2.zero) return;
Vector2 pos = player.position;
// 10是随便设置的一个控制值,不然太慢
pos.y += Time.deltaTime * speed * 10 * dir.y;
pos.x += Time.deltaTime * speed * 10 * dir.x;
player.MovePosition(pos);
}
private Vector2 getDir()
{
if (mode == Mode.BUTTON)
{
if (curPointerObj == null) return Vector2.zero;
switch(curPointerObj.name)
{
case "Up":
return Vector2.up;
case "Down":
return Vector2.down;
case "Left":
return Vector2.left;
default:
return Vector2.right;
}
}
return rockerDir;
}
3.1 按钮模式实现
基本逻辑
监听触摸事件,按下(IPointerDownHandler
)为开始移动,抬起(IPointerUpHandler
)为结束移动,实现按下按钮并松开的移动过程。
脚本
// 值为当前按下的按钮
private GameObject curPointerObj = null;
按下
public void OnPointerDown(PointerEventData eventData)
{
if (player == null || mode != Mode.BUTTON) {
return;
}
GameObject pointerObj = eventData.pointerEnter;
if (curPointerObj != null) {
return;
}
curPointerObj = pointerObj;
}
抬起
public void OnPointerUp(PointerEventData eventData)
{
if (player == null || mode != Mode.BUTTON) {
return;
}
GameObject pointerObj = eventData.pointerEnter;
if (curPointerObj == null || curPointerObj != pointerObj) {
return;
}
curPointerObj = null;
}
3.2 摇杆模式实现
基本逻辑
监听拖拽事件,拖拽中(IEndDragHandler
)为开始/移动中,拖拽结束(IDragHandler
)为结束移动,实现拖拽并松开的移动过程。
脚本
// 摇杆内部可拖拽部分
private RectTransform rockerInnerTransform;
// 摇杆外部不可拖拽部分-边界
private RectTransform rockerOuterTransform;
// 当前摇杆方向
private Vector2 rockerDir = Vector2.zero;
拖拽中
public void OnDrag(PointerEventData eventData)
{
if (player == null || mode != Mode.ROCKER) return;
Vector2 pos = Camera.main.ScreenToWorldPoint(eventData.position);
Vector2 rockerOriginPosition = rockerOuterTransform.position;
// 拖拽方向
rockerDir = (pos - rockerOriginPosition).normalized;
float distance = Vector2.Distance(pos, rockerOriginPosition);
if (distance <= 1.5f) // 1.5f刚好是摇杆外部边界和摇杆内部可拖拽部分中心重合时的距离
{
rockerInnerTransform.position = pos;
}
else
{
Vector2 dir = pos - rockerOriginPosition;
// 拖拽超过摇杆外部边界时,摇杆内部可拖拽的位置为:外部中心 + 当前拖拽方向指定的拖拽距离位置(此时设置为1.5f,到达边界)。
rockerInnerTransform.position = rockerOriginPosition + dir.normalized * 1.5f;
}
}
拖拽结束
public void OnEndDrag(PointerEventData eventData)
{
if (player == null || mode != Mode.ROCKER) return;
// 恢复方向和位置
rockerDir = Vector2.zero;
rockerInnerTransform.position = rockerOuterTransform.position;
}
热门推荐
ADA指南再更新!提出预防或延缓糖尿病及相关合并症的15项建议
多维度艺术创新:吴立民音乐绘画对水墨艺术的未来启示
激光打印机常见故障解决方法大揭秘
海南双人游预算详解:交通、住宿及美食费用全解析
重视胃肠镜检查 远离消化道疾病
马斯克到底有没有阿斯伯格综合征?
发烧会使手指关节痛吗
AI算力产业链及竞争格局分析
极氪领克合并:全球最大汽车合并案后的新能源征途何在?
打造梦想中的更衣室:八大要素详解
李沐详解大语言模型:现状、挑战与未来展望
独特好听龙凤胎宝宝名字大全2024:既有寓意又显个性
职场行为与职业发展的4大优化策略,让成长更高效
栀子的功效与作用
二月初二龙抬头:理发与民俗文化
冬季肉鸭养殖应注意什么?
咳嗽有白痰,偶尔带血丝?当心这些疾病!
洗牙过程详解,每一步的步骤与注意的事
主备站点数据库数据同步异常处理指南
英雄联盟影视的下一站,诺克萨斯还是艾欧尼亚?
提升气质的8种方法
壁挂炉为什么水压力表为0却不漏水?
2024年全国各省市985和211高校录取率分析及工科类学科排名
如何理解和应对港币汇率的变化情况?这种汇率变化对经济有哪些潜在影响?
2的二分一平方,你真的会算吗?揭秘数学背后的逻辑之美
冥想与理财:实现身心平衡的双重指南
编程中的HSV色彩模型:定义、应用与优势
外贸企业如何应对国际市场挑战:多元化市场布局策略
深入探讨“性别”与“性别认同”的复杂性与社会影响
皮肤管理不迷茫,专家教你如何科学护肤!