由于DontDestroyOnLoad()重复

时间:2016-03-22 19:34:57

标签: c# unity3d

我对DontDestroyOnLoad有一个奇怪的问题。我有一张地图作为起始场景。从那里,用户可以单击某些地图对象,并使用Application.LoadLevel()加载新级别。当关卡完成后,将再次加载地图。但是,附加DontDestroyOnLoad的对象在第二次加载时重复。

当前脚本:

void Awake()
{
    DontDestroyOnLoad(transform.gameObject);
}

我在网上搜索并找到了这个可能的解决方案来删除重复项:

public class NoDestroy : MonoBehaviour {

    public static NoDestroy instance;

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this.gameObject);
            return;
        }

        DontDestroyOnLoad(this.gameObject);

    }
    }

以上脚本只是不起作用。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

因为上面的脚本使用static实例,所以只有在单个GameObject附加了它的情况下它才会起作用 - 更糟的是,它会删除其他对象试图使用相同的行为。

最大的问题是无论何时加载场景,该场景中的所有对象都会被加载。如果他们没有被卸载(感谢DontDestroyOnLoad)他们将被复制,因为场景并不知道他们已经存在"

如果您尝试将持久对象打包在伞下,并且只有伞对象(通常称为Toolbox)未被破坏,则上述脚本可能会更好。但这主要适用于管理器脚本。

如果您知道要销毁的对象,请考虑通过" Loading"现场。由于这会将持久对象移出地图场景,因此在重新加载地图场景时,它们不会重复。这种模式的好处,因为它可以更容易实现幕帘。

如果要将其实现为简单的行为脚本,请考虑添加类似的ID

public class NoDestory : MonoBehaviour
{
    private static Dictionary<string, GameObject> _instances = new Dictionary<string, GameObject>();
    public string ID; // HACK: This ID can be pretty much anything, as long as you can set it from the inspector

    void Awake()
    {
        if(_instances.ContainsKey(ID))
        {
            var existing = _instances[ID];

            // A null result indicates the other object was destoryed for some reason
            if(existing != null)
            {
                if(ReferenceEquals(gameObject, existing)
                    return;

                Destroy(gameObject);

                // Return to skip the following registration code
                return;
            }
        }

        // The following code registers this GameObject regardless of whether it's new or replacing
        _instances[ID] = gameObject;

        DontDestroyOnLoad(gameObject);
    }
}

这将防止具有与已存在的ID值相同的Destory值的对象重复,并且如果所述对象已在其他位置ID进行,则允许重新创建。每次执行脚本时,都可以通过添加一个特殊的Editor脚本来移植新的@Entity public class Books { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String title; private String author; private Long numComments; // getters and setters... } 来进一步细化。