c# – 公共静态字典中的GameObjects在Unity中的场景变化中被销毁

第一次正式声明:

编程语言:Unity中的C#(MonoBehavior)

我的技能水平:Kinda noob(不到半年c#经验).

我正在制作一个块状破坏者游戏(Arkanoid)并且正在制作一个实施系统.游戏是一次性的,当你关闭web-build时没有删除所有内容(没有缓存,没有filesave,没有可序列化的类).

Acheivement系统包含:
“成就”课程:很多变量和一些跟踪进度的方法.它附加到具有相同名称的空GameObject的脚本.普通班级.

“AManager”课程.初始化“Acheivement”类的一堆副本的类,为它们提供单独的值并将它们添加到下面提到的字典中.辛格尔顿班.

“AcheivementDictionary”类:仅包含私有静态字典和访问方法.也是一个singelton类

问题:

在第一个场景的“开始”时进行并添加成就.添加它们之后,我会检索GameObjects并测试它们的标签是否正常工作,一切都很好.然后从我的“levelManager”类中,我从下一个场景调用相同的方法,并获得一个消息,即游戏对象被销毁.如果我测试它们,它们也会返回null.

那么……我真正的问题是:

如何使我的实体游戏对象的实例副本能够持续通过Unity中的所有场景变化?

代码参考:

我不认为“成就”是有任何问题的类,如果你需要来自该类的代码只是大喊大叫.

“AManager”

public class Amanager : MonoBehaviour {

    public static Amanager acheivementManager = null;
public GameObject myAchObject;

void Awake () {
        if (acheivementManager != null) { 
        Destroy(gameObject);
        } else {
            acheivementManager = this;
            GameObject.DontDestroyOnLoad(gameObject);
        }
    }

void Start () {

    myAchObject.AddComponent<Acheivement>();


    initAcheivements ("completeLevelThree", "Level 3", "Complete level 3","Level", 3,5);
    initAcheivements ("completeLevelOne", "Level 1", "Complete level 1","Level", 1,5);
    }

private void initAcheivements(string inAch, string inNavn, string inHow, string inCountType, int goalVal, int Reward) {


            Vector3 loc = new Vector3 (0f, 0f,0f);
            GameObject testAch;
            testAch = Instantiate(myAchObject, loc, Quaternion.identity) as GameObject; 
            //testLives.SetActive (true);
            //testLives.gameObject.tag = "clone";

        testAch.GetComponent<Acheivement>().setName(inNavn);
        testAch.GetComponent<Acheivement>().setHowToGet(inHow);
        testAch.GetComponent<Acheivement>().setCountType(inCountType);
        testAch.GetComponent<Acheivement>().setGoalVal(goalVal);
        testAch.GetComponent<Acheivement>().setReward(Reward);
        testAch.tag = inCountType;
        Debug.Log ("InitiAch did run");
        AcheivementDictionary._Instance.achRegAdder(inNavn,testAch);
}

AcheivementDictionary代码:

public class AcheivementDictionary : MonoBehaviour {
public static AcheivementDictionary _Instance;

    private static Dictionary<string,GameObject> AchReg = new Dictionary<string,GameObject>();

void Awake () {
        if (_Instance != null) { 
            Destroy(gameObject);
        } else {
            _Instance = this;
            GameObject.DontDestroyOnLoad(gameObject);
    }
    }

    public void achRegAdder (string inName, GameObject theAch) {
    AchReg.Add(inName,theAch);
    Debug.Log ("achRegAdded did run");
    readThisString = inName;
    tryRead = true;
    }

    private void readIt() {
    Debug.Log ("readItRan"); 
    GameObject testShit; 
    AchReg.TryGetValue("Level 1",out testShit);
    Debug.Log("if it works level should stand there ---> " + testShit.tag);
    tryRead = false;
    }

    public void achRegReader () {
        readIt ();
    }

运行时,控制台中会显示以下消息:

initAch did run

achRegAdded did run

initAch did run

achRegAdded did run

readItRan

if it works level should stand there —> Level

readitRan

MissingReferenceException: The object of type “GameObject” has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the obejct.

(当尝试访问存储对象的标记时出现此错误,并在以下方法调用中发生:Debug.Log(“如果它的工作级别应该站在那里—>”testShit.tag);)

这是用于在失败时调用achRegReader的代码行(来自另一个类):
AcheivementDictionary._Instance.achRegReader();

另外:如果我计算字典中的对象数量,它确实会返回2.它们只是被破坏了,我真的不明白为什么.我的程序中没有代码可以破坏这些代码.

我的猜测是这样的:

关于在Singelton类中放置静态字典,我有些不明白的问题.
虽然两个处理它们的类都是dontDestroyOnLoad,但是实现的实体副本不会在场景中持续存在,因为它们不是dontDestroyOnLoad.
无论哪种方式,我都没有设法在最后6个小时的斗争中孤立或解决问题,请帮忙!

最佳答案 在initAcheivements函数中,也是

testAch.transform.setParent(transform);

要么

DontDestroyOnLoad(testAch);

你的问题是由testAch引起的,要么不是一个不会被破坏的对象的子代,要么testAch不是一个不会被破坏的对象本身.

在回复你的评论时,我很快写了这段代码并没有给我任何问题,我可能错过了什么吗?

Vector3 loc = new Vector3(0f, 0f, 0f);
var testAch = Instantiate(myAchObject, loc, Quaternion.identity) as GameObject;
DontDestroyOnLoad(testAch);
点赞