Unity 2D中Shoot函数内Transform.position返回(0,0,0),子弹生成异常
问题:子弹生成在场景中心而非角色位置
点击按钮调用Shoot()函数时,本该在角色位置生成子弹,结果生成在场景中心。在PlayerShooter脚本的Start()方法中能获取到正确的transform.position值,但点击按钮触发Shoot()时,该值返回(0,0,0)。发现子弹是在预制体的位置生成,而非实例化角色对象的位置,求修复方法。
PlayerShooter脚本
using Photon.Pun; using UnityEngine; public class PlayerShooter : MonoBehaviour { [SerializeField] private GameObject _bullet; [SerializeField] private float _distanceMultiplier; public void Shoot() { if (PhotonNetwork.PlayerList.Length > 1) { PhotonNetwork.Instantiate(_bullet.name, transform.position, transform.rotation); } } }
角色移动脚本(PlayerMover)
using UnityEngine; using Photon.Pun; [RequireComponent(typeof(Rigidbody2D), typeof(CapsuleCollider2D))] public class PlayerMover : MonoBehaviour { [SerializeField] private float _speepMoving, _speedRotation; private Rigidbody2D _rigidbody; private Vector2 _direction; private PhotonView _view; [HideInInspector] public FixedJoystick joystick; private void Start() { _view = GetComponent<PhotonView>(); _rigidbody = GetComponent<Rigidbody2D>(); } private void FixedUpdate() { if (_view.IsMine && PhotonNetwork.PlayerList.Length > 1) { _rigidbody.velocity = new Vector2(joystick.Horizontal * _speepMoving, joystick.Vertical * _speepMoving); RotatePlayer(); } } private void RotatePlayer() { _direction = new Vector2(joystick.Horizontal, joystick.Vertical); if (_direction != Vector2.zero) { Quaternion toRotation = Quaternion.LookRotation(Vector3.forward, _direction); _rigidbody.MoveRotation(Quaternion.Lerp(transform.rotation, toRotation, _speedRotation * Time.deltaTime)); } } }
修复方案
问题根源
核心原因是按钮绑定的是预制体上的Shoot()方法,而非场景中实例化后的角色对象。点击按钮时调用的是预制体(默认位置为(0,0,0))的方法,自然会在场景中心生成子弹。另外缺少本地玩家权限校验,可能引发跨客户端的同步问题。
具体修复步骤
修正按钮事件绑定
- 不要在Project面板的预制体Inspector中绑定按钮事件,而是在运行时找到场景中的角色实例,将按钮的OnClick事件拖拽绑定到该实例的
PlayerShooter -> Shoot()方法上。 - 或者通过代码动态绑定:在角色的
Start()方法中,找到UI按钮组件,添加点击事件监听:// 在PlayerShooter的Start方法中添加 void Start() { var shootButton = GameObject.Find("ShootButton").GetComponent<UnityEngine.UI.Button>(); if(shootButton != null) { shootButton.onClick.AddListener(Shoot); } }
- 不要在Project面板的预制体Inspector中绑定按钮事件,而是在运行时找到场景中的角色实例,将按钮的OnClick事件拖拽绑定到该实例的
添加本地玩家权限校验
修改Shoot()方法,确保只有当前玩家控制的角色才能触发射击:public void Shoot() { var photonView = GetComponent<PhotonView>(); // 仅本地玩家且房间内玩家数大于1时执行射击 if (photonView != null && photonView.IsMine && PhotonNetwork.PlayerList.Length > 1) { PhotonNetwork.Instantiate(_bullet.name, transform.position, transform.rotation); } }检查子弹预制体配置
- 确保子弹预制体已添加到PhotonServerSettings的
Registered Prefabs列表中,否则PhotonNetwork.Instantiate会出现异常。 - 将子弹预制体的Transform初始位置设为(0,0,0),避免实例化时自带偏移。
- 确保子弹预制体已添加到PhotonServerSettings的
内容的提问来源于stack exchange,提问作者user21403547
相关产品推荐
相关产品推荐

