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
相关产品推荐
相关产品推荐

