You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用方向键替代预设目标实现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ç

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 13:05:03