Exemple #1
0
        public static UdonSharpProgramAsset GetProgramAssetForClass(System.Type classType)
        {
            if (classType == null)
            {
                throw new System.ArgumentNullException();
            }

            return(UdonSharpEditorUtility.GetUdonSharpProgramAsset(classType));
        }
Exemple #2
0
        public override void OnInspectorGUI()
        {
            EditorGUILayout.HelpBox("Udon Sharp Behaviours need to be converted to Udon Behaviours to work in game. Click the convert button below to automatically convert the script.", MessageType.Warning);

            if (GUILayout.Button("Convert to UdonBehaviour", GUILayout.Height(25)))
            {
                UdonSharpEditorUtility.ConvertToUdonBehavioursInternal(Array.ConvertAll(targets, e => e as UdonSharpBehaviour), true, true);

                return;
            }

            EditorGUILayout.Space();

            base.OnInspectorGUI();
        }
Exemple #3
0
        protected override void DrawProgramSourceGUI(UdonBehaviour udonBehaviour, ref bool dirty)
        {
            if (undoLabelStyle == null ||
                undoArrowDark == null ||
                undoArrowLight == null)
            {
                undoLabelStyle               = new GUIStyle(EditorStyles.label);
                undoLabelStyle.alignment     = TextAnchor.MiddleCenter;
                undoLabelStyle.padding       = new RectOffset(0, 0, 1, 0);
                undoLabelStyle.margin        = new RectOffset(0, 0, 0, 0);
                undoLabelStyle.border        = new RectOffset(0, 0, 0, 0);
                undoLabelStyle.stretchWidth  = false;
                undoLabelStyle.stretchHeight = false;

                undoArrowLight = new GUIContent((Texture)EditorGUIUtility.Load("Assets/UdonSharp/Editor/Resources/UndoArrowLight.png"), "Reset to default value");
                undoArrowDark  = new GUIContent((Texture)EditorGUIUtility.Load("Assets/UdonSharp/Editor/Resources/UndoArrowBlack.png"), "Reset to default value");
            }

            undoArrowContent = EditorGUIUtility.isProSkin ? undoArrowLight : undoArrowDark;

            currentBehaviour = udonBehaviour;

            EditorGUI.BeginChangeCheck();
            MonoScript newSourceCsScript = (MonoScript)EditorGUILayout.ObjectField("Source Script", sourceCsScript, typeof(MonoScript), false);

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(this, "Changed source C# script");
                sourceCsScript = newSourceCsScript;
                dirty          = true;
            }

            if (sourceCsScript == null)
            {
                if (DrawCreateScriptButton())
                {
                    dirty = true;
                }
                return;
            }

            object behaviourID           = null;
            bool   shouldUseRuntimeValue = EditorApplication.isPlaying && currentBehaviour != null;

            // UdonBehaviours won't have valid heap values unless they have been enabled once to run their initialization.
            // So we check against a value we know will exist to make sure we can use the heap variables.
            if (shouldUseRuntimeValue)
            {
                behaviourID = currentBehaviour.GetProgramVariable(behaviourIDHeapVarName);
                if (behaviourID == null)
                {
                    shouldUseRuntimeValue = false;
                }
            }

            // Just manually break the disabled scope in the UdonBehaviourEditor default drawing for now
            GUI.enabled            = GUI.enabled || shouldUseRuntimeValue;
            shouldUseRuntimeValue &= GUI.enabled;

            if (currentBehaviour != null && hasInteractEvent)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Interact", EditorStyles.boldLabel);
                currentBehaviour.interactText = EditorGUILayout.TextField("Interaction Text", currentBehaviour.interactText);
                currentBehaviour.proximity    = EditorGUILayout.Slider("Proximity", currentBehaviour.proximity, 0f, 100f);

                EditorGUI.BeginDisabledGroup(!EditorApplication.isPlaying);
                if (GUILayout.Button("Trigger Interact"))
                {
                    currentBehaviour.SendCustomEvent("_interact");
                }
                EditorGUI.EndDisabledGroup();
            }

            EditorGUILayout.Space();

            DrawPublicVariables(udonBehaviour, ref dirty);

            if (currentBehaviour != null && !shouldUseRuntimeValue && program != null)
            {
                string[] exportedSymbolNames = program.SymbolTable.GetExportedSymbols();

                foreach (string exportedSymbolName in exportedSymbolNames)
                {
                    bool foundValue = currentBehaviour.publicVariables.TryGetVariableValue(exportedSymbolName, out var variableValue);
                    bool foundType  = currentBehaviour.publicVariables.TryGetVariableType(exportedSymbolName, out var variableType);

                    // Remove this variable from the publicVariable list since UdonBehaviours set all null GameObjects, UdonBehaviours, and Transforms to the current behavior's equivalent object regardless of if it's marked as a `null` heap variable or `this`
                    // This default behavior is not the same as Unity, where the references are just left null. And more importantly, it assumes that the user has interacted with the inspector on that object at some point which cannot be guaranteed.
                    // Specifically, if the user adds some public variable to a class, and multiple objects in the scene reference the program asset,
                    //   the user will need to go through each of the objects' inspectors to make sure each UdonBehavior has its `publicVariables` variable populated by the inspector
                    if (foundValue && foundType &&
                        variableValue == null &&
                        (variableType == typeof(GameObject) || variableType == typeof(UdonBehaviour) || variableType == typeof(Transform)))
                    {
                        currentBehaviour.publicVariables.RemoveVariable(exportedSymbolName);
                    }
                }
            }

            DrawCompileErrorTextArea();
            DrawAssemblyErrorTextArea();

            EditorGUILayout.Space();

            if (GUILayout.Button("Force Compile Script"))
            {
                CompileCsProgram();
            }

            if (GUILayout.Button("Compile All UdonSharp Programs"))
            {
                CompileAllCsPrograms();
            }

            EditorGUILayout.Space();

            showExtraOptions = EditorGUILayout.Foldout(showExtraOptions, "Utilities");
            if (showExtraOptions)
            {
                if (GUILayout.Button("Export to Assembly Asset"))
                {
                    string savePath = EditorUtility.SaveFilePanelInProject("Assembly asset save location", Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(sourceCsScript)), "asset", "Choose a save location for the assembly asset");

                    if (savePath.Length > 0)
                    {
                        UdonSharpEditorUtility.UdonSharpProgramToAssemblyProgram(this, savePath);
                    }
                }
            }

            showProgramUasm = EditorGUILayout.Foldout(showProgramUasm, "Compiled C# Assembly");
            if (showProgramUasm)
            {
                DrawAssemblyTextArea(/*!Application.isPlaying*/ false, ref dirty);

                if (program != null)
                {
                    DrawProgramDisassembly();
                }
            }

            currentBehaviour = null;
        }