Unity 시스템.Weak Reference 사용
19047 단어 Unity
개요
Unity 시스템.Weak Reference 테스트를 사용합니다.
System.Weak Reference 예.Net4.5에서 시작합니다.
https://msdn.microsoft.com/ja-jp/library/gg712738(v=vs.110).aspx
컨디션
Unity5.5.2p4
결실
사용 가능합니다.
System.참조는 Weak Reference의 Target에 저장되어 있으며 모델은 System입니다.Object.
이 Unity Engine 입니다.Object에 대한 특수 null 검사가 처리되지 않았습니다.
System.Weak Reference의 IsAlive, Target 처리를 변경하면 를 사용할 수 있습니다.
테스트 코드
대략적인 절차는 다음과 같다.
Unity5.5.2p4
결실
사용 가능합니다.
System.참조는 Weak Reference의 Target에 저장되어 있으며 모델은 System입니다.Object.
이 Unity Engine 입니다.Object에 대한 특수 null 검사가 처리되지 않았습니다.
System.Weak Reference의 IsAlive, Target 처리를 변경하면 를 사용할 수 있습니다.
테스트 코드
대략적인 절차는 다음과 같다.
대략적인 절차는 다음과 같다.
MonoBehaviourCache.cs
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
[DefaultExecutionOrder(int.MinValue)]
public class MonoBehaviourCache : MonoBehaviour
{
class UnityWeakReference<T> : System.WeakReference where T : UnityEngine.Object
{
public UnityWeakReference(T target) : base(target) {}
public override bool IsAlive
{
get
{
// MEMO: UnityEngine.Objectのnullチェックが特殊なためキャストして調査する
UnityEngine.Object obj = Target as UnityEngine.Object;
return obj != null;
}
}
public new T Target
{
get { return base.Target as T; }
set { base.Target = value; }
}
public bool TryGetTarget(out T target)
{
target = base.Target as T;
return target != null;
}
}
static MonoBehaviourCache _instance;
Dictionary<int, UnityWeakReference<MonoBehaviour>> _dictionary = new Dictionary<int, UnityWeakReference<MonoBehaviour>>();
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void CreateInstance()
{
Debug.LogFormat("MonoBehaviourCache.CreateInstance()");
GameObject gameObject = new GameObject("MonoBehaviourCache");
_instance = gameObject.AddComponent<MonoBehaviourCache>();
DontDestroyOnLoad(gameObject);
SceneManager.sceneUnloaded += SceneUnloaded;
}
private static void SceneUnloaded(Scene scene)
{
Debug.LogFormat("MonoBehaviourCache.SceneUnloaded() scene:{0}", scene.name);
List<int> removeIds = new List<int>(_instance._dictionary.Count);
foreach(var pair in _instance._dictionary)
{
if (pair.Value.Target == null)
{
Debug.LogFormat("MonoBehaviourCache.SceneUnloaded() Unused object. InstanceID:{0}", pair.Key);
removeIds.Add(pair.Key);
}
else
Debug.LogFormat("MonoBehaviourCache.SceneUnloaded() Already used object. InstanceID:{0}, Type:{1}", pair.Key, pair.Value.Target.GetType());
}
foreach (int id in removeIds)
_instance._dictionary.Remove(id);
}
static public bool Add(MonoBehaviour monoBehaviour)
{
if (monoBehaviour == null)
return false;
int id = monoBehaviour.GetInstanceID();
if (_instance._dictionary.ContainsKey(id))
{
Debug.LogFormat("MonoBehaviourCache.Add() Already contains instance id of object. InstanceID:{0}", id);
return false;
}
_instance._dictionary.Add(id, new UnityWeakReference<MonoBehaviour>(monoBehaviour));
return true;
}
static public T Get<T>(int instanceId) where T : MonoBehaviour
{
UnityWeakReference<MonoBehaviour> weakReference;
if (!_instance._dictionary.TryGetValue(instanceId, out weakReference))
{
Debug.LogWarningFormat("MonoBehaviourCache.Get() Not found element. instanceId:{0}", instanceId);
return null;
}
return weakReference.Target as T;
}
}
인스턴스를 생성할 때 TestObject 2 객체를 생성합니다.버튼을 누르면 장면 2로 이동합니다.
TestObject1.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class TestObject1 : MonoBehaviour
{
int _instanceId;
private void Awake()
{
GameObject gameObject = new GameObject("TestObject2");
TestObject2 testObject2 = gameObject.AddComponent<TestObject2>();
_instanceId = testObject2.GetInstanceID();
Debug.LogFormat("TestObject1.Awake() testObject2 id:{0}", _instanceId);
MonoBehaviourCache.Add(testObject2);
testObject2 = MonoBehaviourCache.Get<TestObject2>(_instanceId);
Debug.LogFormat("TestObject1.Awake() testObject2:{0}", testObject2);
}
public void OnPressedButton()
{
SceneManager.LoadScene("Scene2");
}
private void OnDestroy()
{
Debug.LogFormat("TestObject1.OnDestroy()");
TestObject2 testObject2 = MonoBehaviourCache.Get<TestObject2>(_instanceId);
Debug.LogFormat("TestObject1.OnDestroy() testObject2:{0}", testObject2);
}
}
헛되이 실현하다.TestObject2.cs
using UnityEngine;
public class TestObject2 : MonoBehaviour
{
}
출력 로그 MonoBehaviourCache.CreateInstance()
TestObject1.Awake() testObject2 id:-53294
TestObject1.Awake() testObject2:TestObject2 (My.TestObject2)
TestObject1.OnDestroy()
TestObject1.OnDestroy() testObject2:null
MonoBehaviourCache.SceneUnloaded() scene:Scene1
MonoBehaviourCache.SceneUnloaded() Unused object. InstanceID:-53294
프로필에 대한 조사
장면 1
필드 2로 이동 후
Reference
이 문제에 관하여(Unity 시스템.Weak Reference 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/akerusoft/items/d8918bc4dbd2d873a99d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
MonoBehaviourCache.CreateInstance()
TestObject1.Awake() testObject2 id:-53294
TestObject1.Awake() testObject2:TestObject2 (My.TestObject2)
TestObject1.OnDestroy()
TestObject1.OnDestroy() testObject2:null
MonoBehaviourCache.SceneUnloaded() scene:Scene1
MonoBehaviourCache.SceneUnloaded() Unused object. InstanceID:-53294
장면 1
필드 2로 이동 후
Reference
이 문제에 관하여(Unity 시스템.Weak Reference 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/akerusoft/items/d8918bc4dbd2d873a99d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)