public static UdonSharpBehaviour AddComponent(GameObject gameObject, System.Type type) { if (type == typeof(UdonSharpBehaviour)) { throw new System.ArgumentException("Cannot add components of type 'UdonSharpBehaviour', you can only add subclasses of this type"); } if (!typeof(UdonSharpBehaviour).IsAssignableFrom(type)) { throw new System.ArgumentException("Type for AddUdonSharpComponent must be a subclass of UdonSharpBehaviour"); } UdonBehaviour udonBehaviour = Undo.AddComponent <UdonBehaviour>(gameObject); UdonSharpProgramAsset programAsset = UdonSharpProgramAsset.GetProgramAssetForClass(type); udonBehaviour.programSource = programAsset; #pragma warning disable CS0618 // Type or member is obsolete udonBehaviour.AllowCollisionOwnershipTransfer = false; #pragma warning restore CS0618 // Type or member is obsolete SerializedObject componentAsset = new SerializedObject(udonBehaviour); SerializedProperty serializedProgramAssetProperty = componentAsset.FindProperty("serializedProgramAsset"); serializedProgramAssetProperty.objectReferenceValue = programAsset.SerializedProgramAsset; componentAsset.ApplyModifiedProperties(); System.Type scriptType = programAsset.GetClass(); UdonSharpBehaviour proxyComponent = (UdonSharpBehaviour)Undo.AddComponent(udonBehaviour.gameObject, scriptType); proxyComponent.hideFlags = HideFlags.DontSaveInBuild | #if !UDONSHARP_DEBUG HideFlags.HideInInspector | #endif HideFlags.DontSaveInEditor; proxyComponent.enabled = false; UdonSharpEditorUtility.SetBackingUdonBehaviour(proxyComponent, udonBehaviour); UdonSharpEditorUtility.CopyUdonToProxy(proxyComponent, ProxySerializationPolicy.AllWithCreateUndo); if (EditorApplication.isPlaying) { udonBehaviour.InitializeUdonContent(); } return(proxyComponent); }
private static UdonSharpBehaviour ConvertToUdonSharpComponentIntnl(UdonBehaviour behaviour, System.Type type, ProxySerializationPolicy proxySerializationPolicy) { if (behaviour == null) { return(null); } if (!UdonSharpEditorUtility.IsUdonSharpBehaviour(behaviour)) { return(null); } UdonSharpBehaviour udonSharpBehaviour = UdonSharpEditorUtility.GetProxyBehaviour(behaviour, ProxySerializationPolicy.NoSerialization); System.Type uSharpBehaviourType = udonSharpBehaviour.GetType(); if (udonSharpBehaviour && (uSharpBehaviourType == type || uSharpBehaviourType.IsSubclassOf(type))) { UdonSharpEditorUtility.CopyUdonToProxy(udonSharpBehaviour, proxySerializationPolicy); return(udonSharpBehaviour); } return(null); }
internal static UdonBehaviour[] ConvertToUdonBehavioursInternal(UdonSharpBehaviour[] components, bool shouldUndo, bool showPrompts, bool convertChildren) { components = components.Distinct().ToArray(); if (showPrompts) { HashSet <UdonSharpBehaviour> allReferencedBehaviours = new HashSet <UdonSharpBehaviour>(); // Check if any of these need child component conversion foreach (UdonSharpBehaviour targetObject in components) { HashSet <UdonSharpBehaviour> referencedBehaviours = new HashSet <UdonSharpBehaviour>(); CollectUdonSharpBehaviourReferencesInternal(targetObject, referencedBehaviours); if (referencedBehaviours.Count > 1) { foreach (UdonSharpBehaviour referencedBehaviour in referencedBehaviours) { if (referencedBehaviour != targetObject) { allReferencedBehaviours.Add(referencedBehaviour); } } } } if (allReferencedBehaviours.Count > 0) { // This is an absolute mess, it should probably just be simplified to counting the number of affected behaviours string referencedBehaviourStr; if (allReferencedBehaviours.Count <= 2) { referencedBehaviourStr = string.Join(", ", allReferencedBehaviours.Select(e => $"'{e.ToString()}'")); } else { referencedBehaviourStr = $"{allReferencedBehaviours.Count} behaviours"; } string rootBehaviourStr; if (components.Length <= 2) { rootBehaviourStr = $"{string.Join(", ", components.Select(e => $"'{e.ToString()}'"))} reference{(components.Length == 1 ? "s" : "")} "; } else { rootBehaviourStr = $"{components.Length} behaviours to convert reference "; } string messageStr = $"{rootBehaviourStr}{referencedBehaviourStr}. Do you want to convert all referenced behaviours as well? If no, references to these behaviours will be set to null."; int result = EditorUtility.DisplayDialogComplex("Dependent behaviours found", messageStr, "Yes", "Cancel", "No"); if (result == 2) // No { convertChildren = false; } else if (result == 1) // Cancel { return(null); } } } if (shouldUndo) { Undo.RegisterCompleteObjectUndo(components, "Convert to UdonBehaviour"); } List <UdonBehaviour> createdComponents = new List <UdonBehaviour>(); foreach (UdonSharpBehaviour targetObject in components) { MonoScript behaviourScript = MonoScript.FromMonoBehaviour(targetObject); UdonSharpProgramAsset programAsset = GetUdonSharpProgramAsset(behaviourScript); if (programAsset == null) { if (showPrompts) { string scriptPath = AssetDatabase.GetAssetPath(behaviourScript); string scriptDirectory = Path.GetDirectoryName(scriptPath); string scriptFileName = Path.GetFileNameWithoutExtension(scriptPath); string assetPath = Path.Combine(scriptDirectory, $"{scriptFileName}.asset").Replace('\\', '/'); if (EditorUtility.DisplayDialog("No linked program asset", $"There was no UdonSharpProgramAsset found for '{behaviourScript.GetClass()}', do you want to create one?", "Ok", "Cancel")) { if (AssetDatabase.LoadAssetAtPath <UdonSharpProgramAsset>(assetPath) != null) { if (!EditorUtility.DisplayDialog("Existing file found", $"Asset file {assetPath} already exists, do you want to overwrite it?", "Ok", "Cancel")) { continue; } } } else { continue; } programAsset = ScriptableObject.CreateInstance <UdonSharpProgramAsset>(); programAsset.sourceCsScript = behaviourScript; AssetDatabase.CreateAsset(programAsset, assetPath); AssetDatabase.SaveAssets(); UdonSharpProgramAsset.ClearProgramAssetCache(); programAsset.CompileCsProgram(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); } else { Debug.LogWarning($"Could not convert U# behaviour '{behaviourScript.GetClass()}' on '{targetObject.gameObject}' because it does not have a corresponding UdonSharpProgramAsset"); continue; } } GameObject targetGameObject = targetObject.gameObject; UdonBehaviour udonBehaviour = null; if (shouldUndo) { udonBehaviour = Undo.AddComponent <UdonBehaviour>(targetGameObject); } else { udonBehaviour = targetGameObject.AddComponent <UdonBehaviour>(); } udonBehaviour.programSource = programAsset; #pragma warning disable CS0618 // Type or member is obsolete udonBehaviour.SynchronizePosition = false; udonBehaviour.AllowCollisionOwnershipTransfer = false; #pragma warning restore CS0618 // Type or member is obsolete udonBehaviour.Reliable = programAsset.behaviourSyncMode == BehaviourSyncMode.Manual; //if (shouldUndo) // Undo.RegisterCompleteObjectUndo(targetObject, "Convert C# to U# behaviour"); UdonSharpEditorUtility.SetBackingUdonBehaviour(targetObject, udonBehaviour); try { if (convertChildren) { UdonSharpEditorUtility.CopyProxyToUdon(targetObject, shouldUndo ? ProxySerializationPolicy.AllWithCreateUndo : ProxySerializationPolicy.AllWithCreate); } else { UdonSharpEditorUtility.CopyProxyToUdon(targetObject, ProxySerializationPolicy.RootOnly); } } catch (System.Exception e) { Debug.LogError(e); } UdonSharpEditorUtility.SetBackingUdonBehaviour(targetObject, null); System.Type behaviourType = targetObject.GetType(); UdonSharpBehaviour newProxy; SetIgnoreEvents(true); try { if (shouldUndo) { newProxy = (UdonSharpBehaviour)Undo.AddComponent(targetObject.gameObject, behaviourType); } else { newProxy = (UdonSharpBehaviour)targetObject.gameObject.AddComponent(behaviourType); } UdonSharpEditorUtility.SetBackingUdonBehaviour(newProxy, udonBehaviour); try { UdonSharpEditorUtility.CopyUdonToProxy(newProxy); } catch (System.Exception e) { Debug.LogError(e); } if (shouldUndo) { Undo.DestroyObjectImmediate(targetObject); } else { Object.DestroyImmediate(targetObject); } newProxy.hideFlags = HideFlags.DontSaveInBuild | #if !UDONSHARP_DEBUG HideFlags.HideInInspector | #endif HideFlags.DontSaveInEditor; newProxy.enabled = false; } finally { SetIgnoreEvents(false); } createdComponents.Add(udonBehaviour); } return(createdComponents.ToArray()); }
public static void UpdateProxy(this UdonSharpBehaviour behaviour, ProxySerializationPolicy serializationPolicy) { UdonSharpEditorUtility.CopyUdonToProxy(behaviour, serializationPolicy); }
public static void UpdateProxy(this UdonSharpBehaviour behaviour) { UdonSharpEditorUtility.CopyUdonToProxy(behaviour); }