Esempio n. 1
0
        public override void OnInspectorGUI()
        {
            switch (errorState)
            {
            case BehaviourInspectorErrorState.Success:
                #if UDONSHARP_DEBUG
                EditorGUILayout.HelpBox("UDONSHARP_DEBUG is defined; backing UdonBehaviour is shown", MessageType.Info);
                #else
                EditorGUILayout.HelpBox("Something probably went wrong, you should not be able to see the underlying UdonBehaviour for UdonSharpBehaviours", MessageType.Warning);
                #endif

                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.ObjectField("Linked U# Behaviour", UdonSharpEditorUtility.GetProxyBehaviour((UdonBehaviour)target), typeof(UdonSharpBehaviour), true);
                EditorGUILayout.ObjectField("Program Source", ((UdonBehaviour)target).programSource, typeof(AbstractUdonProgramSource), false);
                EditorGUI.EndDisabledGroup();
                break;

            case BehaviourInspectorErrorState.PrefabNeedsUpgrade:
                EditorGUILayout.HelpBox("U# behaviour needs upgrade on prefab, make sure you didn't have any issues during importing the prefab.", MessageType.Error);
                break;

            case BehaviourInspectorErrorState.NoValidUSharpProgram:
                EditorGUILayout.HelpBox("U# behaviour is not pointing to a valid U# program asset.", MessageType.Error);

                UdonSharpProgramAsset programAsset = ((UdonBehaviour)target).programSource as UdonSharpProgramAsset;

                if (programAsset && programAsset.sourceCsScript == null)
                {
                    UdonSharpGUI.DrawCreateScriptButton(programAsset);
                }
                break;
            }
        }
Esempio n. 2
0
        public static UdonSharpBehaviour AddUdonSharpComponent(this 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 = gameObject.AddComponent <UdonBehaviour>();

            UdonSharpProgramAsset programAsset = UdonSharpProgramAsset.GetProgramAssetForClass(type);

            udonBehaviour.programSource = programAsset;
            udonBehaviour.AllowCollisionOwnershipTransfer = false;

            SerializedObject   componentAsset = new SerializedObject(udonBehaviour);
            SerializedProperty serializedProgramAssetProperty = componentAsset.FindProperty("serializedProgramAsset");

            serializedProgramAssetProperty.objectReferenceValue = programAsset.SerializedProgramAsset;
            componentAsset.ApplyModifiedPropertiesWithoutUndo();

            UdonSharpBehaviour proxyComponent = UdonSharpEditorUtility.GetProxyBehaviour(udonBehaviour);

            if (EditorApplication.isPlaying)
            {
                udonBehaviour.InitializeUdonContent();
            }

            return(proxyComponent);
        }
            public static bool EventInterceptor(UdonSharpBehaviour __instance)
            {
                if (UdonSharpEditorUtility.IsProxyBehaviour(__instance) || shouldSkipEventsMethod())
                {
                    return(false);
                }

                return(true);
            }
Esempio n. 4
0
        public static void DestroyImmediate(UdonSharpBehaviour behaviour)
        {
            UdonBehaviour udonBehaviour = UdonSharpEditorUtility.GetBackingUdonBehaviour(behaviour);

            if (udonBehaviour)
            {
                Undo.DestroyObjectImmediate(udonBehaviour);
            }

            Undo.DestroyObjectImmediate(behaviour);
        }
        public static UdonSharpBehaviour AddUdonSharpComponent(this 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 = gameObject.AddComponent <UdonBehaviour>();

            UdonSharpProgramAsset programAsset = UdonSharpProgramAsset.GetProgramAssetForClass(type);

            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

            switch (programAsset.behaviourSyncMode)
            {
            case BehaviourSyncMode.Continuous:
                udonBehaviour.SyncMethod = Networking.SyncType.Continuous;
                break;

            case BehaviourSyncMode.Manual:
                udonBehaviour.SyncMethod = Networking.SyncType.Manual;
                break;

            case BehaviourSyncMode.None:
                udonBehaviour.SyncMethod = Networking.SyncType.None;
                break;
            }

            SerializedObject   componentAsset = new SerializedObject(udonBehaviour);
            SerializedProperty serializedProgramAssetProperty = componentAsset.FindProperty("serializedProgramAsset");

            serializedProgramAssetProperty.objectReferenceValue = programAsset.SerializedProgramAsset;
            componentAsset.ApplyModifiedPropertiesWithoutUndo();

            UdonSharpBehaviour proxyComponent = UdonSharpEditorUtility.GetProxyBehaviour(udonBehaviour);

            if (EditorApplication.isPlaying)
            {
                udonBehaviour.InitializeUdonContent();
            }

            return(proxyComponent);
        }
