Beispiel #1
0
        public static GameObject ResolveGuid(System.Guid guid)
        {
            if (instance == null)
            {
                instance = new GuidManager();
            }

            return(instance.ResolveGuidInternal(guid, null, null));
        }
Beispiel #2
0
        public static GameObject ResolveGuid(System.Guid guid, Action onDestroyCallback)
        {
            if (instance == null)
            {
                instance = new GuidManager();
            }

            return(instance.ResolveGuidInternal(guid, null, onDestroyCallback));
        }
Beispiel #3
0
        public static GameObject ResolveGuid(System.Guid guid, Action <GameObject> onAddCallback, Action onRemoveCallback)
        {
            if (instance == null)
            {
                instance = new GuidManager();
            }

            return(instance.ResolveGuidInternal(guid, onAddCallback, onRemoveCallback));
        }
Beispiel #4
0
        public static void Remove(System.Guid guid)
        {
            if (instance == null)
            {
                instance = new GuidManager();
            }

            instance.InternalRemove(guid);
        }
Beispiel #5
0
        // All the public API is static so you need not worry about creating an instance
        public static bool Add(GuidComponent guidComponent)
        {
            if (instance == null)
            {
                instance = new GuidManager();
            }

            return(instance.InternalAdd(guidComponent));
        }
        // When de-serializing or creating this component, we want to either restore our serialized GUID
        // or create a new one.
        private void CreateGuid()
        {
            // if our serialized data is invalid, then we are a new object and need a new GUID
            if (this.serializedGuid == null || this.serializedGuid.Length != 16)
            {
#if UNITY_EDITOR
                // if in editor, make sure we aren't a prefab of some kind
                if (this.IsAssetOnDisk())
                {
                    return;
                }

                Undo.RecordObject(this, "Added GUID");
#endif
                this.guid           = System.Guid.NewGuid();
                this.serializedGuid = this.guid.ToByteArray();

#if UNITY_EDITOR
                // If we are creating a new GUID for a prefab instance of a prefab, but we have somehow lost our prefab connection
                // force a save of the modified prefab instance properties
                if (PrefabUtility.IsPartOfNonAssetPrefabInstance(this))
                {
                    PrefabUtility.RecordPrefabInstancePropertyModifications(this);
                }
#endif
            }
            else if (this.guid == System.Guid.Empty)
            {
                // otherwise, we should set our system guid to our serialized guid
                this.guid = new System.Guid(this.serializedGuid);
            }

            // register with the GUID Manager so that other components can access this
            if (this.guid != System.Guid.Empty)
            {
                if (!GuidManager.Add(this))
                {
                    // if registration fails, we probably have a duplicate or invalid GUID, get us a new one.
                    this.serializedGuid = null;
                    this.guid           = System.Guid.Empty;
                    this.CreateGuid();
                }
            }
        }
 // Let the manager know we are gone, so other objects no longer find this
 public void OnDestroy()
 {
     GuidManager.Remove(this.guid);
 }
Beispiel #8
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            guidProp  = property.FindPropertyRelative("serializedGuid");
            nameProp  = property.FindPropertyRelative("cachedName");
            sceneProp = property.FindPropertyRelative("cachedScene");

            // Using BeginProperty / EndProperty on the parent property means that
            // prefab override logic works on the entire property.
            EditorGUI.BeginProperty(position, label, property);

            position.height = EditorGUIUtility.singleLineHeight;

            // Draw prefix label, returning the new rect we can draw in
            var guidCompPosition = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

            System.Guid currentGuid;
            GameObject  currentGO = null;

            // working with array properties is a bit unwieldy
            // you have to get the property at each index manually
            byte[] byteArray = new byte[16];
            int    arraySize = guidProp.arraySize;

            for (int i = 0; i < arraySize; ++i)
            {
                var byteProp = guidProp.GetArrayElementAtIndex(i);
                byteArray[i] = (byte)byteProp.intValue;
            }

            currentGuid = new System.Guid(byteArray);
            currentGO   = GuidManager.ResolveGuid(currentGuid);
            GuidComponent currentGuidComponent = currentGO != null?currentGO.GetComponent <GuidComponent>() : null;

            GuidComponent component = null;

            if (currentGuid != System.Guid.Empty && currentGuidComponent == null)
            {
                // 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
                float buttonWidth = 55.0f;

                guidCompPosition.xMax -= buttonWidth;

                bool guiEnabled = GUI.enabled;
                GUI.enabled = false;
                EditorGUI.LabelField(guidCompPosition, new GUIContent(nameProp.stringValue, "Target GameObject is not currently loaded."), EditorStyles.objectField);
                GUI.enabled = guiEnabled;

                Rect clearButtonRect = new Rect(guidCompPosition);
                clearButtonRect.xMin  = guidCompPosition.xMax;
                clearButtonRect.xMax += buttonWidth;

                if (GUI.Button(clearButtonRect, clearButtonGUI, EditorStyles.miniButton))
                {
                    ClearPreviousGuid();
                }
            }
            else
            {
                // if our object is loaded, we can simply use an object field directly
                component = EditorGUI.ObjectField(guidCompPosition, currentGuidComponent, typeof(GuidComponent), true) as GuidComponent;
            }

            if (currentGuidComponent != null && component == null)
            {
                ClearPreviousGuid();
            }

            // if we have a valid reference, draw the scene name of the scene it lives in so users can find it
            if (component != null)
            {
                nameProp.stringValue = component.name;
                string scenePath = component.gameObject.scene.path;
                sceneProp.objectReferenceValue = AssetDatabase.LoadAssetAtPath <SceneAsset>(scenePath);

                // only update the GUID Prop if something changed. This fixes multi-edit on GUID References
                if (component != currentGuidComponent)
                {
                    byteArray = component.GetGuid().ToByteArray();
                    arraySize = guidProp.arraySize;
                    for (int i = 0; i < arraySize; ++i)
                    {
                        var byteProp = guidProp.GetArrayElementAtIndex(i);
                        byteProp.intValue = byteArray[i];
                    }
                }
            }

            EditorGUI.indentLevel++;
            position.y += EditorGUIUtility.singleLineHeight;
            bool cachedGUIState = GUI.enabled;

            GUI.enabled = false;
            EditorGUI.ObjectField(position, sceneLabel, sceneProp.objectReferenceValue, typeof(SceneAsset), false);
            GUI.enabled = cachedGUIState;
            EditorGUI.indentLevel--;

            EditorGUI.EndProperty();
        }