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

Unity中如何将射门方向钳制在玩家前向45度范围内?

射门角度限制在玩家前向45度范围内的实现方案

现有功能概述

  • 已实现360度环绕玩家的相机,能计算玩家与相机前向的水平夹角(相机在玩家正后方时夹角为0,前方朝向玩家时为180),代码如下:
void AngleBetweenCameraAndPlayer()
{
        var playerAngle = _playerTransform.forward;
        var camAngle = _cameraTransform.forward;
        playerAngle.y = 0;
        camAngle.y = 0;
        var horizDiffAngle = Vector3.Angle(playerAngle, camAngle);
}
  • 射门逻辑:通过Rigidbody.AddForce让球沿相机前向运动:
_ballrb.AddForce(_cameraForward * (power * _timer), ForceMode.Impulse);  // 按相机前向,结合蓄力时间和力量参数射门
  • 轨迹绘制:基于运动学方程绘制球的轨迹,脚本挂载在球上运行正常:
private void DrawProjection()
{
    lineRenderer.positionCount = Mathf.CeilToInt(linePoints / timeBetweenPoints) + 1;
    Vector3 startPosition = transform.position;
    Vector3 startVelocity = _cameraForward * (power * _timer);
    int i = 0;
    lineRenderer.SetPosition(i, startPosition);
    

     for (float time = 0; time < linePoints; time += timeBetweenPoints)
     {
         i++;
         Vector3 point = startPosition + time * startVelocity;
         point.y = startPosition.y + startVelocity.y * time + (Physics.gravity.y/2f * Mathf.Pow(time, 2));
         
         lineRenderer.SetPosition(i, point);
     }
}

需求

射门角度需限制在玩家前向的±45度范围内:当相机前向与玩家前向的夹角超出45度时,仍允许射门,但射门方向锁定在45度边界位置。此前尝试通过判断夹角是否小于45度来控制,导致超出角度时无法射门和绘制轨迹,不符合需求。

解决方案

核心是将相机的水平前向向量约束在玩家前向±45度范围内,得到修正后的射门方向,用该方向统一处理射门和轨迹绘制。

1. 封装获取约束后射门方向的方法

private Vector3 GetConstrainedShootDirection()
{
    // 提取玩家和相机的水平前向(忽略Y轴)
    Vector3 playerHorizontalForward = _playerTransform.forward;
    playerHorizontalForward.y = 0;
    Vector3 cameraHorizontalForward = _cameraTransform.forward;
    cameraHorizontalForward.y = 0;

    // 计算相机前向相对于玩家前向的带符号夹角(区分左右)
    float relativeAngle = Vector3.SignedAngle(playerHorizontalForward, cameraHorizontalForward, Vector3.up);
    
    // 将夹角限制在-45°到45°之间
    float clampedAngle = Mathf.Clamp(relativeAngle, -45f, 45f);
    
    // 根据修正后的角度生成约束后的水平方向
    Vector3 constrainedHorizontalDir = Quaternion.Euler(0, clampedAngle, 0) * playerHorizontalForward;
    constrainedHorizontalDir.Normalize();

    // 保留相机原有的垂直方向分量,保证射门俯仰角度不变
    constrainedHorizontalDir.y = _cameraTransform.forward.y;
    constrainedHorizontalDir.Normalize();

    return constrainedHorizontalDir;
}

2. 修改射门逻辑

替换原相机前向为约束后的方向:

Vector3 finalShootDir = GetConstrainedShootDirection();
_ballrb.AddForce(finalShootDir * (power * _timer), ForceMode.Impulse);

3. 修改轨迹绘制逻辑

同样使用约束后的方向计算初始速度:

private void DrawProjection()
{
    lineRenderer.positionCount = Mathf.CeilToInt(linePoints / timeBetweenPoints) + 1;
    Vector3 startPosition = transform.position;
    Vector3 finalShootDir = GetConstrainedShootDirection();
    Vector3 startVelocity = finalShootDir * (power * _timer);
    int i = 0;
    lineRenderer.SetPosition(i, startPosition);
    

     for (float time = 0; time < linePoints; time += timeBetweenPoints)
     {
         i++;
         Vector3 point = startPosition + time * startVelocity;
         point.y = startPosition.y + startVelocity.y * time + (Physics.gravity.y/2f * Mathf.Pow(time, 2));
         
         lineRenderer.SetPosition(i, point);
     }
}

关键说明

  • 用Vector3.SignedAngle获取带正负的夹角,能精准区分左右方向,确保约束范围是玩家前向左右各45度。
  • 保留相机前向的Y轴分量,仅限制水平方向角度,不影响射门的上下俯仰操作。
  • 无论相机角度是否超出范围,都能生成有效射门方向,避免无法射门或绘制轨迹的问题。

内容的提问来源于stack exchange,提问作者SamuraiCoder17

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:45:06