[Add] VContainer
This commit is contained in:
@@ -0,0 +1,292 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using VContainer.Internal;
|
||||
|
||||
namespace VContainer.Unity
|
||||
{
|
||||
public static class ObjectResolverUnityExtensions
|
||||
{
|
||||
public readonly struct PrefabDirtyScope : IDisposable
|
||||
{
|
||||
readonly GameObject _prefab;
|
||||
readonly bool _madeDirty;
|
||||
|
||||
public PrefabDirtyScope(GameObject prefab)
|
||||
{
|
||||
_prefab = prefab;
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2020_1_OR_NEWER
|
||||
_madeDirty = prefab.activeSelf && !UnityEditor.EditorUtility.IsDirty(_prefab);
|
||||
#else
|
||||
_madeDirty = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if UNITY_EDITOR && UNITY_2020_1_OR_NEWER
|
||||
if (_madeDirty)
|
||||
{
|
||||
UnityEditor.EditorUtility.ClearDirty(_prefab);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static void InjectGameObject(this IObjectResolver resolver, GameObject gameObject)
|
||||
{
|
||||
void InjectGameObjectRecursive(GameObject current)
|
||||
{
|
||||
if (current == null) return;
|
||||
|
||||
using (ListPool<MonoBehaviour>.Get(out var buffer))
|
||||
{
|
||||
buffer.Clear();
|
||||
current.GetComponents(buffer);
|
||||
foreach (var monoBehaviour in buffer)
|
||||
{
|
||||
if (monoBehaviour != null)
|
||||
{ // Can be null if the MonoBehaviour's type wasn't found (e.g. if it was stripped)
|
||||
resolver.Inject(monoBehaviour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var transform = current.transform;
|
||||
for (var i = 0; i < transform.childCount; i++)
|
||||
{
|
||||
var child = transform.GetChild(i);
|
||||
InjectGameObjectRecursive(child.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
InjectGameObjectRecursive(gameObject);
|
||||
}
|
||||
|
||||
public static T Instantiate<T>(this IObjectResolver resolver, T prefab)
|
||||
where T : Component
|
||||
{
|
||||
return resolver.Instantiate(prefab, prefab.transform.position, prefab.transform.rotation);
|
||||
}
|
||||
|
||||
public static T Instantiate<T>(this IObjectResolver resolver, T prefab, Transform parent, bool worldPositionStays = false)
|
||||
where T : Component
|
||||
{
|
||||
var wasActive = prefab.gameObject.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab.gameObject))
|
||||
{
|
||||
prefab.gameObject.SetActive(false);
|
||||
|
||||
var instance = UnityEngine.Object.Instantiate(prefab, parent, worldPositionStays);
|
||||
|
||||
SetName(instance, prefab);
|
||||
|
||||
try
|
||||
{
|
||||
resolver.InjectGameObject(instance.gameObject);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.gameObject.SetActive(wasActive);
|
||||
instance.gameObject.SetActive(wasActive);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static T Instantiate<T>(
|
||||
this IObjectResolver resolver,
|
||||
T prefab,
|
||||
Vector3 position,
|
||||
Quaternion rotation)
|
||||
where T : Component
|
||||
{
|
||||
if (resolver.ApplicationOrigin is LifetimeScope scope)
|
||||
{
|
||||
return scope.Instantiate(prefab, position, rotation);
|
||||
}
|
||||
|
||||
return resolver.Instantiate(prefab, position, rotation, null);
|
||||
}
|
||||
|
||||
public static T Instantiate<T>(
|
||||
this IObjectResolver resolver,
|
||||
T prefab,
|
||||
Vector3 position,
|
||||
Quaternion rotation,
|
||||
Transform parent)
|
||||
where T : Component
|
||||
{
|
||||
var wasActive = prefab.gameObject.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab.gameObject))
|
||||
{
|
||||
prefab.gameObject.SetActive(false);
|
||||
|
||||
var instance = UnityEngine.Object.Instantiate(prefab, position, rotation, parent);
|
||||
|
||||
SetName(instance, prefab);
|
||||
|
||||
try
|
||||
{
|
||||
resolver.InjectGameObject(instance.gameObject);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.gameObject.SetActive(wasActive);
|
||||
instance.gameObject.SetActive(wasActive);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
static T Instantiate<T>(this LifetimeScope scope, T prefab, Vector3 position, Quaternion rotation)
|
||||
where T : Component
|
||||
{
|
||||
var wasActive = prefab.gameObject.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab.gameObject))
|
||||
{
|
||||
prefab.gameObject.SetActive(false);
|
||||
|
||||
T instance;
|
||||
if (scope.IsRoot)
|
||||
{
|
||||
instance = UnityEngine.Object.Instantiate(prefab, position, rotation);
|
||||
UnityEngine.Object.DontDestroyOnLoad(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Into the same scene as LifetimeScope
|
||||
instance = UnityEngine.Object.Instantiate(prefab, position, rotation, scope.transform);
|
||||
instance.transform.SetParent(null);
|
||||
}
|
||||
|
||||
SetName(instance, prefab);
|
||||
|
||||
try
|
||||
{
|
||||
scope.Container.InjectGameObject(instance.gameObject);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.gameObject.SetActive(wasActive);
|
||||
instance.gameObject.SetActive(wasActive);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
static GameObject Instantiate(this LifetimeScope scope, GameObject prefab, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
var wasActive = prefab.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab))
|
||||
{
|
||||
prefab.SetActive(false);
|
||||
|
||||
GameObject instance;
|
||||
if (scope.IsRoot)
|
||||
{
|
||||
instance = UnityEngine.Object.Instantiate(prefab, position, rotation);
|
||||
UnityEngine.Object.DontDestroyOnLoad(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Into the same scene as LifetimeScope
|
||||
instance = UnityEngine.Object.Instantiate(prefab, position, rotation, scope.transform);
|
||||
instance.transform.SetParent(null);
|
||||
}
|
||||
|
||||
SetName(instance, prefab);
|
||||
|
||||
try
|
||||
{
|
||||
scope.Container.InjectGameObject(instance);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.SetActive(wasActive);
|
||||
instance.SetActive(wasActive);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject Instantiate(this IObjectResolver resolver, GameObject prefab)
|
||||
{
|
||||
return resolver.Instantiate(prefab, prefab.transform.position, prefab.transform.rotation);
|
||||
}
|
||||
|
||||
public static GameObject Instantiate(this IObjectResolver resolver, GameObject prefab, Transform parent, bool worldPositionStays = false)
|
||||
{
|
||||
var wasActive = prefab.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab))
|
||||
{
|
||||
prefab.SetActive(false);
|
||||
|
||||
GameObject instance = null;
|
||||
try
|
||||
{
|
||||
instance = UnityEngine.Object.Instantiate(prefab, parent, worldPositionStays);
|
||||
SetName(instance, prefab);
|
||||
resolver.InjectGameObject(instance);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.SetActive(wasActive);
|
||||
instance?.SetActive(wasActive);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
public static GameObject Instantiate(
|
||||
this IObjectResolver resolver,
|
||||
GameObject prefab,
|
||||
Vector3 position,
|
||||
Quaternion rotation)
|
||||
{
|
||||
if (resolver.ApplicationOrigin is LifetimeScope scope)
|
||||
{
|
||||
return scope.Instantiate(prefab, position, rotation);
|
||||
}
|
||||
|
||||
return resolver.Instantiate(prefab, position, rotation, null);
|
||||
}
|
||||
|
||||
public static GameObject Instantiate(
|
||||
this IObjectResolver resolver,
|
||||
GameObject prefab,
|
||||
Vector3 position,
|
||||
Quaternion rotation,
|
||||
Transform parent)
|
||||
{
|
||||
var wasActive = prefab.activeSelf;
|
||||
using (new PrefabDirtyScope(prefab))
|
||||
{
|
||||
prefab.SetActive(false);
|
||||
|
||||
var instance = UnityEngine.Object.Instantiate(prefab, position, rotation, parent);
|
||||
|
||||
SetName(instance, prefab);
|
||||
|
||||
try
|
||||
{
|
||||
resolver.InjectGameObject(instance);
|
||||
}
|
||||
finally
|
||||
{
|
||||
prefab.SetActive(wasActive);
|
||||
instance.SetActive(wasActive);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetName(UnityEngine.Object instance, UnityEngine.Object prefab)
|
||||
{
|
||||
if (VContainerSettings.Instance != null && VContainerSettings.Instance.RemoveClonePostfix)
|
||||
instance.name = prefab.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user