Unity2D横版卷轴:实现《武士零》风格锥形区域固定距离传送
问题:2D横版跑酷传送冲刺功能实现+Unity学习资源推荐
背景与需求
- 接触Unity不到一周的纯新手,首个项目是移动端2D横版无限跑酷,用于熟悉引擎
- 已实现按住屏幕触发短时间慢动作,需新增以下功能:
- 按住屏幕时显示锥形/圆形指示器,标记最大传送距离
- 玩家上下滑动手指,通过一条线确定具体传送位置
- 抬起手指后,角色传送到线与指示器的交点,同时路径上所有敌人受伤/被消灭(瞬移或高速冲刺均可),参考《武士零》00:21的效果
- 补充:游戏中玩家移动速度随时间提升
遇到的问题
- 尝试施加力:角色沿弧线运动,无法限制最大移动距离
- 尝试让角色跟随鼠标:角色持续跟随,不符合需求
现有测试脚本
慢动作触发脚本(空格键触发)
public TimeManager timeManager; [SerializeField] private float force = 5f; //Force that is implied to move the character forward void Update() { if (Input.GetButtonDown("Jump")) { timeManager.DoSlowmotion(); Rigidbody2D rb = GetComponent<Rigidbody2D>(); // Gets the position of the mouse cursor in world space Vector3 direction = Camera.main.ScreenToWorldPoint(Input.mousePosition); rb.AddForce(direction * force, ForceMode2D.Impulse); } }
鼠标位置跟踪脚本
public class Mouse : MonoBehaviour { public GameObject MousePosGameObject; void Update() { Vector3 mousePos = Input.mousePosition; mousePos.z = MousePosGameObject.transform.position.z - Camera.main.transform.position.z ; MousePosGameObject.transform.position = Camera.main.ScreenToWorldPoint(mousePos); }
实现方案与资源推荐
一、传送冲刺功能分步实现
1. 移动端输入处理
替换鼠标输入为触摸输入,通过Input.touches区分触摸阶段:
TouchPhase.Began:触摸开始时触发慢动作,激活指示器TouchPhase.Moved:触摸滑动时更新瞄准线和目标点TouchPhase.Ended:触摸抬起时执行传送/冲刺+伤害判定
2. 指示器与瞄准线绘制
- 指示器:用圆形/锥形Sprite制作,设置
maxDashDistance(比如10f)作为最大传送距离,触摸开始时将其位置设为角色当前位置,半径/长度对应最大距离,显示在世界空间中。 - 瞄准线:给角色添加LineRenderer组件,触摸滑动时,计算角色到触摸点的方向,取与指示器边界的交点作为终点,实时更新LineRenderer的两个端点(角色位置→交点)。
3. 计算传送目标点
触摸滑动时,通过方向向量锁定最大距离内的目标点:
public float maxDashDistance = 10f; void CalculateTargetPos() { Vector3 playerPos = transform.position; // 触摸点转世界坐标,保持Z轴与角色一致 Vector3 touchWorldPos = Camera.main.ScreenToWorldPoint(Input.GetTouch(0).position); touchWorldPos.z = playerPos.z; // 计算单位方向向量 Vector3 direction = (touchWorldPos - playerPos).normalized; // 目标点锁定在最大传送距离边界 Vector3 targetPos = playerPos + direction * maxDashDistance; }
4. 传送/冲刺实现
- 瞬移(新手首选):直接设置角色位置,简单无物理干扰:
transform.position = targetPos; - 高速冲刺:用协程实现平滑移动,保留冲刺视觉效果:
IEnumerator DashToTarget(Vector3 target) { float dashSpeed = 50f; while (Vector3.Distance(transform.position, target) > 0.1f) { transform.position = Vector3.MoveTowards(transform.position, target, dashSpeed * Time.deltaTime); yield return null; } transform.position = target; }
5. 路径敌人伤害判定
用2D射线检测覆盖冲刺路径,检测敌人并触发伤害:
void DetectEnemiesInPath(Vector3 startPos, Vector3 direction, float distance) { // 仅检测Enemy层(需提前给敌人设置专属Layer) int enemyLayer = LayerMask.GetMask("Enemy"); RaycastHit2D[] hits = Physics2D.RaycastAll(startPos, direction, distance, enemyLayer); foreach (RaycastHit2D hit in hits) { Enemy enemy = hit.collider.GetComponent<Enemy>(); if (enemy != null) { enemy.TakeDamage(100); // 直接消灭或自定义伤害值 } } }
6. 修复现有问题
- 移除AddForce实现:物理力会受重力影响导致弧线,改用直接位置设置或MoveTowards实现直线移动
- 取消持续跟随:仅在触摸抬起(
TouchPhase.Ended)时执行一次传送,而非持续更新位置
二、优质Unity学习资源
新手入门类
- Unity官方Learn平台「2D Beginner」系列:从基础操作到完整2D游戏制作,免费且适配新手节奏
- Brackeys的2D游戏教程:中文搬运版覆盖基础跑酷、平台跳跃项目,代码注释清晰,手把手教学
- 阿发的Unity入门课:针对国内新手的中文教程,讲解细致,适合零基础快速上手
进阶提升类
- 猫都能学会的Unity:专注2D开发技巧,包含输入优化、物理调优、性能优化等实用内容
- Unity官方文档:API问题的权威参考,建议养成查文档的习惯
项目实战类
- Code Monkey的2D跑酷完整项目教程:从空白到发布全流程,包含无限地形生成、分数系统等,适合练手
内容的提问来源于stack exchange,提问作者StonedPineapple
相关产品推荐
相关产品推荐

