如何用方向键替代预设目标实现2D俯视角抛物投掷?
实现思路与代码修改
核心思路
放弃依赖预设目标的坐标,改为通过方向键输入生成虚拟目标点,复用原有抛物轨迹计算逻辑,让物体沿指定方向的抛物线飞行。
具体步骤
1. 清理旧目标相关代码
- 删除
[SerializeField] private GameObject target;变量 - 删除
Start()里的target = GameObject.FindGameObjectWithTag("Post"); - 移除代码中所有直接依赖
target的变量(比如targetX),替换为虚拟目标点的坐标
2. 添加方向控制与投掷参数
新增以下变量,用于控制投掷方向和距离:
[SerializeField] private float throwDistance = 15f; // 投掷的最大距离 private Vector2 throwDirection; // 存储方向键输入的方向 private Vector3 virtualTargetPos; // 虚拟目标点坐标
3. 获取方向键输入并生成虚拟目标点
在Start()中获取方向键输入(如果是触发式投掷,可移到投掷触发逻辑里,比如按下空格时计算):
void Start() { player = GameObject.FindGameObjectWithTag("Player"); // 获取方向键输入,归一化后确保方向向量长度一致 throwDirection = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); // 如果没有输入,默认向右投掷 if (throwDirection.magnitude < 0.1f) { throwDirection = Vector2.right; } throwDirection.Normalize(); // 计算虚拟目标点:玩家位置 + 方向向量 × 投掷距离 virtualTargetPos = player.transform.position + new Vector3(throwDirection.x, throwDirection.y, 0) * throwDistance; }
4. 重构轨迹计算逻辑
将原有依赖target的部分替换为虚拟目标点的坐标,修改Update()方法:
void Update() { playerX = player.transform.position.x; float targetX = virtualTargetPos.x; float targetY = virtualTargetPos.y; dist = targetX - playerX; // 避免除以零的错误(当虚拟目标和玩家X坐标相同时) if (Mathf.Abs(dist) < 0.01f) { dist = 0.01f * Mathf.Sign(targetX - playerX); } nextX = Mathf.MoveTowards(transform.position.x, targetX, speed * Time.deltaTime); // 修正Lerp的参数,用进度值替代原有计算方式 float progress = Mathf.InverseLerp(playerX, targetX, nextX); baseY = Mathf.Lerp(player.transform.position.y, targetY, progress); // 调整height计算,确保抛物线形状正确 height = 2 * (nextX - playerX) * (nextX - targetX) / (-0.25f * dist * dist); Vector3 movePosition = new Vector3(nextX, baseY + height, transform.position.z); transform.rotation = LookAtTarget(movePosition - transform.position); transform.position = movePosition; }
5. 可选:触发式投掷优化
如果希望按下按键(比如空格)才生成并投掷物体,可以把方向输入和虚拟目标计算移到玩家脚本的触发逻辑中:
// 玩家脚本中的示例代码 public GameObject projectilePrefab; public float throwDistance = 15f; public void ThrowProjectile() { Vector2 dir = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); if (dir.magnitude < 0.1f) dir = Vector2.right; dir.Normalize(); GameObject projectile = Instantiate(projectilePrefab, transform.position, Quaternion.identity); Projectile projScript = projectile.GetComponent<Projectile>(); projScript.SetThrowDirection(dir, throwDistance); }
然后在Projectile类中添加对应的方法:
public void SetThrowDirection(Vector2 direction, float distance) { throwDirection = direction; virtualTargetPos = player.transform.position + new Vector3(direction.x, direction.y, 0) * distance; }
注意事项
- 确保
Input.GetAxis("Horizontal")和Input.GetAxis("Vertical")对应你在Unity输入设置中的方向键(默认是方向键和WASD) - 可以调整
throwDistance和height计算中的系数,来改变抛物线的高度和投掷距离 - 处理边界情况:比如方向向量为零、虚拟目标和玩家坐标重叠时的除以零问题
内容的提问来源于stack exchange,提问作者kıvanç
相关产品推荐
相关产品推荐

