public override void DrawSpecificProperty(SerializedProperty property, string propertyName) { switch (propertyName) { case GUID: EditorGUILayout.LabelField("Guid:", guidComp.GetGuid().ToString()); break; } }
private bool InternalAdd(GuidComponent guidComponent) { Guid guid = guidComponent.GetGuid(); GuidInfo info = new GuidInfo(guidComponent); if (!guidToObjectMap.ContainsKey(guid)) { guidToObjectMap.Add(guid, info); return(true); } GuidInfo existingInfo = guidToObjectMap[guid]; if (existingInfo.go != null && existingInfo.go != guidComponent.gameObject) { // normally, a duplicate GUID is a big problem, means you won't necessarily be referencing what you expect if (Application.isPlaying) { 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")); } else { // however, at editor time, copying an object with a GUID will duplicate the GUID resulting in a collision and repair. // we warn about this just for pedantry reasons, and so you can detect if you are unexpectedly copying these components Debug.LogWarningFormat(guidComponent, "Guid Collision Detected while creating {0}.\nAssigning new Guid.", (guidComponent != null ? guidComponent.name : "NULL")); } return(false); } // 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 existingInfo.go = info.go; existingInfo.HandleAddCallback(); guidToObjectMap[guid] = existingInfo; return(true); }
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(); }
public GuidReference(GuidComponent target) { guid = target.GetGuid(); }