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

Unity3D俯视射击游戏子弹无法沿直线发射、方向偏移问题求助

俯视射击游戏子弹发射问题修复方案

核心问题原因

  • 旋转逻辑中直接修改四元数的x/z分量,四元数的分量不是直观的角度值,直接赋值会导致朝向计算错误
  • 移动与旋转操作的Transform对象不统一:朝向旋转作用在playerObj.transform,但移动作用在当前脚本挂载的transform,如果二者不是同一对象,会导致枪口生成点位置与玩家实际朝向错位
  • 子弹实例化后没有显式指定沿朝向正前方飞行的逻辑,仅继承旋转无法保证子弹飞行方向正确

修改后的完整代码

void Update()
{
    //Player face mouse
    Plane playerPlane = new Plane(Vector3.up, transform.position);
    Ray ray = UnityEngine.Camera.main.ScreenPointToRay(Input.mousePosition);
    float hitDist = 0.0f;

    if(playerPlane.Raycast(ray, out hitDist))
    {
        Vector3 targetPoint = ray.GetPoint(hitDist);
        Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
        // 限制欧拉角而非直接修改四元数分量
        Vector3 eulerRotation = targetRotation.eulerAngles;
        eulerRotation.x = 0;
        eulerRotation.z = 0;
        targetRotation = Quaternion.Euler(eulerRotation);
        playerObj.transform.rotation = Quaternion.Slerp(playerObj.transform.rotation, targetRotation, 7f * Time.deltaTime);
    }
    //Player Movement
    // 添加Space.World参数,确保WASD对应世界坐标的前后左右,避免和自身朝向冲突
    if (Input.GetKey(KeyCode.W))
    {
        transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime, Space.World);
    }
    if (Input.GetKey(KeyCode.A))
    {
        transform.Translate(Vector3.left * movementSpeed * Time.deltaTime, Space.World);
    }
    if (Input.GetKey(KeyCode.S))
    {
        transform.Translate(Vector3.back * movementSpeed * Time.deltaTime, Space.World);
    }
    if (Input.GetKey(KeyCode.D))
    {
        transform.Translate(Vector3.right * movementSpeed * Time.deltaTime, Space.World);
    }

    //Shooting
    if (Input.GetMouseButtonDown(0))
    {
       Shoot();
        gunAudio.Play();
    }
}

void Shoot()
{
    // 实例化完整预制体而非transform组件
    GameObject spawnedBullet = Instantiate(bullet, bulletSpawnPoint.transform.position, playerObj.transform.rotation);
    // 给子弹添加沿玩家朝向正前方的初速度,需要保证bullet预制体有Rigidbody组件
    Rigidbody bulletRb = spawnedBullet.GetComponent<Rigidbody>();
    if (bulletRb != null)
    {
        // bulletSpeed可以定义为public变量在Inspector面板调整数值
        bulletRb.velocity = playerObj.transform.forward * bulletSpeed;
    }
}

额外注意事项

  • 确保bulletSpawnPoint对象挂载在playerObj层级下,跟随playerObj旋转和移动
  • 子弹预制体需要添加Rigidbody组件,并且关闭重力选项,避免子弹受重力影响下坠
  • 如果你的WASD需要跟随玩家自身朝向移动,移除移动代码里的Space.World参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:24:04