Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Guribo committed Apr 22, 2020
0 parents commit 1cc52e9
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 0 deletions.
128 changes: 128 additions & 0 deletions Assets/Guribo/Scripts/GuriboUdonUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using VRC.Udon;

namespace Guribo.Scripts
{
public class GuriboUdonUtils : MonoBehaviour
{
private static bool _interactiveMode = true;
#if UNITY_EDITOR
public class FileModificationWarning : UnityEditor.AssetModificationProcessor
{
static string[] OnWillSaveAssets(string[] paths)
{
// disable interactive mode
_interactiveMode = false;
try
{
ValidateUdonBehaviours();
}
catch (Exception e)
{
Debug.LogException(e);
}
finally
{
_interactiveMode = true;
}

return paths;
}
}
#endif

/// <summary>
/// checks all UdonBehaviours in the scene for unset public variables. Displays a dialog to skip or show the error.
/// </summary>
[MenuItem("Guribo/UDON/Validate UdonBehaviour References")]
public static void ValidateUdonBehaviours()
{
#if UNITY_EDITOR

int errorCount = 0;
var udonBehaviours = FindObjectsOfType<UdonBehaviour>();
if (udonBehaviours.Length == 0)
{
if (_interactiveMode)
{
EditorUtility.DisplayDialog("Conclusion", "No UdonBehaviours in the scene", "Ok");
}

return;
}

foreach (var udonBehaviour in udonBehaviours)
{
var udonBehaviourProgramSource = udonBehaviour.programSource;
if (udonBehaviourProgramSource == null)
{
Debug.LogWarning("UdonBehaviour on " + udonBehaviour.gameObject.name +
" has no Udon program attached", udonBehaviour);
if (_interactiveMode && EditorUtility.DisplayDialog("Empty UdonBehaviour found",
"The UdonBehaviour on the GameObject '" +
udonBehaviour.gameObject.name + "' has no program attached", "Show me", "Skip"))
{
Selection.SetActiveObjectWithContext(udonBehaviour.gameObject, udonBehaviour);
EditorGUIUtility.PingObject(udonBehaviour.gameObject);
return;
}

errorCount++;
continue;
}

var udonBehaviourPublicVariables = udonBehaviour.publicVariables;
if (udonBehaviourPublicVariables == null) continue;

var variableSymbols = udonBehaviourPublicVariables.VariableSymbols;
if (variableSymbols == null) continue;

foreach (var symbols in variableSymbols)
{
if (!udonBehaviourPublicVariables.TryGetVariableValue(symbols, out var variableValue) ||
variableValue == null)
{
Debug.LogWarning(symbols + " is not set", udonBehaviour);
if (_interactiveMode && EditorUtility.DisplayDialog("Empty public variable found",
"A public variable called '" + symbols +
"' is not set on the UdonBehaviour with the program '" +
udonBehaviourProgramSource.name + "'. You may want to fix this.", "Show me", "Skip"))
{
Selection.SetActiveObjectWithContext(udonBehaviour.gameObject, udonBehaviour);
EditorGUIUtility.PingObject(udonBehaviour.gameObject);
return;
}

errorCount++;
}
}
}


var conclusion = errorCount + " potential error" + (errorCount > 1 ? "s" : "") + " found in " +
udonBehaviours.Length +
" UdonBehaviours." +
(errorCount > 0
? " You may want to fix " + (errorCount > 1 ? "those" : "that") + "."
: "");
if (errorCount > 0)
{
Debug.LogWarning(conclusion);
}
else
{
Debug.Log(conclusion);
}

if (_interactiveMode)
{
EditorUtility.DisplayDialog("Conclusion", conclusion, "Ok");
}
#endif
}
}
}
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Guribo Udon Utils

Scripts that make developing with UDON for VRChat safer and more fun :)

## Features

* automatically checks the scene for empty public variables (*null*) and logs to the console (every time assets get saved)
* allows checking manually via menu entry to allow instant navigation to errors

## Usage

Use via menu or silently by saving the scene (Ctrl+s):
![Menu](README/menu.png)

Skip or show errors:
![Error Dialog](README/errorMessage.png)

Locate empty variable by name and allow easy fixing of variable (optionally (¬‿¬) ):
![Error Location](README/errorLocation.png)

Warns about potential errors is the console and clicking on the message will alos highlight the affected gameobject in the hierarchy:
![Error Navigation in Console](README/errorNavigationInConsole.png)

In case all errors get skipped a conclusion will be presented:
![Conclusion on Skipping](README/conclusion.png)
Binary file added README/conclusion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README/errorLocation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README/errorMessage.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README/errorNavigationInConsole.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added README/menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1cc52e9

Please sign in to comment.