unity3d 玩家死亡后重新启动游戏将删除游戏对象

5rgfhyps  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(309)

我正在创建一个使命召唤僵尸风格的游戏。我目前遇到的问题是当我的球员的健康= 0游戏重新启动,但出于某种原因抛出了以下错误:
缺少引用异常:类型为“Transform”的对象已被破坏,但您仍在尝试访问它。
您的脚本应该检查它是否为空,或者您不应该销毁该对象。
获取位置()(位置:0)
Gun.Shoot()(位于资产/脚本/Gun.cs:55)
播放器拍摄.更新()(位于资产/脚本/播放器拍摄.cs:16)
我正在使用Unity场景管理功能,当我的玩家的生命值达到0时,我运行代码:

Debug.Log("Dead");
            SceneManager.LoadScene("Zombie Game");

在枪脚本或玩家射击脚本中没有任何地方是关于在死亡时摧毁任何游戏对象或变形的。
玩家拍摄脚本:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerShoot : MonoBehaviour {

    public static Action shootInput;
    public static Action reloadInput;

    [SerializeField] private KeyCode reloadKey = KeyCode.R;

    private void Update()
    {
        if (Input.GetMouseButton(0))
            shootInput?.Invoke();

        if (Input.GetKeyDown(reloadKey))
            reloadInput?.Invoke();
    }
}

枪械剧本:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class Gun : MonoBehaviour {

    Ray ray; // the ray with origin amd direction for the cast
    float distance; // if needed a maximum distance
    LayerMask layers; // the general raycast layer - not different ones for each player ;)
    GameObject Player; // your player object
    

    [Header("References")]
    [SerializeField] private GunData gunData;
    [SerializeField] private Transform cam;
    
    float timeSinceLastShot;
        

    public void Start() {
        PlayerShoot.shootInput += Shoot;
        PlayerShoot.reloadInput += StartReload;
        
    }

    public void OnDisable() => gunData.reloading = false;

    public void StartReload() {
        if (!gunData.reloading && this.gameObject.activeSelf)
            StartCoroutine(Reload());
    }

    private IEnumerator Reload() {
        gunData.reloading = true;

        yield return new WaitForSeconds(gunData.reloadTime);

        gunData.currentAmmo = gunData.magSize;

        gunData.reloading = false;
    }

    public bool CanShoot() => !gunData.reloading && timeSinceLastShot > 1f / (gunData.fireRate / 60f);

    public void Shoot() {
        
        if (gunData.currentAmmo > 0) {
            if (CanShoot()) 
            {
                
                if (Physics.Raycast(cam.position, cam.forward, out RaycastHit hitInfo, gunData.maxDistance))
                {
                    IDamageable damageable = hitInfo.transform.GetComponent<IDamageable>();
                    damageable?.TakeDamage(gunData.damage);
                    
                }

                gunData.currentAmmo--;
                timeSinceLastShot = 0;
                OnGunShot();

            }
        }

        

    }

    public void Update() 
    
    {
        timeSinceLastShot += Time.deltaTime;

        Debug.DrawRay(cam.position, cam.forward * gunData.maxDistance);

        
    }

    public void OnGunShot() {}

    

   
      }

我是新的编码,所以这是一个坚韧的一个我尝试和工作。
我确信这个问题与玩家变形或射线投射有关,但我不知道我能做些什么来防止游戏重置时发生这种错误。
任何帮助都将不胜感激。

pqwbnv8z

pqwbnv8z1#

当你调用SceneManager.LoadScene("Zombie Game")来重新加载你的场景时。这会有效地破坏场景中没有DontDestroyOnLoad属性的对象。
通常,在对象被销毁时取消订阅事件是一种好的做法。这是因为事件是一种委托类型,是对可在以后调用的方法的引用。如果不取消订阅事件,则委托将继续引用该方法,即使为事件注册的对象已被销毁。
如果事件是在终结对象之后触发,这可能会造成问题,因为委派仍会尝试呼叫终结对象上的方法。这可能会导致掷回错误或例外状况,视事件的实作和它呼叫的方法而定。
若要避免这些问题,建议您取消订阅事件之已注册对象的OnDestroy()方法中的事件。这样可以确保委派不再指涉对象上的方法,而且事件可以安全地触发而不会造成任何错误:

public class Gun : MonoBehaviour {
    
    public void Start() {
        PlayerShoot.shootInput += Shoot;
        PlayerShoot.reloadInput += StartReload;
    }

    private void OnDestroy() {
        PlayerShoot.shootInput -= Shoot;
        PlayerShoot.reloadInput -= StartReload;
    }
}

还应确保通过检查器指定的任何引用在重新加载场景后仍保持有效。

相关问题