我对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);
}
}
以上脚本只是不起作用。我该如何解决这个问题?
答案 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...
}
来进一步细化。