-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSceneObjectReference.cs
More file actions
155 lines (129 loc) · 4.42 KB
/
SceneObjectReference.cs
File metadata and controls
155 lines (129 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Cysharp.Threading.Tasks;
using Screenplay.Component;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace Screenplay
{
[Serializable, InlineProperty]
public struct SceneObjectReference<T> where T : Object
{
public string ScenePath => _genericRef.ScenePath;
[SerializeField, HideInInspector] private GenericSceneObjectReference _genericRef;
public GenericSceneObjectReference ToGeneric => _genericRef;
public guid Guid => _genericRef.Guid;
#if UNITY_EDITOR
public SceneObjectReference(GameObject obj)
{
_genericRef = new(obj);
}
public SceneObjectReference(UnityEngine.Component obj)
{
_genericRef = new(obj);
}
#endif
public bool Empty() => _genericRef.Empty();
public bool TryGet([MaybeNullWhen(false)] out T obj, out ReferenceState referenceState)
{
if (_genericRef.TryGet(out var abstractObj, out referenceState))
{
obj = (T)abstractObj;
return true;
}
obj = default;
return false;
}
public static implicit operator GenericSceneObjectReference(SceneObjectReference<T> value)
{
return value._genericRef;
}
public T GetNowOrThrow()
{
return _genericRef.TryGet(out var r, out var result) ? (T)r : throw new InvalidOperationException($"Could not get {ScenePath} {typeof(T)}: {result}");
}
public UniTask<T> GetAsync(Cancellation cancellation)
{
return _genericRef.GetAsync<T>(cancellation);
}
}
[Serializable]
public struct GenericSceneObjectReference : ISerializationCallbackReceiver
{
public string ScenePath => _scenePath;
[SerializeField, HideInInspector] private string _scenePath;
[SerializeField, HideInInspector] private guid _objId;
public guid Guid => _objId;
public bool Empty() => _objId == default;
public bool TryGet([MaybeNullWhen(false)] out Object obj, out ReferenceState referenceState)
{
if (Empty())
{
obj = default;
referenceState = ReferenceState.Empty;
return false;
}
if (ScreenplayReference.TryGetRef(_objId, out var abstractObj))
{
obj = abstractObj;
referenceState = ReferenceState.Success;
return true;
}
referenceState = ReferenceState.SceneUnloaded;
for (int i = 0; i < SceneManager.sceneCount; i++)
{
if (SceneManager.GetSceneAt(i).path == ScenePath)
{
referenceState = ReferenceState.SceneLoadedButNoRef;
break;
}
}
obj = default;
return false;
}
public UniTask<T> GetAsync<T>(Cancellation cancellation) where T : Object
{
return ScreenplayReference.GetAsync<T>(_objId, cancellation);
}
#if UNITY_EDITOR
[SerializeField, HideLabel] private UnityEditor.SceneAsset _sceneAsset;
public GenericSceneObjectReference(GameObject obj) : this(obj, obj, Component.ScreenplayReference.GetOrCreate(obj))
{
}
public GenericSceneObjectReference(UnityEngine.Component obj) : this(obj, obj.gameObject, Component.ScreenplayReference.GetOrCreate(obj))
{
}
private GenericSceneObjectReference(Object obj, GameObject go, guid objId)
{
_scenePath = go.scene.path;
_sceneAsset = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEditor.SceneAsset>(_scenePath);
_objId = objId;
}
#endif
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
// Make sure the path is always up-to-date
if (_sceneAsset != null)
_scenePath = UnityEditor.AssetDatabase.GetAssetPath(_sceneAsset);
#endif
}
public void OnAfterDeserialize()
{
}
public bool IsValid()
{
return _scenePath != null;
}
}
public enum ReferenceState
{
Empty,
SceneUnloaded,
SceneLoadedButNoRef,
Success,
}
}