├── .gitignore ├── Assets ├── CrossSceneReference │ ├── Editor.meta │ ├── Samples │ │ ├── LoadFirst.unity.meta │ │ ├── LoadSecond.unity.meta │ │ ├── TestCrossScene.cs.meta │ │ ├── LoadScenes.cs.meta │ │ ├── TestCrossScene.cs │ │ ├── LoadScenes.cs │ │ ├── LoadSecond.unity │ │ └── LoadFirst.unity │ ├── Runtime.meta │ ├── Samples.meta │ ├── Tests.meta │ ├── Tests │ │ ├── Editor.meta │ │ └── Editor │ │ │ ├── GuidReferenceTests.cs.meta │ │ │ └── GuidReferenceTests.cs │ ├── Runtime │ │ ├── GuidManager.cs.meta │ │ ├── GuidComponent.cs.meta │ │ ├── GuidReference.cs.meta │ │ ├── GuidReference.cs │ │ ├── GuidComponent.cs │ │ └── GuidManager.cs │ ├── Editor │ │ ├── GuidComponentDrawer.cs.meta │ │ ├── GuidReferenceDrawer.cs.meta │ │ ├── GuidComponentDrawer.cs │ │ └── GuidReferenceDrawer.cs │ └── Documentation~ │ │ └── guid-based-reference.md └── CrossSceneReference.meta ├── LICENSE.md ├── CONTRIBUTIONS.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Library/* 2 | ProjectSettings/* 3 | UnityPackageManager/* 4 | Temp/* 5 | Build/* 6 | *.csproj 7 | *.sln 8 | .vs/* 9 | Logs/Packages-Update.log 10 | Packages/manifest.json 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab3f0d3c87f4e4542b3fca67cd6ae5e8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8013f34f0b656684fbc03322c7682ed3 3 | folderAsset: yes 4 | timeCreated: 1523920636 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadFirst.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f8ba3c4c3bf19d4999033b50832272b 3 | timeCreated: 1524091778 4 | licenseType: Pro 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadSecond.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8acfd1b1a375f2049a2dde40d955ce3f 3 | timeCreated: 1524091841 4 | licenseType: Pro 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 020e5b1d051f1754498ff5a352de74dc 3 | folderAsset: yes 4 | timeCreated: 1528409386 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 104046076828f4d46812aeed0183ae79 3 | folderAsset: yes 4 | timeCreated: 1528409386 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Tests.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8181887cd9cd2ae4cb92941c5ab88958 3 | folderAsset: yes 4 | timeCreated: 1528409386 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Tests/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c37456657216ae548bdf77b7302f7e7d 3 | folderAsset: yes 4 | timeCreated: 1524696955 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a025fc98970524f4fafbe145be2d52d9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98bbc2c1e63e98543830eec78d976795 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidReference.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 061c5c53f1e3d044fbe53d54e6f5ceb9 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/TestCrossScene.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dac07e8eb76e66a4fa8c4fe45f186fc4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Editor/GuidComponentDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d391a6c68619db747b22b71468282c7f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Editor/GuidReferenceDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d2bca965b1349294cab5244279477c6d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadScenes.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1c3a067d9be6204c9e067023c1c768b 3 | timeCreated: 1524092328 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Tests/Editor/GuidReferenceTests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3f6a48c5939ae764d8166d49595c308d 3 | timeCreated: 1524168629 4 | licenseType: Pro 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Guid based Reference copyright © 2018 Unity Technologies ApS 2 | 3 | Licensed under the Unity Companion License for Unity-dependent projects--see [Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). 4 | 5 | Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. Please review the license for details on these and other terms and conditions. 6 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Editor/GuidComponentDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | [CustomEditor(typeof(GuidComponent))] 5 | public class GuidComponentDrawer : Editor 6 | { 7 | private GuidComponent guidComp; 8 | 9 | public override void OnInspectorGUI() 10 | { 11 | if (guidComp == null) 12 | { 13 | guidComp = (GuidComponent)target; 14 | } 15 | 16 | // Draw label 17 | EditorGUILayout.LabelField("Guid:", guidComp.GetGuid().ToString()); 18 | } 19 | } -------------------------------------------------------------------------------- /CONTRIBUTIONS.md: -------------------------------------------------------------------------------- 1 | # Contributions 2 | 3 | ## If you are interested in contributing, here are some ground rules: 4 | * ... Define guidelines & rules for what contributors need to know to successfully make Pull requests against your repo ... 5 | 6 | ## All contributions are subject to the [Unity Contribution Agreement(UCA)](https://unity3d.com/legal/licenses/Unity_Contribution_Agreement) 7 | By making a pull request, you are confirming agreement to the terms and conditions of the UCA, including that your Contributions are your original creation and that you have complete right and authority to make your Contributions. 8 | 9 | ## Once you have a change ready following these ground rules. Simply make a pull request in Github 10 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Documentation~/guid-based-reference.md: -------------------------------------------------------------------------------- 1 | Guid Based Reference 2 | 3 | Summary 4 | A component to give a Globaly Unique IDentifier (GUID) to a Game Object. 5 | This GUID can then be used to reference an object even if it is another Scene, not loaded yet, or otherwise not easy to directly reference. 6 | 7 | Maintainers 8 | William Armstrong williama@unity3d.com 9 | 10 | To Use: 11 | 12 | Add a GuidComponent to any object you want to be able to reference. 13 | 14 | In any code that needs to be able to reference objects by GUID, add a GuidReference field. 15 | 16 | GuidReference.gameObject will then return the GameObject if it is loaded, otherwise null. 17 | 18 | Look in the CrossSceneReference/SampleContent folder for example usage. 19 | 20 | Load up the LoadFirst scene, and then use the SceneLoader object to load 'LoadSecond' 21 | 22 | You should see the CrossSceneReferencer object find the CrossSceneTarget object, and set both of them to start spinning. 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Guid Based Reference 2 | 3 | License - Please see LICENSE.md in this repository 4 | 5 | Summary 6 | A component to give a Globaly Unique IDentifier (GUID) to a Game Object. 7 | This GUID can then be used to reference an object even if it is another Scene, not loaded yet, or otherwise not easy to directly reference. 8 | 9 | Maintainers 10 | William Armstrong williama@unity3d.com 11 | 12 | To Use: 13 | 14 | Add a GuidComponent to any object you want to be able to reference. 15 | 16 | In any code that needs to be able to reference objects by GUID, add a GuidReference field. 17 | 18 | GuidReference.gameObject will then return the GameObject if it is loaded, otherwise null. 19 | 20 | Look in the CrossSceneReference/SampleContent folder for example usage. 21 | 22 | Load up the LoadFirst scene, and then use the SceneLoader object to load 'LoadSecond' 23 | 24 | You should see the CrossSceneReferencer object find the CrossSceneTarget object, and set both of them to start spinning. 25 | 26 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/TestCrossScene.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Profiling; 5 | 6 | public class TestCrossScene : MonoBehaviour 7 | { 8 | 9 | public GuidReference crossSceneReference = new GuidReference(); 10 | private Renderer cachedRenderer; 11 | 12 | void Awake() 13 | { 14 | // set up a callback when the target is destroyed so we can remove references to the destroyed object 15 | crossSceneReference.OnGuidRemoved += ClearCache; 16 | } 17 | 18 | void Update () 19 | { 20 | // simple example looking for our reference and spinning both if we get one. 21 | // due to caching, this only causes a dictionary lookup the first time we call it, so you can comfortably poll. 22 | if (crossSceneReference.gameObject != null) 23 | { 24 | transform.Rotate(new Vector3(0, 1, 0), 10.0f * Time.deltaTime); 25 | 26 | if (cachedRenderer == null) 27 | { 28 | cachedRenderer = crossSceneReference.gameObject.GetComponent(); 29 | } 30 | 31 | if (cachedRenderer != null) 32 | { 33 | cachedRenderer.gameObject.transform.Rotate(new Vector3(0, 1, 0), 10.0f * Time.deltaTime, Space.World); 34 | } 35 | 36 | } 37 | 38 | // added a performance test if you want to see. Most cost is in the profiling tags. 39 | //TestPerformance(); 40 | } 41 | 42 | void ClearCache() 43 | { 44 | cachedRenderer = null; 45 | } 46 | 47 | void TestPerformance() 48 | { 49 | GameObject derefTest = null; 50 | 51 | for (int i = 0; i < 10000; ++i) 52 | { 53 | Profiler.BeginSample("Guid Resolution"); 54 | derefTest = crossSceneReference.gameObject; 55 | Profiler.EndSample(); 56 | } 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadScenes.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.SceneManagement; 5 | 6 | public class LoadScenes : MonoBehaviour 7 | { 8 | [System.Serializable] 9 | public struct SceneInfo 10 | { 11 | public string name; 12 | public bool shouldLoad; 13 | } 14 | 15 | public List scenes = new List(); 16 | 17 | // Update is called once per frame 18 | void Update () 19 | { 20 | foreach( var info in scenes ) 21 | { 22 | Scene scene = SceneManager.GetSceneByName(info.name); 23 | 24 | if (info.shouldLoad && !scene.isLoaded) 25 | { 26 | SceneManager.LoadScene(info.name, LoadSceneMode.Additive); 27 | } 28 | 29 | if (!info.shouldLoad && scene.isLoaded) 30 | { 31 | SceneManager.UnloadSceneAsync(scene); 32 | } 33 | } 34 | } 35 | 36 | // a little User Interface 37 | private void OnGUI() 38 | { 39 | // this code is a great example of how NOT to write Unity code 40 | 41 | Vector2 padding = new Vector2(5.0f, 5.0f); 42 | Vector2 buttonSize = new Vector2(150.0f, 50.0f); 43 | Rect buttonPosition = new Rect(padding, buttonSize); 44 | 45 | for ( int i = 0; i < scenes.Count; ++i ) 46 | { 47 | // PER FRAME ALLOCATION HERE 48 | string buttonText = scenes[i].name; 49 | buttonText += scenes[i].shouldLoad ? " : Unload" : " : Load"; 50 | 51 | if (GUI.Button(buttonPosition, buttonText)) 52 | { 53 | // UGH! Lists mean I can't modify scenes[i].shouldLoad directly! I guess make an awkward copy and then set =/ 54 | SceneInfo newInfo = scenes[i]; 55 | newInfo.shouldLoad = !newInfo.shouldLoad; 56 | scenes[i] = newInfo; 57 | } 58 | 59 | buttonPosition.y += buttonSize.y + padding.y; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Tests/Editor/GuidReferenceTests.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.TestTools; 3 | using NUnit.Framework; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEditor; 7 | 8 | public class GuidReferenceTests 9 | { 10 | // Tests - make a new GUID 11 | // duplicate it 12 | // make it a prefab 13 | // delete it 14 | // reference it 15 | // dereference it 16 | 17 | string prefabPath; 18 | GuidComponent guidBase; 19 | GameObject prefab; 20 | GuidComponent guidPrefab; 21 | 22 | [OneTimeSetUp] 23 | public void Setup() 24 | { 25 | prefabPath = "Assets/TemporaryTestGuid.prefab"; 26 | 27 | guidBase = CreateNewGuid(); 28 | prefab = PrefabUtility.CreatePrefab(prefabPath, guidBase.gameObject); 29 | 30 | guidPrefab = prefab.GetComponent(); 31 | } 32 | 33 | public GuidComponent CreateNewGuid() 34 | { 35 | GameObject newGO = new GameObject("GuidTestGO"); 36 | return newGO.AddComponent(); 37 | } 38 | 39 | [UnityTest] 40 | public IEnumerator GuidCreation() 41 | { 42 | GuidComponent guid1 = guidBase; 43 | GuidComponent guid2 = CreateNewGuid(); 44 | 45 | Assert.AreNotEqual(guid1.GetGuid(), guid2.GetGuid()); 46 | 47 | yield return null; 48 | } 49 | 50 | [UnityTest] 51 | public IEnumerator GuidDuplication() 52 | { 53 | LogAssert.Expect(LogType.Warning, "Guid Collision Detected while creating GuidTestGO(Clone).\nAssigning new Guid."); 54 | 55 | GuidComponent clone = GameObject.Instantiate(guidBase); 56 | 57 | Assert.AreNotEqual(guidBase.GetGuid(), clone.GetGuid()); 58 | 59 | yield return null; 60 | } 61 | 62 | [UnityTest] 63 | public IEnumerator GuidPrefab() 64 | { 65 | Assert.AreNotEqual(guidBase.GetGuid(), guidPrefab.GetGuid()); 66 | Assert.AreEqual(guidPrefab.GetGuid(), System.Guid.Empty); 67 | 68 | yield return null; 69 | } 70 | 71 | [UnityTest] 72 | public IEnumerator GuidPrefabInstance() 73 | { 74 | GuidComponent instance = GameObject.Instantiate(guidPrefab); 75 | Assert.AreNotEqual(guidBase.GetGuid(), instance.GetGuid()); 76 | Assert.AreNotEqual(instance.GetGuid(), guidPrefab.GetGuid()); 77 | 78 | yield return null; 79 | } 80 | 81 | [UnityTest] 82 | public IEnumerator GuidValidReference() 83 | { 84 | GuidReference reference = new GuidReference(guidBase); 85 | Assert.AreEqual(reference.gameObject, guidBase.gameObject); 86 | 87 | yield return null; 88 | } 89 | 90 | [UnityTest] 91 | public IEnumerator GuidInvalidReference() 92 | { 93 | GuidComponent newGuid = CreateNewGuid(); 94 | GuidReference reference = new GuidReference(newGuid); 95 | Object.DestroyImmediate(newGuid); 96 | 97 | Assert.IsNull(reference.gameObject); 98 | 99 | yield return null; 100 | } 101 | 102 | [OneTimeTearDown] 103 | public void TearDown() 104 | { 105 | AssetDatabase.DeleteAsset(prefabPath); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidReference.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | 4 | #if UNITY_EDITOR 5 | using UnityEditor; 6 | #endif 7 | 8 | // This call is the type used by any other code to hold a reference to an object by GUID 9 | // If the target object is loaded, it will be returned, otherwise, NULL will be returned 10 | // This always works in Game Objects, so calling code will need to use GetComponent<> 11 | // or other methods to track down the specific objects need by any given system 12 | 13 | // Ideally this would be a struct, but we need the ISerializationCallbackReciever 14 | [System.Serializable] 15 | public class GuidReference : ISerializationCallbackReceiver 16 | { 17 | // cache the referenced Game Object if we find one for performance 18 | private GameObject cachedReference; 19 | private bool isCacheSet; 20 | 21 | // store our GUID in a form that Unity can save 22 | [SerializeField] 23 | private byte[] serializedGuid; 24 | private System.Guid guid; 25 | 26 | #if UNITY_EDITOR 27 | // decorate with some extra info in Editor so we can inform a user of what that GUID means 28 | [SerializeField] 29 | private string cachedName; 30 | [SerializeField] 31 | private SceneAsset cachedScene; 32 | #endif 33 | 34 | // Set up events to let users register to cleanup their own cached references on destroy or to cache off values 35 | public event Action OnGuidAdded = delegate (GameObject go) { }; 36 | public event Action OnGuidRemoved = delegate() { }; 37 | 38 | // create concrete delegates to avoid boxing. 39 | // When called 10,000 times, boxing would allocate ~1MB of GC Memory 40 | private Action addDelegate; 41 | private Action removeDelegate; 42 | 43 | // optimized accessor, and ideally the only code you ever call on this class 44 | public GameObject gameObject 45 | { 46 | get 47 | { 48 | if( isCacheSet ) 49 | { 50 | return cachedReference; 51 | } 52 | 53 | cachedReference = GuidManager.ResolveGuid( guid, addDelegate, removeDelegate ); 54 | isCacheSet = true; 55 | return cachedReference; 56 | } 57 | 58 | private set {} 59 | } 60 | 61 | public GuidReference() { } 62 | 63 | public GuidReference(GuidComponent target) 64 | { 65 | guid = target.GetGuid(); 66 | } 67 | 68 | private void GuidAdded(GameObject go) 69 | { 70 | cachedReference = go; 71 | OnGuidAdded(go); 72 | } 73 | 74 | private void GuidRemoved() 75 | { 76 | cachedReference = null; 77 | isCacheSet = false; 78 | OnGuidRemoved(); 79 | } 80 | 81 | //convert system guid to a format unity likes to work with 82 | public void OnBeforeSerialize() 83 | { 84 | serializedGuid = guid.ToByteArray(); 85 | } 86 | 87 | // convert from byte array to system guid and reset state 88 | public void OnAfterDeserialize() 89 | { 90 | cachedReference = null; 91 | isCacheSet = false; 92 | if (serializedGuid == null || serializedGuid.Length != 16) 93 | { 94 | serializedGuid = new byte[16]; 95 | } 96 | guid = new System.Guid(serializedGuid); 97 | addDelegate = GuidAdded; 98 | removeDelegate = GuidRemoved; 99 | 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Editor/GuidReferenceDrawer.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | // Using a property drawer to allow any class to have a field of type GuidRefernce and still get good UX 5 | // If you are writing your own inspector for a class that uses a GuidReference, drawing it with 6 | // EditorLayout.PropertyField(prop) or similar will get this to show up automatically 7 | [CustomPropertyDrawer(typeof(GuidReference))] 8 | public class GuidReferenceDrawer : PropertyDrawer 9 | { 10 | SerializedProperty guidProp; 11 | SerializedProperty sceneProp; 12 | SerializedProperty nameProp; 13 | 14 | // cache off GUI content to avoid creating garbage every frame in editor 15 | GUIContent sceneLabel = new GUIContent("Containing Scene", "The target object is expected in this scene asset."); 16 | GUIContent clearButtonGUI = new GUIContent("Clear", "Remove Cross Scene Reference"); 17 | 18 | // add an extra line to display source scene for targets 19 | public override float GetPropertyHeight(SerializedProperty property, GUIContent label) 20 | { 21 | return base.GetPropertyHeight(property, label) + EditorGUIUtility.singleLineHeight; 22 | } 23 | 24 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) 25 | { 26 | 27 | guidProp = property.FindPropertyRelative("serializedGuid"); 28 | nameProp = property.FindPropertyRelative("cachedName"); 29 | sceneProp = property.FindPropertyRelative("cachedScene"); 30 | 31 | // Using BeginProperty / EndProperty on the parent property means that 32 | // prefab override logic works on the entire property. 33 | EditorGUI.BeginProperty(position, label, property); 34 | 35 | position.height = EditorGUIUtility.singleLineHeight; 36 | 37 | // Draw prefix label, returning the new rect we can draw in 38 | var guidCompPosition = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label); 39 | 40 | System.Guid currentGuid; 41 | GameObject currentGO = null; 42 | 43 | // working with array properties is a bit unwieldy 44 | // you have to get the property at each index manually 45 | byte[] byteArray = new byte[16]; 46 | int arraySize = guidProp.arraySize; 47 | for( int i = 0; i < arraySize; ++i ) 48 | { 49 | var byteProp = guidProp.GetArrayElementAtIndex(i); 50 | byteArray[i] = (byte)byteProp.intValue; 51 | } 52 | 53 | currentGuid = new System.Guid(byteArray); 54 | currentGO = GuidManager.ResolveGuid(currentGuid); 55 | GuidComponent currentGuidComponent = currentGO != null ? currentGO.GetComponent() : null; 56 | 57 | GuidComponent component = null; 58 | 59 | if (currentGuid != System.Guid.Empty && currentGuidComponent == null) 60 | { 61 | // if our reference is set, but the target isn't loaded, we display the target and the scene it is in, and provide a way to clear the reference 62 | float buttonWidth = 55.0f; 63 | 64 | guidCompPosition.xMax -= buttonWidth; 65 | 66 | bool guiEnabled = GUI.enabled; 67 | GUI.enabled = false; 68 | EditorGUI.LabelField(guidCompPosition, new GUIContent(nameProp.stringValue, "Target GameObject is not currently loaded."), EditorStyles.objectField); 69 | GUI.enabled = guiEnabled; 70 | 71 | Rect clearButtonRect = new Rect(guidCompPosition); 72 | clearButtonRect.xMin = guidCompPosition.xMax; 73 | clearButtonRect.xMax += buttonWidth; 74 | 75 | if (GUI.Button(clearButtonRect, clearButtonGUI, EditorStyles.miniButton)) 76 | { 77 | ClearPreviousGuid(); 78 | } 79 | } 80 | else 81 | { 82 | // if our object is loaded, we can simply use an object field directly 83 | component = EditorGUI.ObjectField(guidCompPosition, currentGuidComponent, typeof(GuidComponent), true) as GuidComponent; 84 | } 85 | 86 | if (currentGuidComponent != null && component == null) 87 | { 88 | ClearPreviousGuid(); 89 | } 90 | 91 | // if we have a valid reference, draw the scene name of the scene it lives in so users can find it 92 | if (component != null) 93 | { 94 | nameProp.stringValue = component.name; 95 | string scenePath = component.gameObject.scene.path; 96 | sceneProp.objectReferenceValue = AssetDatabase.LoadAssetAtPath(scenePath); 97 | 98 | // only update the GUID Prop if something changed. This fixes multi-edit on GUID References 99 | if (component != currentGuidComponent) 100 | { 101 | byteArray = component.GetGuid().ToByteArray(); 102 | arraySize = guidProp.arraySize; 103 | for (int i = 0; i < arraySize; ++i) 104 | { 105 | var byteProp = guidProp.GetArrayElementAtIndex(i); 106 | byteProp.intValue = byteArray[i]; 107 | } 108 | } 109 | } 110 | 111 | EditorGUI.indentLevel++; 112 | position.y += EditorGUIUtility.singleLineHeight; 113 | bool cachedGUIState = GUI.enabled; 114 | GUI.enabled = false; 115 | EditorGUI.ObjectField(position, sceneLabel, sceneProp.objectReferenceValue, typeof(SceneAsset), false); 116 | GUI.enabled = cachedGUIState; 117 | EditorGUI.indentLevel--; 118 | 119 | EditorGUI.EndProperty(); 120 | } 121 | 122 | void ClearPreviousGuid() 123 | { 124 | nameProp.stringValue = string.Empty; 125 | sceneProp.objectReferenceValue = null; 126 | 127 | int arraySize = guidProp.arraySize; 128 | for (int i = 0; i < arraySize; ++i) 129 | { 130 | var byteProp = guidProp.GetArrayElementAtIndex(i); 131 | byteProp.intValue = 0; 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidComponent.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | #if UNITY_EDITOR 6 | using UnityEditor; 7 | using UnityEditor.SceneManagement; 8 | using UnityEditor.Experimental.SceneManagement; 9 | #endif 10 | 11 | // This component gives a GameObject a stable, non-replicatable Globally Unique IDentifier. 12 | // It can be used to reference a specific instance of an object no matter where it is. 13 | // This can also be used for other systems, such as Save/Load game 14 | [ExecuteInEditMode, DisallowMultipleComponent] 15 | public class GuidComponent : MonoBehaviour, ISerializationCallbackReceiver 16 | { 17 | // System guid we use for comparison and generation 18 | System.Guid guid = System.Guid.Empty; 19 | 20 | // Unity's serialization system doesn't know about System.Guid, so we convert to a byte array 21 | // Fun fact, we tried using strings at first, but that allocated memory and was twice as slow 22 | [SerializeField] 23 | private byte[] serializedGuid; 24 | 25 | 26 | public bool IsGuidAssigned() 27 | { 28 | return guid != System.Guid.Empty; 29 | } 30 | 31 | 32 | // When de-serializing or creating this component, we want to either restore our serialized GUID 33 | // or create a new one. 34 | void CreateGuid() 35 | { 36 | // if our serialized data is invalid, then we are a new object and need a new GUID 37 | if (serializedGuid == null || serializedGuid.Length != 16) 38 | { 39 | #if UNITY_EDITOR 40 | // if in editor, make sure we aren't a prefab of some kind 41 | if (IsAssetOnDisk()) 42 | { 43 | return; 44 | } 45 | Undo.RecordObject(this, "Added GUID"); 46 | #endif 47 | guid = System.Guid.NewGuid(); 48 | serializedGuid = guid.ToByteArray(); 49 | 50 | #if UNITY_EDITOR 51 | // If we are creating a new GUID for a prefab instance of a prefab, but we have somehow lost our prefab connection 52 | // force a save of the modified prefab instance properties 53 | if (PrefabUtility.IsPartOfNonAssetPrefabInstance(this)) 54 | { 55 | PrefabUtility.RecordPrefabInstancePropertyModifications(this); 56 | } 57 | #endif 58 | } 59 | else if (guid == System.Guid.Empty) 60 | { 61 | // otherwise, we should set our system guid to our serialized guid 62 | guid = new System.Guid(serializedGuid); 63 | } 64 | 65 | // register with the GUID Manager so that other components can access this 66 | if (guid != System.Guid.Empty) 67 | { 68 | if (!GuidManager.Add(this)) 69 | { 70 | // if registration fails, we probably have a duplicate or invalid GUID, get us a new one. 71 | serializedGuid = null; 72 | guid = System.Guid.Empty; 73 | CreateGuid(); 74 | } 75 | } 76 | } 77 | 78 | #if UNITY_EDITOR 79 | private bool IsEditingInPrefabMode() 80 | { 81 | if (EditorUtility.IsPersistent(this)) 82 | { 83 | // if the game object is stored on disk, it is a prefab of some kind, despite not returning true for IsPartOfPrefabAsset =/ 84 | return true; 85 | } 86 | else 87 | { 88 | // If the GameObject is not persistent let's determine which stage we are in first because getting Prefab info depends on it 89 | var mainStage = StageUtility.GetMainStageHandle(); 90 | var currentStage = StageUtility.GetStageHandle(gameObject); 91 | if (currentStage != mainStage) 92 | { 93 | var prefabStage = PrefabStageUtility.GetPrefabStage(gameObject); 94 | if (prefabStage != null) 95 | { 96 | return true; 97 | } 98 | } 99 | } 100 | return false; 101 | } 102 | 103 | private bool IsAssetOnDisk() 104 | { 105 | return PrefabUtility.IsPartOfPrefabAsset(this) || IsEditingInPrefabMode(); 106 | } 107 | #endif 108 | 109 | // We cannot allow a GUID to be saved into a prefab, and we need to convert to byte[] 110 | public void OnBeforeSerialize() 111 | { 112 | #if UNITY_EDITOR 113 | // This lets us detect if we are a prefab instance or a prefab asset. 114 | // A prefab asset cannot contain a GUID since it would then be duplicated when instanced. 115 | if (IsAssetOnDisk()) 116 | { 117 | serializedGuid = null; 118 | guid = System.Guid.Empty; 119 | } 120 | else 121 | #endif 122 | { 123 | if (guid != System.Guid.Empty) 124 | { 125 | serializedGuid = guid.ToByteArray(); 126 | } 127 | } 128 | } 129 | 130 | // On load, we can go head a restore our system guid for later use 131 | public void OnAfterDeserialize() 132 | { 133 | if (serializedGuid != null && serializedGuid.Length == 16) 134 | { 135 | guid = new System.Guid(serializedGuid); 136 | } 137 | } 138 | 139 | void Awake() 140 | { 141 | CreateGuid(); 142 | } 143 | 144 | void OnValidate() 145 | { 146 | #if UNITY_EDITOR 147 | // similar to on Serialize, but gets called on Copying a Component or Applying a Prefab 148 | // at a time that lets us detect what we are 149 | if (IsAssetOnDisk()) 150 | { 151 | serializedGuid = null; 152 | guid = System.Guid.Empty; 153 | } 154 | else 155 | #endif 156 | { 157 | CreateGuid(); 158 | } 159 | } 160 | 161 | // Never return an invalid GUID 162 | public System.Guid GetGuid() 163 | { 164 | if (guid == System.Guid.Empty && serializedGuid != null && serializedGuid.Length == 16) 165 | { 166 | guid = new System.Guid(serializedGuid); 167 | } 168 | 169 | return guid; 170 | } 171 | 172 | // let the manager know we are gone, so other objects no longer find this 173 | public void OnDestroy() 174 | { 175 | GuidManager.Remove(guid); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Runtime/GuidManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using System; 5 | 6 | // Class to handle registering and accessing objects by GUID 7 | public class GuidManager 8 | { 9 | // for each GUID we need to know the Game Object it references 10 | // and an event to store all the callbacks that need to know when it is destroyed 11 | private struct GuidInfo 12 | { 13 | public GameObject go; 14 | 15 | public event Action OnAdd; 16 | public event Action OnRemove; 17 | 18 | public GuidInfo(GuidComponent comp) 19 | { 20 | go = comp.gameObject; 21 | OnRemove = null; 22 | OnAdd = null; 23 | } 24 | 25 | public void HandleAddCallback() 26 | { 27 | if (OnAdd != null) 28 | { 29 | OnAdd(go); 30 | } 31 | } 32 | 33 | public void HandleRemoveCallback() 34 | { 35 | if (OnRemove != null) 36 | { 37 | OnRemove(); 38 | } 39 | } 40 | } 41 | 42 | // Singleton interface 43 | static GuidManager Instance; 44 | 45 | // All the public API is static so you need not worry about creating an instance 46 | public static bool Add(GuidComponent guidComponent ) 47 | { 48 | if (Instance == null) 49 | { 50 | Instance = new GuidManager(); 51 | } 52 | 53 | return Instance.InternalAdd(guidComponent); 54 | } 55 | 56 | public static void Remove(System.Guid guid) 57 | { 58 | if (Instance == null) 59 | { 60 | Instance = new GuidManager(); 61 | } 62 | 63 | Instance.InternalRemove(guid); 64 | } 65 | public static GameObject ResolveGuid(System.Guid guid, Action onAddCallback, Action onRemoveCallback) 66 | { 67 | if (Instance == null) 68 | { 69 | Instance = new GuidManager(); 70 | } 71 | 72 | return Instance.ResolveGuidInternal(guid, onAddCallback, onRemoveCallback); 73 | } 74 | 75 | public static GameObject ResolveGuid(System.Guid guid, Action onDestroyCallback) 76 | { 77 | if (Instance == null) 78 | { 79 | Instance = new GuidManager(); 80 | } 81 | 82 | return Instance.ResolveGuidInternal(guid, null, onDestroyCallback); 83 | } 84 | 85 | public static GameObject ResolveGuid(System.Guid guid) 86 | { 87 | if (Instance == null) 88 | { 89 | Instance = new GuidManager(); 90 | } 91 | return Instance.ResolveGuidInternal(guid, null, null); 92 | } 93 | 94 | // instance data 95 | private Dictionary guidToObjectMap; 96 | 97 | private GuidManager() 98 | { 99 | guidToObjectMap = new Dictionary(); 100 | } 101 | 102 | private bool InternalAdd(GuidComponent guidComponent) 103 | { 104 | Guid guid = guidComponent.GetGuid(); 105 | 106 | GuidInfo info = new GuidInfo(guidComponent); 107 | 108 | if (!guidToObjectMap.ContainsKey(guid)) 109 | { 110 | guidToObjectMap.Add(guid, info); 111 | return true; 112 | } 113 | 114 | GuidInfo existingInfo = guidToObjectMap[guid]; 115 | if ( existingInfo.go != null && existingInfo.go != guidComponent.gameObject ) 116 | { 117 | // normally, a duplicate GUID is a big problem, means you won't necessarily be referencing what you expect 118 | if (Application.isPlaying) 119 | { 120 | Debug.AssertFormat(false, guidComponent, "Guid Collision Detected between {0} and {1}.\nAssigning new Guid. Consider tracking runtime instances using a direct reference or other method.", (guidToObjectMap[guid].go != null ? guidToObjectMap[guid].go.name : "NULL"), (guidComponent != null ? guidComponent.name : "NULL")); 121 | } 122 | else 123 | { 124 | // however, at editor time, copying an object with a GUID will duplicate the GUID resulting in a collision and repair. 125 | // we warn about this just for pedantry reasons, and so you can detect if you are unexpectedly copying these components 126 | Debug.LogWarningFormat(guidComponent, "Guid Collision Detected while creating {0}.\nAssigning new Guid.", (guidComponent != null ? guidComponent.name : "NULL")); 127 | } 128 | return false; 129 | } 130 | 131 | // if we already tried to find this GUID, but haven't set the game object to anything specific, copy any OnAdd callbacks then call them 132 | existingInfo.go = info.go; 133 | existingInfo.HandleAddCallback(); 134 | guidToObjectMap[guid] = existingInfo; 135 | return true; 136 | } 137 | 138 | private void InternalRemove(System.Guid guid) 139 | { 140 | GuidInfo info; 141 | if (guidToObjectMap.TryGetValue(guid, out info)) 142 | { 143 | // trigger all the destroy delegates that have registered 144 | info.HandleRemoveCallback(); 145 | } 146 | 147 | guidToObjectMap.Remove(guid); 148 | } 149 | 150 | // nice easy api to find a GUID, and if it works, register an on destroy callback 151 | // this should be used to register functions to cleanup any data you cache on finding 152 | // your target. Otherwise, you might keep components in memory by referencing them 153 | private GameObject ResolveGuidInternal(System.Guid guid, Action onAddCallback, Action onRemoveCallback) 154 | { 155 | GuidInfo info; 156 | if (guidToObjectMap.TryGetValue(guid, out info)) 157 | { 158 | if (onAddCallback != null) 159 | { 160 | info.OnAdd += onAddCallback; 161 | } 162 | 163 | if (onRemoveCallback != null) 164 | { 165 | info.OnRemove += onRemoveCallback; 166 | } 167 | guidToObjectMap[guid] = info; 168 | return info.go; 169 | } 170 | 171 | if (onAddCallback != null) 172 | { 173 | info.OnAdd += onAddCallback; 174 | } 175 | 176 | if (onRemoveCallback != null) 177 | { 178 | info.OnRemove += onRemoveCallback; 179 | } 180 | 181 | guidToObjectMap.Add(guid, info); 182 | 183 | return null; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadSecond.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 1 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 1 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &959225784 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 5 122 | m_Component: 123 | - component: {fileID: 959225788} 124 | - component: {fileID: 959225787} 125 | - component: {fileID: 959225786} 126 | - component: {fileID: 959225785} 127 | - component: {fileID: 959225789} 128 | m_Layer: 0 129 | m_Name: CrossSceneTarget 130 | m_TagString: Untagged 131 | m_Icon: {fileID: 0} 132 | m_NavMeshLayer: 0 133 | m_StaticEditorFlags: 0 134 | m_IsActive: 1 135 | --- !u!23 &959225785 136 | MeshRenderer: 137 | m_ObjectHideFlags: 0 138 | m_PrefabParentObject: {fileID: 0} 139 | m_PrefabInternal: {fileID: 0} 140 | m_GameObject: {fileID: 959225784} 141 | m_Enabled: 1 142 | m_CastShadows: 1 143 | m_ReceiveShadows: 1 144 | m_DynamicOccludee: 1 145 | m_MotionVectors: 1 146 | m_LightProbeUsage: 1 147 | m_ReflectionProbeUsage: 1 148 | m_Materials: 149 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 150 | m_StaticBatchInfo: 151 | firstSubMesh: 0 152 | subMeshCount: 0 153 | m_StaticBatchRoot: {fileID: 0} 154 | m_ProbeAnchor: {fileID: 0} 155 | m_LightProbeVolumeOverride: {fileID: 0} 156 | m_ScaleInLightmap: 1 157 | m_PreserveUVs: 1 158 | m_IgnoreNormalsForChartDetection: 0 159 | m_ImportantGI: 0 160 | m_StitchLightmapSeams: 0 161 | m_SelectedEditorRenderState: 3 162 | m_MinimumChartSize: 4 163 | m_AutoUVMaxDistance: 0.5 164 | m_AutoUVMaxAngle: 89 165 | m_LightmapParameters: {fileID: 0} 166 | m_SortingLayerID: 0 167 | m_SortingLayer: 0 168 | m_SortingOrder: 0 169 | --- !u!136 &959225786 170 | CapsuleCollider: 171 | m_ObjectHideFlags: 0 172 | m_PrefabParentObject: {fileID: 0} 173 | m_PrefabInternal: {fileID: 0} 174 | m_GameObject: {fileID: 959225784} 175 | m_Material: {fileID: 0} 176 | m_IsTrigger: 0 177 | m_Enabled: 1 178 | m_Radius: 0.5 179 | m_Height: 2 180 | m_Direction: 1 181 | m_Center: {x: 0, y: 0, z: 0} 182 | --- !u!33 &959225787 183 | MeshFilter: 184 | m_ObjectHideFlags: 0 185 | m_PrefabParentObject: {fileID: 0} 186 | m_PrefabInternal: {fileID: 0} 187 | m_GameObject: {fileID: 959225784} 188 | m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0} 189 | --- !u!4 &959225788 190 | Transform: 191 | m_ObjectHideFlags: 0 192 | m_PrefabParentObject: {fileID: 0} 193 | m_PrefabInternal: {fileID: 0} 194 | m_GameObject: {fileID: 959225784} 195 | m_LocalRotation: {x: 0.20633711, y: 0.112342596, z: 0.102588624, w: 0.96658146} 196 | m_LocalPosition: {x: -0.273, y: 1.112, z: -0.035} 197 | m_LocalScale: {x: 0.6114925, y: 0.5617244, z: 0.6114929} 198 | m_Children: [] 199 | m_Father: {fileID: 0} 200 | m_RootOrder: 0 201 | m_LocalEulerAnglesHint: {x: 22.076, y: 16.263, z: 15.31} 202 | --- !u!114 &959225789 203 | MonoBehaviour: 204 | m_ObjectHideFlags: 0 205 | m_PrefabParentObject: {fileID: 0} 206 | m_PrefabInternal: {fileID: 0} 207 | m_GameObject: {fileID: 959225784} 208 | m_Enabled: 1 209 | m_EditorHideFlags: 0 210 | m_Script: {fileID: 11500000, guid: 98bbc2c1e63e98543830eec78d976795, type: 3} 211 | m_Name: 212 | m_EditorClassIdentifier: 213 | serializedGuid: f60547967b8a894b859818a7477a708c 214 | -------------------------------------------------------------------------------- /Assets/CrossSceneReference/Samples/LoadFirst.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 1 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 1 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &690392693 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 5 122 | m_Component: 123 | - component: {fileID: 690392695} 124 | - component: {fileID: 690392694} 125 | m_Layer: 0 126 | m_Name: SceneLoader 127 | m_TagString: Untagged 128 | m_Icon: {fileID: 0} 129 | m_NavMeshLayer: 0 130 | m_StaticEditorFlags: 0 131 | m_IsActive: 1 132 | --- !u!114 &690392694 133 | MonoBehaviour: 134 | m_ObjectHideFlags: 0 135 | m_PrefabParentObject: {fileID: 0} 136 | m_PrefabInternal: {fileID: 0} 137 | m_GameObject: {fileID: 690392693} 138 | m_Enabled: 1 139 | m_EditorHideFlags: 0 140 | m_Script: {fileID: 11500000, guid: f1c3a067d9be6204c9e067023c1c768b, type: 3} 141 | m_Name: 142 | m_EditorClassIdentifier: 143 | scenes: 144 | - name: LoadSecond 145 | shouldLoad: 0 146 | --- !u!4 &690392695 147 | Transform: 148 | m_ObjectHideFlags: 0 149 | m_PrefabParentObject: {fileID: 0} 150 | m_PrefabInternal: {fileID: 0} 151 | m_GameObject: {fileID: 690392693} 152 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 153 | m_LocalPosition: {x: 0.9354887, y: 1.5564613, z: 0.030759811} 154 | m_LocalScale: {x: 1, y: 1, z: 1} 155 | m_Children: [] 156 | m_Father: {fileID: 0} 157 | m_RootOrder: 4 158 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 159 | --- !u!1 &811793634 160 | GameObject: 161 | m_ObjectHideFlags: 0 162 | m_PrefabParentObject: {fileID: 0} 163 | m_PrefabInternal: {fileID: 0} 164 | serializedVersion: 5 165 | m_Component: 166 | - component: {fileID: 811793638} 167 | - component: {fileID: 811793637} 168 | - component: {fileID: 811793635} 169 | m_Layer: 0 170 | m_Name: Main Camera 171 | m_TagString: MainCamera 172 | m_Icon: {fileID: 0} 173 | m_NavMeshLayer: 0 174 | m_StaticEditorFlags: 0 175 | m_IsActive: 1 176 | --- !u!81 &811793635 177 | AudioListener: 178 | m_ObjectHideFlags: 0 179 | m_PrefabParentObject: {fileID: 0} 180 | m_PrefabInternal: {fileID: 0} 181 | m_GameObject: {fileID: 811793634} 182 | m_Enabled: 1 183 | --- !u!20 &811793637 184 | Camera: 185 | m_ObjectHideFlags: 0 186 | m_PrefabParentObject: {fileID: 0} 187 | m_PrefabInternal: {fileID: 0} 188 | m_GameObject: {fileID: 811793634} 189 | m_Enabled: 1 190 | serializedVersion: 2 191 | m_ClearFlags: 1 192 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 193 | m_NormalizedViewPortRect: 194 | serializedVersion: 2 195 | x: 0 196 | y: 0 197 | width: 1 198 | height: 1 199 | near clip plane: 0.3 200 | far clip plane: 1000 201 | field of view: 60 202 | orthographic: 0 203 | orthographic size: 5 204 | m_Depth: -1 205 | m_CullingMask: 206 | serializedVersion: 2 207 | m_Bits: 4294967295 208 | m_RenderingPath: -1 209 | m_TargetTexture: {fileID: 0} 210 | m_TargetDisplay: 0 211 | m_TargetEye: 3 212 | m_HDR: 1 213 | m_AllowMSAA: 1 214 | m_AllowDynamicResolution: 0 215 | m_ForceIntoRT: 0 216 | m_OcclusionCulling: 1 217 | m_StereoConvergence: 10 218 | m_StereoSeparation: 0.022 219 | --- !u!4 &811793638 220 | Transform: 221 | m_ObjectHideFlags: 0 222 | m_PrefabParentObject: {fileID: 0} 223 | m_PrefabInternal: {fileID: 0} 224 | m_GameObject: {fileID: 811793634} 225 | m_LocalRotation: {x: -0.079268835, y: 0.85997003, z: -0.14082073, w: -0.4840843} 226 | m_LocalPosition: {x: 3.117961, y: 1.4224658, z: 2.4359696} 227 | m_LocalScale: {x: 1, y: 1, z: 1} 228 | m_Children: [] 229 | m_Father: {fileID: 0} 230 | m_RootOrder: 0 231 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 232 | --- !u!1 &959225784 233 | GameObject: 234 | m_ObjectHideFlags: 0 235 | m_PrefabParentObject: {fileID: 0} 236 | m_PrefabInternal: {fileID: 0} 237 | serializedVersion: 5 238 | m_Component: 239 | - component: {fileID: 959225789} 240 | - component: {fileID: 959225788} 241 | - component: {fileID: 959225787} 242 | - component: {fileID: 959225786} 243 | - component: {fileID: 959225785} 244 | m_Layer: 0 245 | m_Name: CrossSceneReferencer 246 | m_TagString: Untagged 247 | m_Icon: {fileID: 0} 248 | m_NavMeshLayer: 0 249 | m_StaticEditorFlags: 0 250 | m_IsActive: 1 251 | --- !u!114 &959225785 252 | MonoBehaviour: 253 | m_ObjectHideFlags: 0 254 | m_PrefabParentObject: {fileID: 0} 255 | m_PrefabInternal: {fileID: 0} 256 | m_GameObject: {fileID: 959225784} 257 | m_Enabled: 1 258 | m_EditorHideFlags: 0 259 | m_Script: {fileID: 11500000, guid: dac07e8eb76e66a4fa8c4fe45f186fc4, type: 3} 260 | m_Name: 261 | m_EditorClassIdentifier: 262 | crossSceneReference: 263 | serializedGuid: f60547967b8a894b859818a7477a708c 264 | cachedName: CrossSceneTarget 265 | cachedScene: {fileID: 102900000, guid: 8acfd1b1a375f2049a2dde40d955ce3f, type: 3} 266 | --- !u!23 &959225786 267 | MeshRenderer: 268 | m_ObjectHideFlags: 0 269 | m_PrefabParentObject: {fileID: 0} 270 | m_PrefabInternal: {fileID: 0} 271 | m_GameObject: {fileID: 959225784} 272 | m_Enabled: 1 273 | m_CastShadows: 1 274 | m_ReceiveShadows: 1 275 | m_DynamicOccludee: 1 276 | m_MotionVectors: 1 277 | m_LightProbeUsage: 1 278 | m_ReflectionProbeUsage: 1 279 | m_Materials: 280 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 281 | m_StaticBatchInfo: 282 | firstSubMesh: 0 283 | subMeshCount: 0 284 | m_StaticBatchRoot: {fileID: 0} 285 | m_ProbeAnchor: {fileID: 0} 286 | m_LightProbeVolumeOverride: {fileID: 0} 287 | m_ScaleInLightmap: 1 288 | m_PreserveUVs: 1 289 | m_IgnoreNormalsForChartDetection: 0 290 | m_ImportantGI: 0 291 | m_StitchLightmapSeams: 0 292 | m_SelectedEditorRenderState: 3 293 | m_MinimumChartSize: 4 294 | m_AutoUVMaxDistance: 0.5 295 | m_AutoUVMaxAngle: 89 296 | m_LightmapParameters: {fileID: 0} 297 | m_SortingLayerID: 0 298 | m_SortingLayer: 0 299 | m_SortingOrder: 0 300 | --- !u!65 &959225787 301 | BoxCollider: 302 | m_ObjectHideFlags: 0 303 | m_PrefabParentObject: {fileID: 0} 304 | m_PrefabInternal: {fileID: 0} 305 | m_GameObject: {fileID: 959225784} 306 | m_Material: {fileID: 0} 307 | m_IsTrigger: 0 308 | m_Enabled: 1 309 | serializedVersion: 2 310 | m_Size: {x: 1, y: 1, z: 1} 311 | m_Center: {x: 0, y: 0, z: 0} 312 | --- !u!33 &959225788 313 | MeshFilter: 314 | m_ObjectHideFlags: 0 315 | m_PrefabParentObject: {fileID: 0} 316 | m_PrefabInternal: {fileID: 0} 317 | m_GameObject: {fileID: 959225784} 318 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 319 | --- !u!4 &959225789 320 | Transform: 321 | m_ObjectHideFlags: 0 322 | m_PrefabParentObject: {fileID: 0} 323 | m_PrefabInternal: {fileID: 0} 324 | m_GameObject: {fileID: 959225784} 325 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 326 | m_LocalPosition: {x: 0, y: 0.125, z: 0} 327 | m_LocalScale: {x: 1, y: 0.27227148, z: 1} 328 | m_Children: [] 329 | m_Father: {fileID: 0} 330 | m_RootOrder: 3 331 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 332 | --- !u!1 &1164708736 333 | GameObject: 334 | m_ObjectHideFlags: 0 335 | m_PrefabParentObject: {fileID: 0} 336 | m_PrefabInternal: {fileID: 0} 337 | serializedVersion: 5 338 | m_Component: 339 | - component: {fileID: 1164708738} 340 | - component: {fileID: 1164708737} 341 | m_Layer: 0 342 | m_Name: Directional Light 343 | m_TagString: Untagged 344 | m_Icon: {fileID: 0} 345 | m_NavMeshLayer: 0 346 | m_StaticEditorFlags: 0 347 | m_IsActive: 1 348 | --- !u!108 &1164708737 349 | Light: 350 | m_ObjectHideFlags: 0 351 | m_PrefabParentObject: {fileID: 0} 352 | m_PrefabInternal: {fileID: 0} 353 | m_GameObject: {fileID: 1164708736} 354 | m_Enabled: 1 355 | serializedVersion: 8 356 | m_Type: 1 357 | m_Color: {r: 0.99264705, g: 0.7929071, b: 0.24816176, a: 1} 358 | m_Intensity: 1 359 | m_Range: 10 360 | m_SpotAngle: 30 361 | m_CookieSize: 10 362 | m_Shadows: 363 | m_Type: 2 364 | m_Resolution: -1 365 | m_CustomResolution: -1 366 | m_Strength: 1 367 | m_Bias: 0.05 368 | m_NormalBias: 0.4 369 | m_NearPlane: 0.2 370 | m_Cookie: {fileID: 0} 371 | m_DrawHalo: 0 372 | m_Flare: {fileID: 0} 373 | m_RenderMode: 0 374 | m_CullingMask: 375 | serializedVersion: 2 376 | m_Bits: 4294967295 377 | m_Lightmapping: 4 378 | m_AreaSize: {x: 1, y: 1} 379 | m_BounceIntensity: 1 380 | m_ColorTemperature: 6570 381 | m_UseColorTemperature: 0 382 | m_ShadowRadius: 0 383 | m_ShadowAngle: 0 384 | --- !u!4 &1164708738 385 | Transform: 386 | m_ObjectHideFlags: 0 387 | m_PrefabParentObject: {fileID: 0} 388 | m_PrefabInternal: {fileID: 0} 389 | m_GameObject: {fileID: 1164708736} 390 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 391 | m_LocalPosition: {x: 2.921, y: 4.077, z: 1.796} 392 | m_LocalScale: {x: 1, y: 1.3005475, z: 1} 393 | m_Children: [] 394 | m_Father: {fileID: 0} 395 | m_RootOrder: 1 396 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 397 | --- !u!1 &2137497974 398 | GameObject: 399 | m_ObjectHideFlags: 0 400 | m_PrefabParentObject: {fileID: 0} 401 | m_PrefabInternal: {fileID: 0} 402 | serializedVersion: 5 403 | m_Component: 404 | - component: {fileID: 2137497978} 405 | - component: {fileID: 2137497977} 406 | - component: {fileID: 2137497976} 407 | - component: {fileID: 2137497975} 408 | m_Layer: 0 409 | m_Name: Plane 410 | m_TagString: Untagged 411 | m_Icon: {fileID: 0} 412 | m_NavMeshLayer: 0 413 | m_StaticEditorFlags: 0 414 | m_IsActive: 1 415 | --- !u!23 &2137497975 416 | MeshRenderer: 417 | m_ObjectHideFlags: 0 418 | m_PrefabParentObject: {fileID: 0} 419 | m_PrefabInternal: {fileID: 0} 420 | m_GameObject: {fileID: 2137497974} 421 | m_Enabled: 1 422 | m_CastShadows: 1 423 | m_ReceiveShadows: 1 424 | m_DynamicOccludee: 1 425 | m_MotionVectors: 1 426 | m_LightProbeUsage: 1 427 | m_ReflectionProbeUsage: 1 428 | m_Materials: 429 | - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} 430 | m_StaticBatchInfo: 431 | firstSubMesh: 0 432 | subMeshCount: 0 433 | m_StaticBatchRoot: {fileID: 0} 434 | m_ProbeAnchor: {fileID: 0} 435 | m_LightProbeVolumeOverride: {fileID: 0} 436 | m_ScaleInLightmap: 1 437 | m_PreserveUVs: 1 438 | m_IgnoreNormalsForChartDetection: 0 439 | m_ImportantGI: 0 440 | m_StitchLightmapSeams: 0 441 | m_SelectedEditorRenderState: 3 442 | m_MinimumChartSize: 4 443 | m_AutoUVMaxDistance: 0.5 444 | m_AutoUVMaxAngle: 89 445 | m_LightmapParameters: {fileID: 0} 446 | m_SortingLayerID: 0 447 | m_SortingLayer: 0 448 | m_SortingOrder: 0 449 | --- !u!64 &2137497976 450 | MeshCollider: 451 | m_ObjectHideFlags: 0 452 | m_PrefabParentObject: {fileID: 0} 453 | m_PrefabInternal: {fileID: 0} 454 | m_GameObject: {fileID: 2137497974} 455 | m_Material: {fileID: 0} 456 | m_IsTrigger: 0 457 | m_Enabled: 1 458 | serializedVersion: 3 459 | m_Convex: 0 460 | m_CookingOptions: 14 461 | m_SkinWidth: 0.01 462 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 463 | --- !u!33 &2137497977 464 | MeshFilter: 465 | m_ObjectHideFlags: 0 466 | m_PrefabParentObject: {fileID: 0} 467 | m_PrefabInternal: {fileID: 0} 468 | m_GameObject: {fileID: 2137497974} 469 | m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} 470 | --- !u!4 &2137497978 471 | Transform: 472 | m_ObjectHideFlags: 0 473 | m_PrefabParentObject: {fileID: 0} 474 | m_PrefabInternal: {fileID: 0} 475 | m_GameObject: {fileID: 2137497974} 476 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 477 | m_LocalPosition: {x: -0.12, y: -0, z: -0.05} 478 | m_LocalScale: {x: 0.4336311, y: 1, z: 0.46933734} 479 | m_Children: [] 480 | m_Father: {fileID: 0} 481 | m_RootOrder: 2 482 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 483 | --------------------------------------------------------------------------------