【问题标题】:How to find the GameObject tagged as 'Player'如何找到标记为“玩家”的游戏对象
【发布时间】:2019-03-29 13:30:10
【问题描述】:

[Picture]我正在开发一款游戏并尝试制作一个保存和加载按钮。我相信我的编码是正确的,但我的问题是找不到我想要访问的播放器。我怀疑这与我的编码方式有关。

由于有多个级别,我使用了以下代码: GameObject player = GameObject.FindWithTag("Player");尝试在场景中找到给定的玩家,但我认为它不起作用。

我没有将播放器设置为公共变量,因为它在每个场景中都会发生变化。

例如,我尝试使用以下代码行访问玩家当前的健康状况,这些代码保存在名为 Gamecontrol.cs 的脚本中的 GameController 空游戏对象中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using UnityEngine.SceneManagement;

public class GameControl : MonoBehaviour {
    public static GameControl controller;
    int shooterHealth;
    int shooterScore;
//public GameObject player;
//public GameObject gun;
    int level;

// Use this for initialization
    void Awake() {
        GameObject player = GameObject.FindWithTag("Player");
        shooterHealth = player.GetComponent<PlayerHealth>().currentHealth;
        shooterScore = player.GetComponent<Gun>().score;
        level = player.GetComponent<PlayerHealth>().level;


        if(controller == null) {
            DontDestroyOnLoad(gameObject);
            controller = this;
        }
        else if(controller != this) {
            Destroy(gameObject);
        }

    }
    public void SaveGame() {
        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Create(Application.persistentDataPath +     "/shooter.dat");

        PlayerData data = new PlayerData();
        data.shooterHealth = shooterHealth;
        data.shooterScore = shooterScore;
        data.level = level;
        bf.Serialize(file, data);
        file.Close();
    }

    public void LoadGame() {
        if(File.Exists(Application.persistentDataPath + "/shooter.dat")) 
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath +     "/shooter.dat", FileMode.Open);
            PlayerData data = (PlayerData)bf.Deserialize(file);

            file.Close();


            GameObject player = GameObject.FindWithTag("Player");
            player.GetComponent<PlayerHealth>().currentHealth = data.shooterHealth;
            player.GetComponent<Gun>().score = data.shooterScore;
            level = player.GetComponent<PlayerHealth>().level;
            SceneManager.LoadScene(level);




        }
    }


}
[Serializable]
class PlayerData
{
    public int shooterHealth;
    public int shooterScore;
    public int level;
}

我得到的错误是:

NullReferenceException:对象引用未设置为对象的实例 GameControl.Awake () (在 Assets/GameControl.cs:20)

有人知道解决这个问题的方法吗?提前谢谢你:)

【问题讨论】:

  • 您确定播放器标记正确吗?
  • 是的,我敢肯定,我什至尝试将标签更改为不同的标签,它说同样的错误:(
  • 这很奇怪。你能分享完整的脚本,也许你在代码的其他部分做错了
  • 玩家也在场景中活跃吗?如果没有,那你就找不到了。
  • 我更新了一张图片:)

标签: c# unity3d


【解决方案1】:

错误在shooterScore = player.GetComponent&lt;Gun&gt;().score; 您正在尝试访问组件Gun,但玩家游戏对象没有附加Gun 组件。可能是你忘了附上它,或者它有另一个名字。

也许您在运行时附加了Gun 组件。在这种情况下,请检查脚本执行顺序以验证 GameControl 脚本是否在运行时附加 Gun 组件的脚本之后执行。

【讨论】:

  • 我现在刚刚将 Gun 组件附加到 Player,但不幸的是出现了同样的错误,GameControl 脚本似乎无法找到带有 player 标签的对象,原因很奇怪..
  • 你检查脚本执行顺序了吗?
  • 我检查了执行顺序,并添加了 Gun 和 PlayerHealth 组件在任何其他脚本之前执行,但这也没有任何作用?从错误来看,我认为它是“GameObject player =...”部分。如果找到玩家,这些命令应该执行
  • NullReferenceException: Object reference not set to an instance of an object GameControl.Awake () (at Assets/GameControl.cs:20) -- 这是 shooterHealth 所在的行
  • 也许你有更多带有“玩家”标签的游戏​​对象。在这种情况下,您应该使用FindGameObjectsWithTag("Player")。它返回一个游戏对象列表而不是单个游戏对象。然后您循环返回的 GameObjects 并找到哪个附加了 PlayerHealth 组件并使用它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多