Esempio n. 6
0
        static void RunAllUpdates(List <UdonBehaviour> allBehaviours = null)
        {
            UdonSharpEditorUtility.SetIgnoreEvents(false);

            if (allBehaviours == null)
            {
                allBehaviours = GetAllUdonBehaviours();
            }

            UpdateSerializedProgramAssets(allBehaviours);
            UpdatePublicVariables(allBehaviours);
            UpdateSyncModes(allBehaviours);
            CreateProxyBehaviours(allBehaviours);
        }
        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);
        }
Esempio n. 8
0
        public static void DestroyImmediate(UdonSharpBehaviour behaviour)
        {
            UdonBehaviour udonBehaviour = UdonSharpEditorUtility.GetBackingUdonBehaviour(behaviour);

            if (udonBehaviour)
            {
                Undo.DestroyObjectImmediate(udonBehaviour);
            }

            UdonSharpEditorUtility.SetIgnoreEvents(true);

            try
            {
                Undo.DestroyObjectImmediate(behaviour);
            }
            finally
            {
                UdonSharpEditorUtility.SetIgnoreEvents(false);
            }
        }
Esempio n. 9
0
        public static UdonSharpBehaviour AddUdonSharpComponent(this GameObject gameObject, Type type)
        {
            if (type == typeof(UdonSharpBehaviour))
            {
                throw new ArgumentException("Cannot add components of type 'UdonSharpBehaviour', you can only add subclasses of this type");
            }

            if (!typeof(UdonSharpBehaviour).IsAssignableFrom(type))
            {
                throw new ArgumentException("Type for AddUdonSharpComponent must be a subclass of UdonSharpBehaviour");
            }

            UdonSharpBehaviour proxyBehaviour = (UdonSharpBehaviour)gameObject.AddComponent(type);

            UdonSharpEditorUtility.RunBehaviourSetup(proxyBehaviour);

            if (EditorApplication.isPlaying)
            {
                UdonSharpEditorUtility.GetBackingUdonBehaviour(proxyBehaviour).InitializeUdonContent();
            }

            return(proxyBehaviour);
        }
        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);
        }
            public static UnityEngine.Object ValidateObjectReference(UnityEngine.Object[] references, System.Type objType, SerializedProperty property, Enum options = null)
            {
                if (references.Length == 0)
                {
                    return(null);
                }

                if (property != null)
                {
                    if (references[0] != null)
                    {
                        if (EditorSceneManager.preventCrossSceneReferences && crossSceneRefCheckMethod(references[0], property.serializedObject.targetObject))
                        {
                            return(null);
                        }

                        if (references[0] is GameObject gameObject)
                        {
                            references = gameObject.GetComponents <UdonSharpBehaviour>();
                        }

                        foreach (UnityEngine.Object reference in references)
                        {
                            System.Type refType = reference.GetType();

                            if (objType.IsAssignableFrom(reference.GetType()))
                            {
                                return(reference);
                            }
                            else if (reference is UdonBehaviour udonBehaviour && UdonSharpEditorUtility.IsUdonSharpBehaviour(udonBehaviour))
                            {
                                UdonSharpBehaviour proxy = UdonSharpEditorUtility.GetProxyBehaviour(udonBehaviour);

                                if (proxy && objType.IsAssignableFrom(proxy.GetType()))
                                {
                                    return(proxy);
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (objType == typeof(UdonSharpBehaviour) ||
                        objType.IsSubclassOf(typeof(UdonSharpBehaviour)))
                    {
                        foreach (UnityEngine.Object reference in references)
                        {
                            System.Type refType = reference.GetType();

                            if (objType.IsAssignableFrom(refType))
                            {
                                return(reference);
                            }
                            else if (reference is GameObject referenceObject)
                            {
                                UnityEngine.Object foundRef = ValidateObjectReference(referenceObject.GetComponents <UdonSharpBehaviour>(), objType, null);

                                if (foundRef)
                                {
                                    return(foundRef);
                                }
                            }
                            else if (reference is UdonBehaviour referenceBehaviour && UdonSharpEditorUtility.IsUdonSharpBehaviour(referenceBehaviour))
                            {
                                UdonSharpBehaviour proxy = UdonSharpEditorUtility.GetProxyBehaviour(referenceBehaviour);

                                if (proxy && objType.IsAssignableFrom(proxy.GetType()))
                                {
                                    return(proxy);
                                }
                            }
                        }
                    }
                }

                return(null);
            }
 public static void UpdateProxy(this UdonSharpBehaviour behaviour)
 {
     UdonSharpEditorUtility.CopyUdonToProxy(behaviour);
 }
 public static void UpdateProxy(this UdonSharpBehaviour behaviour, ProxySerializationPolicy serializationPolicy)
 {
     UdonSharpEditorUtility.CopyUdonToProxy(behaviour, serializationPolicy);
 }
        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 ApplyProxyModifications(this UdonSharpBehaviour behaviour)
 {
     UdonSharpEditorUtility.CopyProxyToUdon(behaviour);
 }
 public static void ApplyProxyModifications(this UdonSharpBehaviour behaviour, ProxySerializationPolicy serializationPolicy)
 {
     UdonSharpEditorUtility.CopyProxyToUdon(behaviour, serializationPolicy);
 }
Esempio n. 17
0
        public void OnEnable()
        {
            errorState = BehaviourInspectorErrorState.Success;
            bool needsUpgradePass = false;

            foreach (Object target in targets)
            {
                UdonBehaviour targetBehaviour = (UdonBehaviour)target;

                if (!UdonSharpEditorUtility.IsUdonSharpBehaviour(targetBehaviour))
                {
                    UdonSharpUtils.LogWarning($"UdonBehaviour '{targetBehaviour}' is not using a valid U# program asset", targetBehaviour);
                    errorState = BehaviourInspectorErrorState.NoValidUSharpProgram;
                    break;
                }

                if (UdonSharpEditorUtility.GetProxyBehaviour(targetBehaviour) != null)
                {
                    continue;
                }

                needsUpgradePass = true;

                if (PrefabUtility.IsPartOfPrefabInstance(targetBehaviour) &&
                    !PrefabUtility.IsAddedComponentOverride(targetBehaviour))
                {
                    UdonSharpUtils.LogWarning($"UdonBehaviour '{targetBehaviour}' needs upgrade on source prefab asset.", targetBehaviour);
                    errorState = BehaviourInspectorErrorState.PrefabNeedsUpgrade;
                    break;
                }
            }

            if (!needsUpgradePass || errorState != BehaviourInspectorErrorState.Success)
            {
                return;
            }

            foreach (Object target in targets)
            {
                UdonBehaviour      targetBehaviour    = (UdonBehaviour)target;
                UdonSharpBehaviour udonSharpBehaviour = UdonSharpEditorUtility.GetProxyBehaviour(targetBehaviour);

                // Needs setup
                if (udonSharpBehaviour == null)
                {
                    UdonSharpEditorUtility.SetIgnoreEvents(true);

                    try
                    {
                        udonSharpBehaviour = (UdonSharpBehaviour)Undo.AddComponent(targetBehaviour.gameObject, UdonSharpEditorUtility.GetUdonSharpBehaviourType(targetBehaviour));

                        UdonSharpEditorUtility.SetBackingUdonBehaviour(udonSharpBehaviour, targetBehaviour);
                        UdonSharpEditorUtility.MoveComponentRelativeToComponent(udonSharpBehaviour, targetBehaviour, true);
                        UdonSharpEditorUtility.SetBehaviourVersion(targetBehaviour, UdonSharpBehaviourVersion.CurrentVersion);
                        UdonSharpEditorUtility.SetSceneBehaviourUpgraded(targetBehaviour);
                    }
                    finally
                    {
                        UdonSharpEditorUtility.SetIgnoreEvents(false);
                    }
                }

                udonSharpBehaviour.enabled = targetBehaviour.enabled;

            #if !UDONSHARP_DEBUG
                targetBehaviour.hideFlags = HideFlags.HideInInspector;
            #else
                targetBehaviour.hideFlags = HideFlags.None;
            #endif
            }
        }