Поскольку вышеуказанный скрипт использует static
экземпляра, он будет работать, только если `одного GameObject прилагается еще это - еще хуже, он будет удалять других объектов, которые пытаются использовать такое же поведение.
Самая большая проблема заключается в том, что всякий раз, когда вы загружаете сцену, все объекты в этой сцене загружаются. Если они не были выгружены (спасибо DontDestroyOnLoad
), они будут дублированы, так как сцена не знает, что они «уже существуют»
Приведенный выше сценарий может работать лучше, если вы попытаетесь поместить ваши постоянные объекты под зонтик, и только зонтичный объект (обычно называемый Toolbox
) не разрушается. Однако это в основном подходит для сценариев администратора.
Если вы знаете объекты, которые не предназначены для уничтожения, попробуйте загрузить их через сцену «Загрузка». Поскольку это перемещает постоянные объекты из вашей сцены карты, они не будут дублироваться при перезагрузке сцены карты. Бонус к этому шаблону, поскольку он упрощает реализацию занавеса.
Если вы хотите реализовать это в качестве простого поведенческого сценария, рассмотрите возможность добавления идентификатора, как так
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
каждый раз, когда скрипт будет реализован.
Никогда, никогда не применяйте статику в Единстве. *** это не система OO, это ECS. *** никогда не используйте «это» ключевое слово в Unity, если вы это делаете, вы делаете что-то совершенно неправильное. *** это не система OO, это ECS. *** http://stackoverflow.com/a/35723305/294884 – Fattie
(хех) Обратите внимание, что «технически абсолютно невозможно» «удалить дубликаты» (по крайней мере, не внутри, так что это конец) - вы часто видите нелепые примеры кода в Интернете, где люди пытаются «удалить дубликаты», чтобы сделать ситуацию, как в OO, где у вас «что-то вроде одиночного». ECS совершенно иная. – Fattie