Unity学习90天-第3天-认识触屏输入(手游基础)并完成手机点击屏幕,物体向点击位置移动

张开发
2026/4/15 7:57:56 15 分钟阅读

分享文章

Unity学习90天-第3天-认识触屏输入(手游基础)并完成手机点击屏幕,物体向点击位置移动
一、什么是触屏输入手机游戏没有鼠标和键盘玩家唯一的输入设备就是手指。Unity 把每一次手指触碰屏幕封装成一个叫做Touch的结构体。Touch 记录了三个核心信息position触点位置手指在屏幕哪里phase触摸阶段手指现在处于什么状态deltaPosition移动量这一帧手指移动了多少可以把Touch理解为手指的档案每根手指有自己的一份档案随时更新。二、两个最常用的 API在Update()里我们用这两个 API 获取触摸信息Input.touchCount // 当前屏幕上有几根手指 Input.GetTouch(index) // 获取第 index 根手指的 Touch 数据touchCount就像数人头——你得先知道有没有人再去拿数据。GetTouch(0)中的0是索引代表第一根手指和数组一样从0开始。三、TouchPhase——触摸的五个阶段这是触屏输入里最重要的概念。每根手指在屏幕上的生命周期分为五个阶段阶段英文枚举触发时机按下TouchPhase.Began手指刚放上去的那一帧移动TouchPhase.Moved手指在移动的每一帧静止TouchPhase.Stationary手指按着但没动抬起TouchPhase.Ended手指离开屏幕的那一帧中断TouchPhase.Canceled来电话等系统打断类比就像开门的过程——推门Began→ 门在动Moved→ 门停住Stationary→ 门关上Ended四、Touch 结构体详解Touch touch Input.GetTouch(0); touch.fingerId // 手指的唯一编号区分哪根手指 touch.position // 屏幕像素坐标Vector2左下角是(0,0) touch.deltaPosition // 本帧相对上一帧的位移Vector2 touch.phase // 当前所处阶段见上表 touch.tapCount // 连续点击次数单击1双击2position 的坐标系是这样的(0, 1080)————————(1920, 1080)屏幕中心(0, 0)—————————(1920, 0)注意触摸坐标原点在左下角和 Unity UI 的锚点方向一致。五、脚本实现——点击检测那么我们手机触屏的基本知识就已经学完啦接下来我们来运用知识进行实现脚本吧目标手指点下屏幕时打印触点的屏幕坐标。using UnityEngine; public class TapDemo : MonoBehaviour { void Update() { // 第一步先判断有没有手指在屏幕上 if (Input.touchCount 0) { // 第二步取第一根手指的数据 Touch touch Input.GetTouch(0); // 第三步只在按下的那一帧响应 if (touch.phase TouchPhase.Began) { Debug.Log(点击位置 touch.position); } } } }为什么要判断TouchPhase.Began因为手指放在屏幕上不动Update()每帧都会执行。如果不判断 Began只要手指还按着就会每帧都打印——这不是我们想要的点击效果。Began 只在放下的那一帧为 true之后变成 Stationary 或 Moved所以只会触发一次。六、脚本实现——点击位置移动6.1 实现思路拆解在动手写代码之前先把这个功能拆解成几个小问题手指点击屏幕 → 获取屏幕坐标2D像素坐标屏幕坐标 → 转换成世界坐标3D空间位置物体当前位置 → 平滑移动到目标位置最关键的一步是第2步——屏幕坐标和世界坐标不是一回事坐标类型单位示例屏幕坐标touch.position像素(540, 960)世界坐标物体 TransformUnity单位(2.3f, 0, -1.5f)Unity 提供了转换函数Camera.main.ScreenToWorldPoint()帮我们完成这个换算。6.2 ScreenToWorldPoint——屏幕转世界坐标Camera.main.ScreenToWorldPoint(Vector3 position)参数说明参数类型说明position.xfloat触点的屏幕 x 坐标position.yfloat触点的屏幕 y 坐标position.zfloat距相机的深度必须手动指定为什么需要 z因为相机把 3D 世界拍扁成了 2D 屏幕丢失了深度信息。z 就是告诉 Unity我要的那个点在相机前方多远的平面上z 值怎么填把物体当前离相机的距离赋给 z这样转换出来的世界坐标就和物体在同一个深度平面上。// 先算出物体离相机有多远 float distToCamera Vector3.Distance(transform.position, Camera.main.transform.position); // 再传给 ScreenToWorldPoint Vector3 worldPos Camera.main.ScreenToWorldPoint( new Vector3(touch.position.x, touch.position.y, distToCamera) );6.3 平滑移动——Vector3.MoveTowards移动到目标点有两种常见方式方式函数效果匀速移动Vector3.MoveTowards全程速度一致到达即停缓动移动Vector3.Lerp越接近目标越慢丝滑感在这里我使用MoveTowards更适合点哪走哪的手游操控感transform.position Vector3.MoveTowards( transform.position, // 当前位置 targetPos, // 目标位置 speed * Time.deltaTime // 每帧移动距离 );transform.position物体当前所在位置targetPos我们想让它去的位置点击处speed * Time.deltaTime每帧最多走多远乘以 deltaTime 保证帧率无关6.4 脚本总结在这里我将展示完整的代码给大家以供参考using UnityEngine; public class ClickMoveDemo : MonoBehaviour { public float speed 5f; // 移动速度 private Vector3 targetPos; // 目标位置 void Start() { // 初始目标位置就是自身位置防止一开始就乱跑 targetPos transform.position; } void Update() { HandleInput(); // 第一步处理输入更新目标点 MoveToTarget(); // 第二步每帧向目标点靠近 } // ── 输入处理 ────────────────────────────── void HandleInput() { #if UNITY_EDITOR // 编辑器里用鼠标左键模拟点击 if (Input.GetMouseButtonDown(0)) { SetTargetFromScreen(Input.mousePosition); } #else // 真机上用触摸 if (Input.touchCount 0 Input.GetTouch(0).phase TouchPhase.Began) { SetTargetFromScreen(Input.GetTouch(0).position); } #endif } // ── 屏幕坐标 → 世界坐标 → 更新目标点 ───── void SetTargetFromScreen(Vector2 screenPos) { // 用物体到相机的距离作为深度值 float distToCamera Vector3.Distance( transform.position, Camera.main.transform.position ); // 屏幕坐标转世界坐标 Vector3 worldPos Camera.main.ScreenToWorldPoint( new Vector3(screenPos.x, screenPos.y, distToCamera) ); // 保持 y 轴不变物体在地面上不要飞起来或陷地里 worldPos.y transform.position.y; targetPos worldPos; Debug.Log(新目标点 targetPos); } // ── 每帧向目标位置移动 ──────────────────── void MoveToTarget() { transform.position Vector3.MoveTowards( transform.position, targetPos, speed * Time.deltaTime ); } }七、在编辑器里怎么测试真机触屏没法在 PC 编辑器里直接测用下面这段代码可以一套脚本编辑器用鼠标手机用触摸自动切换void Update() { #if UNITY_EDITOR // 编辑器中用鼠标模拟 if (Input.GetMouseButtonDown(0)) { Debug.Log(【编辑器】点击 Input.mousePosition); } #else // 真机上用触摸 if (Input.touchCount 0 Input.GetTouch(0).phase TouchPhase.Began) { Debug.Log(【真机】点击 Input.GetTouch(0).position); } #endif }#if UNITY_EDITOR是预编译指令Unity 打包到手机时UNITY_EDITOR那段代码会被自动剔除只保留触摸部分。八、总结下面我将总结本章的关键函数为表给大家功能关键代码检测有无触摸Input.touchCount 0点击瞬间touch.phase TouchPhase.Began抬起瞬间touch.phase TouchPhase.Ended滑动方向Ended时 (终点 - 起点)坐标转世界坐标Camera.main.ScreenToWorldPoint()今天的教学就到这里接下来我将连续更新90天的Untiy教程从基础到一个网络部分有兴趣的朋友们可以收藏关注谢谢如果有疑问评论区见。成果展示由于不是真机测试这个博主用的是鼠标模拟屏幕点击忘记的可以回看Unity学习90天-第2天-认识键盘 / 鼠标输入PC并实现WASD 移动鼠标控制物体转向https://blog.csdn.net/qq_57101277/article/details/160084017?spm1001.2014.3001.5501

更多文章