Added Unity project files
This commit is contained in:
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce43b6297c145894390ff674ed7598a1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8abd1cc8bd6eb464c886df3e4b6d6104
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,10 @@
|
||||
|
||||
namespace UdonSharp.Lib.Internal
|
||||
{
|
||||
public static class CompilerConstants
|
||||
{
|
||||
public const string UsbTypeIDHeapKey = "__refl_typeid";
|
||||
public const string UsbTypeNameHeapKey = "__refl_typename";
|
||||
public const string UsbTypeIDArrayHeapKey = "__refl_typeids";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a434385f6fdf35b4a92bbe1db28fc52a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,486 @@
|
||||
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using VRC.Udon;
|
||||
|
||||
// These are invalid in C#, but valid in U# because UdonSharpBehaviours are weakly considered UdonBehaviours
|
||||
// ReSharper disable PossibleInvalidCastException
|
||||
// ReSharper disable SuspiciousTypeConversion.Global
|
||||
|
||||
namespace UdonSharp.Lib.Internal
|
||||
{
|
||||
public static class GetComponentShim
|
||||
{
|
||||
#region GetComponent
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponent<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] udonBehaviours = (UdonBehaviour[])instance.GetComponents(typeof(UdonBehaviour));
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in udonBehaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null && (long) idValue == targetID)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildren<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] udonBehaviours = (UdonBehaviour[])instance.GetComponentsInChildren(typeof(UdonBehaviour));
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in udonBehaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null && (long) idValue == targetID)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildren<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] udonBehaviours = (UdonBehaviour[])instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive);
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in udonBehaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null && (long) idValue == targetID)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInParent<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] udonBehaviours = (UdonBehaviour[])instance.GetComponentsInParent(typeof(UdonBehaviour));
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in udonBehaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null && (long) idValue == targetID)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInParent<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] udonBehaviours = (UdonBehaviour[])instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive);
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in udonBehaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null && (long) idValue == targetID)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetComponents
|
||||
|
||||
private static T[] GetComponentsOfType<T>(UdonBehaviour[] inputArray) where T : UdonSharpBehaviour
|
||||
{
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
int arraySize = 0;
|
||||
foreach (UdonBehaviour behaviour in inputArray)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object typeID = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (typeID != null && (long) typeID == targetID)
|
||||
arraySize++;
|
||||
}
|
||||
|
||||
Component[] foundBehaviours = new Component[arraySize];
|
||||
int targetIdx = 0;
|
||||
|
||||
foreach (UdonBehaviour behaviour in inputArray)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object typeID = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (typeID != null && (long) typeID == targetID)
|
||||
foundBehaviours[targetIdx++] = behaviour;
|
||||
}
|
||||
|
||||
return (T[])foundBehaviours;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponents<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] instanceBehaviours = (UdonBehaviour[])instance.GetComponents(typeof(UdonBehaviour));
|
||||
return GetComponentsOfType<T>(instanceBehaviours);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildren<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] instanceBehaviours = (UdonBehaviour[])instance.GetComponentsInChildren(typeof(UdonBehaviour));
|
||||
return GetComponentsOfType<T>(instanceBehaviours);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildren<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] instanceBehaviours = (UdonBehaviour[])instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive);
|
||||
return GetComponentsOfType<T>(instanceBehaviours);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParent<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] instanceBehaviours = (UdonBehaviour[])instance.GetComponentsInParent(typeof(UdonBehaviour));
|
||||
return GetComponentsOfType<T>(instanceBehaviours);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParent<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
UdonBehaviour[] instanceBehaviours = (UdonBehaviour[])instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive);
|
||||
return GetComponentsOfType<T>(instanceBehaviours);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get UdonSharpBehaviour components
|
||||
// For doing GetComponent(s)<UdonSharpBehaviour>() specifically, just checks for existence of ID variable
|
||||
private static UdonSharpBehaviour GetUdonSharpComponent(Component[] behaviours)
|
||||
{
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])behaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (idValue != null)
|
||||
return (UdonSharpBehaviour)(Component)behaviour;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour GetComponentUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponent(instance.GetComponents(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour GetComponentInChildrenUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponent(instance.GetComponentsInChildren(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour GetComponentInChildrenUSB(Component instance, bool includeInactive)
|
||||
{
|
||||
return GetUdonSharpComponent(instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour GetComponentInParentUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponent(instance.GetComponentsInParent(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour GetComponentInParentUSB(Component instance, bool includeInactive)
|
||||
{
|
||||
return GetUdonSharpComponent(instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
// GetComponents
|
||||
private static UdonSharpBehaviour[] GetUdonSharpComponents(Component[] inputArray)
|
||||
{
|
||||
int arraySize = 0;
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])inputArray)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object typeID = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (typeID != null)
|
||||
arraySize++;
|
||||
}
|
||||
|
||||
Component[] foundBehaviours = new Component[arraySize];
|
||||
int targetIdx = 0;
|
||||
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])inputArray)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object typeID = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (typeID != null)
|
||||
foundBehaviours[targetIdx++] = behaviour;
|
||||
}
|
||||
|
||||
return (UdonSharpBehaviour[])foundBehaviours;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour[] GetComponentsUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponents(instance.GetComponents(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour[] GetComponentsInChildrenUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponents(instance.GetComponentsInChildren(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour[] GetComponentsInChildrenUSB(Component instance, bool includeInactive)
|
||||
{
|
||||
return GetUdonSharpComponents(instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour[] GetComponentsInParentUSB(Component instance)
|
||||
{
|
||||
return GetUdonSharpComponents(instance.GetComponentsInParent(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static UdonSharpBehaviour[] GetComponentsInParentUSB(Component instance, bool includeInactive)
|
||||
{
|
||||
return GetUdonSharpComponents(instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get user component that has some inheritance
|
||||
// Types with inheritance build a type array that we can do a lookup into
|
||||
private static T GetUdonSharpComponentInherited<T>(Component[] behaviours) where T : UdonSharpBehaviour
|
||||
{
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])behaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDArrayHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDArrayHeapKey);
|
||||
if (idValue != null)
|
||||
{
|
||||
if (Array.IndexOf((Array)idValue, targetID) != -1)
|
||||
return (T)(Component)behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentInherited<T>(instance.GetComponents(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildrenI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentInherited<T>(instance.GetComponentsInChildren(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildrenI<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentInherited<T>(instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInParentI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentInherited<T>(instance.GetComponentsInParent(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInParentI<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentInherited<T>(instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
// GetComponents
|
||||
private static T[] GetUdonSharpComponentsInherited<T>(Component[] behaviours) where T : UdonSharpBehaviour
|
||||
{
|
||||
long targetID = UdonSharpBehaviour.GetUdonTypeID<T>();
|
||||
|
||||
int arraySize = 0;
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])behaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDArrayHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDArrayHeapKey);
|
||||
if (idValue != null)
|
||||
{
|
||||
if (Array.IndexOf((Array)idValue, targetID) != -1)
|
||||
arraySize++;
|
||||
}
|
||||
}
|
||||
|
||||
Component[] foundBehaviours = new Component[arraySize];
|
||||
int targetIdx = 0;
|
||||
|
||||
foreach (UdonBehaviour behaviour in (UdonBehaviour[])behaviours)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (behaviour.GetProgramVariableType(CompilerConstants.UsbTypeIDArrayHeapKey) == null)
|
||||
continue;
|
||||
#endif
|
||||
object idValue = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDArrayHeapKey);
|
||||
if (idValue != null)
|
||||
{
|
||||
if (Array.IndexOf((Array)idValue, targetID) != -1)
|
||||
foundBehaviours[targetIdx++] = behaviour;
|
||||
}
|
||||
}
|
||||
|
||||
return (T[])foundBehaviours;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentsInherited<T>(instance.GetComponents(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildrenI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentsInherited<T>(instance.GetComponentsInChildren(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildrenI<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentsInherited<T>(instance.GetComponentsInChildren(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParentI<T>(Component instance) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentsInherited<T>(instance.GetComponentsInParent(typeof(UdonBehaviour)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParentI<T>(Component instance, bool includeInactive) where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonSharpComponentsInherited<T>(instance.GetComponentsInParent(typeof(UdonBehaviour), includeInactive));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Broken VRC component getcomponent workaround
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return (T)instance.GetComponent(typeof(T));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildrenVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return (T)instance.GetComponentInChildren(typeof(T));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInChildrenVRC<T>(Component instance, bool includeInactive) where T : Component
|
||||
{
|
||||
return (T)instance.GetComponentInChildren(typeof(T), includeInactive);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T GetComponentInParentVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return (T)instance.GetComponentInParent(typeof(T));
|
||||
}
|
||||
|
||||
private static T[] ConvertToTArray<T>(Component[] components) where T : Component
|
||||
{
|
||||
T[] newArr = new T[components.Length];
|
||||
Array.Copy(components, newArr, components.Length);
|
||||
|
||||
return newArr;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return ConvertToTArray<T>(instance.GetComponents(typeof(T)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildrenVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return ConvertToTArray<T>(instance.GetComponentsInChildren(typeof(T)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInChildrenVRC<T>(Component instance, bool includeInactive) where T : Component
|
||||
{
|
||||
return ConvertToTArray<T>(instance.GetComponentsInChildren(typeof(T), includeInactive));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParentVRC<T>(Component instance) where T : Component
|
||||
{
|
||||
return ConvertToTArray<T>(instance.GetComponentsInParent(typeof(T)));
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static T[] GetComponentsInParentVRC<T>(Component instance, bool includeInactive) where T : Component
|
||||
{
|
||||
return ConvertToTArray<T>(instance.GetComponentsInParent(typeof(T), includeInactive));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8232339c6b1acb3469fef9fd4ed71ad6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,59 @@
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UdonSharp.Lib.Internal
|
||||
{
|
||||
public static class InstantiationShim
|
||||
{
|
||||
// Gets aliased to VRCInstantiate by the compiler
|
||||
private static GameObject Instantiate_Extern(GameObject original) => null;
|
||||
|
||||
[UsedImplicitly]
|
||||
public static GameObject Instantiate(GameObject original)
|
||||
{
|
||||
return Instantiate_Extern(original);
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static GameObject Instantiate(GameObject original, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
GameObject instantiatedObject = Instantiate(original);
|
||||
Transform objectTransform = instantiatedObject.transform;
|
||||
objectTransform.SetPositionAndRotation(position, rotation);
|
||||
|
||||
return instantiatedObject;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static GameObject Instantiate(GameObject original, Transform parent)
|
||||
{
|
||||
GameObject instantiatedObject = Instantiate(original);
|
||||
Transform objectTransform = instantiatedObject.transform;
|
||||
objectTransform.SetParent(parent, false);
|
||||
|
||||
return instantiatedObject;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static GameObject Instantiate(GameObject original, Transform parent, bool worldPositionStays)
|
||||
{
|
||||
GameObject instantiatedObject = Instantiate(original);
|
||||
Transform objectTransform = instantiatedObject.transform;
|
||||
objectTransform.SetParent(parent, worldPositionStays);
|
||||
|
||||
return instantiatedObject;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
public static GameObject Instantiate(GameObject original, Vector3 position, Quaternion rotation, Transform parent)
|
||||
{
|
||||
GameObject instantiatedObject = Instantiate(original);
|
||||
Transform objectTransform = instantiatedObject.transform;
|
||||
objectTransform.SetPositionAndRotation(position, rotation);
|
||||
objectTransform.SetParent(parent, true);
|
||||
|
||||
return instantiatedObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65860a727d016b5419fa81530b1ab589
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,25 @@
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using VRC.Udon;
|
||||
|
||||
namespace UdonSharp.Lib.Internal
|
||||
{
|
||||
public static class UdonSharpBehaviourMethods
|
||||
{
|
||||
[UsedImplicitly]
|
||||
internal static long GetUdonTypeID(UdonBehaviour behaviour)
|
||||
{
|
||||
object id = behaviour.GetProgramVariable(CompilerConstants.UsbTypeIDHeapKey);
|
||||
if (id == null)
|
||||
return 0;
|
||||
|
||||
return (long)id;
|
||||
}
|
||||
|
||||
[UsedImplicitly]
|
||||
internal static string GetUdonTypeName(UdonBehaviour behaviour)
|
||||
{
|
||||
return (string)behaviour.GetProgramVariable(CompilerConstants.UsbTypeNameHeapKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31a99fcb8a0560a468dca1ec5706eaaf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "UdonSharp.Lib",
|
||||
"references": [
|
||||
"GUID:3c1bc1267eab5884ebe7f232c09ee0d9",
|
||||
"GUID:99835874ee819da44948776e0df4ff1d"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1a67d4778ffb214390ddafa61c1a557
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 5136146375e9a0a498a72a0091b40cc1, type: 3}
|
||||
m_Name: UdonSharp.Lib
|
||||
m_EditorClassIdentifier:
|
||||
sourceAssembly: {fileID: 5897886265953266890, guid: e1a67d4778ffb214390ddafa61c1a557,
|
||||
type: 3}
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 891645f3172a08b47b8fdf0d6006b667
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d1354616d45a9644b3c92a34f62c8c1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,219 @@
|
||||
|
||||
#define UDONSHARP_LOC_DEBUG
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml.Linq;
|
||||
using UdonSharp.Updater;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UdonSharp.Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// Locale string ID list used to get a specified localized string
|
||||
///
|
||||
/// Used for UI, compiler messages, warnings, and errors
|
||||
/// The int ID of a given LocStr is not reliable and is liable to change so do not depend on the integer value of it.
|
||||
///
|
||||
/// Enums are grouped and prefixed by the type of string they represent:
|
||||
/// `UI_`: UI related strings for UI elements, for instance the Compile All UdonSharp Programs button
|
||||
/// `CI_`: Compiler info messages, ex. Compile of X scripts finished in Y
|
||||
/// `CW_`: Compiler warning messages, ex. Multiple UdonSharpProgramAssets referencing the same script
|
||||
/// `CE_`: Compiler error messages, ex. Most compile errors
|
||||
/// </summary>
|
||||
public enum LocStr
|
||||
{
|
||||
UI_TestLocStr,
|
||||
UI_CompileProgram,
|
||||
UI_CompileAllPrograms,
|
||||
UI_SendCustomEvent,
|
||||
UI_TriggerInteract,
|
||||
UI_ProgramSource,
|
||||
UI_ProgramScript,
|
||||
UI_SourceScript,
|
||||
UI_SerializedUdonProgramAsset,
|
||||
CE_UdonSharpBehaviourConstructorsNotSupported,
|
||||
CE_PartialMethodsNotSupported,
|
||||
CE_UdonSharpBehaviourGenericMethodsNotSupported,
|
||||
CE_LocalMethodsNotSupported,
|
||||
CE_NodeNotSupported,
|
||||
CE_UdonMethodNotExposed,
|
||||
CE_InitializerListsNotSupported,
|
||||
CE_UdonFieldNotExposed,
|
||||
|
||||
Length,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instance of the currently selected locale, with lookups for appropriate messages and errors, falls back to en-US for missing strings
|
||||
/// </summary>
|
||||
internal class LocaleInstance
|
||||
{
|
||||
Dictionary<LocStr, string> localizedStringLookup = new Dictionary<LocStr, string>();
|
||||
|
||||
public LocaleInstance(string locale)
|
||||
{
|
||||
string localeDir = UdonSharpLocator.LocalizationPath;
|
||||
string fileContents = "";
|
||||
|
||||
try
|
||||
{
|
||||
fileContents = LoadLocale(Path.Combine(localeDir, locale.ToLowerInvariant() + ".resx"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError($"Failed to load locale {locale}\nException: {e}");
|
||||
}
|
||||
|
||||
XName nameAttributeID = XName.Get("name");
|
||||
XName valueAttributeID = XName.Get("value");
|
||||
|
||||
using (StringReader strReader = new StringReader(fileContents))
|
||||
{
|
||||
XElement xml = XElement.Load(strReader, LoadOptions.PreserveWhitespace);
|
||||
|
||||
foreach (var element in xml.Elements())
|
||||
{
|
||||
if (element.Name != "data")
|
||||
continue;
|
||||
|
||||
string elementName = element.Attribute(nameAttributeID).Value;
|
||||
string elementValue = element.Element(valueAttributeID).Value;
|
||||
|
||||
if (Enum.TryParse(elementName, out LocStr elementResult))
|
||||
{
|
||||
localizedStringLookup.Add(elementResult, elementValue);
|
||||
}
|
||||
#if UDONSHARP_LOC_DEBUG
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Could not find corresponding enum for key '{elementName}'");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if UDONSHARP_LOC_DEBUG
|
||||
for (int i = 0; i < (int)LocStr.Length; ++i)
|
||||
{
|
||||
if (!localizedStringLookup.ContainsKey((LocStr)i))
|
||||
Debug.LogWarning($"Did not find string for key '{(LocStr)i}'");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static string LoadLocale(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
throw new System.IO.FileNotFoundException($"Could not find locale file at {path}, make sure you have installed UdonSharp following the installation instructions.");
|
||||
|
||||
return ReadFileTextSync(path, 1f);
|
||||
}
|
||||
|
||||
// Stolen from UdonSharpUtils because it's in a different assembly, todo: move it somewhere more accessible
|
||||
static string ReadFileTextSync(string filePath, float timeoutSeconds)
|
||||
{
|
||||
bool sourceLoaded = false;
|
||||
|
||||
string fileText = "";
|
||||
|
||||
System.DateTime startTime = System.DateTime.Now;
|
||||
|
||||
while (true)
|
||||
{
|
||||
System.IO.IOException exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
fileText = System.IO.File.ReadAllText(filePath);
|
||||
sourceLoaded = true;
|
||||
}
|
||||
catch (System.IO.IOException e)
|
||||
{
|
||||
exception = e;
|
||||
|
||||
if (e is System.IO.FileNotFoundException ||
|
||||
e is System.IO.DirectoryNotFoundException)
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (sourceLoaded)
|
||||
break;
|
||||
else
|
||||
System.Threading.Thread.Sleep(20);
|
||||
|
||||
System.TimeSpan timeFromStart = System.DateTime.Now - startTime;
|
||||
|
||||
if (timeFromStart.TotalSeconds > timeoutSeconds)
|
||||
{
|
||||
UnityEngine.Debug.LogError($"Timeout when attempting to read file {filePath}");
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
return fileText;
|
||||
}
|
||||
|
||||
public string GetString(LocStr locStr)
|
||||
{
|
||||
if (localizedStringLookup.TryGetValue(locStr, out string foundStr))
|
||||
{
|
||||
return foundStr;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Localization manager
|
||||
/// </summary>
|
||||
public static class Loc
|
||||
{
|
||||
private static LocaleInstance _instance;
|
||||
|
||||
public static void InitLocalization()
|
||||
{
|
||||
if (_instance == null)
|
||||
ReloadLocalization();
|
||||
}
|
||||
|
||||
internal static void ReloadLocalization()
|
||||
{
|
||||
_instance = new LocaleInstance("en-us");
|
||||
}
|
||||
|
||||
public static string Get(LocStr locKey)
|
||||
{
|
||||
InitLocalization();
|
||||
return _instance.GetString(locKey);
|
||||
}
|
||||
|
||||
public static string Format(LocStr locKey, params object[] parameters)
|
||||
{
|
||||
InitLocalization();
|
||||
return string.Format(_instance.GetString(locKey), parameters);
|
||||
}
|
||||
}
|
||||
|
||||
#if UDONSHARP_LOC_DEBUG && UNITY_EDITOR
|
||||
internal class LocalePostProcessor : AssetPostprocessor
|
||||
{
|
||||
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
|
||||
{
|
||||
foreach (string str in importedAssets)
|
||||
{
|
||||
if (Path.GetExtension(str) == ".resx")
|
||||
{
|
||||
Loc.ReloadLocalization();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3874ffdfd4fe1d49a68990563c15819
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6525b4c44fdf9404dbe87bab83ba6cfb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,95 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf93e699136730c4bb47d4aa04c1a922
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 1
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,102 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a19a5153c23411a46923731185430b93
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 1
|
||||
validateReferences: 0
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Android: 1
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
- first:
|
||||
Android: Android
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: ARMv7
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
DefaultValueInitialized: true
|
||||
OS: AnyOS
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,93 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94ef9729b9524a34ea4b868379e06f48
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 1
|
||||
validateReferences: 0
|
||||
platformData:
|
||||
- first:
|
||||
: Any
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
Exclude Editor: 0
|
||||
Exclude Linux: 1
|
||||
Exclude Linux64: 1
|
||||
Exclude LinuxUniversal: 1
|
||||
Exclude OSXUniversal: 1
|
||||
Exclude Win: 1
|
||||
Exclude Win64: 1
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Facebook: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Facebook: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Linux64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: LinuxUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: OSXUniversal
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: x86
|
||||
- first:
|
||||
Standalone: Win
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Standalone: Win64
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: None
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15eaba9fdc5c0b34a86676edbbb3afb0
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 0
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 1
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
Windows Store Apps: WindowsStoreApps
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
CPU: AnyCPU
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "UdonSharp.Runtime",
|
||||
"references": [
|
||||
"VRC.Udon.Serialization.OdinSerializer",
|
||||
"VRC.Udon"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99835874ee819da44948776e0df4ff1d
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,123 @@
|
||||
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
|
||||
namespace UdonSharp
|
||||
{
|
||||
// At the moment Udon syncing is in a very early state.
|
||||
// This is very liable to be changed with changes to Udon syncing in the future.
|
||||
[PublicAPI]
|
||||
public enum UdonSyncMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Not synced, this is the same as not adding the UdonSynced attribute
|
||||
/// </summary>
|
||||
// [Obsolete("This is getting removed, do not use a UdonSynced attribute with NotSynced")]
|
||||
NotSynced,
|
||||
/// <summary>
|
||||
/// Synced with no interpolation, this is the same as just using `[UdonSynced]`
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// Lerped sync
|
||||
/// </summary>
|
||||
Linear,
|
||||
/// <summary>
|
||||
/// Smoothed sync
|
||||
/// </summary>
|
||||
Smooth,
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
public class UdonSyncedAttribute : Attribute
|
||||
{
|
||||
public UdonSyncMode NetworkSyncType { get; }
|
||||
|
||||
public UdonSyncedAttribute(UdonSyncMode networkSyncTypeIn = UdonSyncMode.None)
|
||||
{
|
||||
NetworkSyncType = networkSyncTypeIn;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to enforce consistent sync modes per behaviour since Udon Behaviours are usually authored with a specific type of sync in mind
|
||||
/// and it's tedious to set and make sure the sync type is correct on each behaviour.
|
||||
/// This also allows U# to verify that you're using types and variable tweening modes that are supported for the given sync mode
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public enum BehaviourSyncMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Nothing is enforced and the behaviours can be set to either sync type by the user. This is the default when no BehaviourSyncTypeAttribute is specified on a behaviour
|
||||
/// </summary>
|
||||
Any,
|
||||
/// <summary>
|
||||
/// Enforces no synced variables on the behaviour and hides the selection dropdown in the UI for the sync mode. Nothing is synced and SendCustomNetworkEvent will not work on the behaviour
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// Enforces no synced variables on the behaviour and hides the selection dropdown in the UI for the sync mode, SendCustomNetworkEvent() will still work on this behaviour
|
||||
/// </summary>
|
||||
NoVariableSync,
|
||||
/// <summary>
|
||||
/// Enforces continuous sync mode on the behaviour
|
||||
/// </summary>
|
||||
Continuous,
|
||||
/// <summary>
|
||||
/// Enforces manual sync mode on the behaviour
|
||||
/// </summary>
|
||||
Manual,
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class UdonBehaviourSyncModeAttribute : Attribute
|
||||
{
|
||||
public BehaviourSyncMode behaviourSyncMode = BehaviourSyncMode.Any;
|
||||
|
||||
public UdonBehaviourSyncModeAttribute(BehaviourSyncMode behaviourSyncMode)
|
||||
{
|
||||
this.behaviourSyncMode = behaviourSyncMode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks a method that can be called recursively in U#.
|
||||
/// This should be used on the methods that are being called recursively, you do not need to mark methods that are calling recursive methods with this.
|
||||
/// This attribute has a performance overhead which makes the marked method perform slower and usually generate more garbage. So use it only on methods that **need** to be called recursively.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
|
||||
public class RecursiveMethodAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls the target property's setter when the marked field is modified by network sync or SetProgramVariable().
|
||||
/// Fields marked with this will instead have the target property's setter called. The setter is expected to set the field if you want the field to change.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class FieldChangeCallbackAttribute : Attribute
|
||||
{
|
||||
public string CallbackPropertyName { get; private set; }
|
||||
|
||||
private FieldChangeCallbackAttribute() { }
|
||||
|
||||
public FieldChangeCallbackAttribute(string targetPropertyName)
|
||||
{
|
||||
CallbackPropertyName = targetPropertyName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks a field to only run its initializer at compile time. This may be used on particularly expensive initializers, or initializers that run code which is not currently valid in Udon.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
[Obsolete("This attribute currently does nothing")]
|
||||
public class CompileInitAttribute : Attribute
|
||||
{}
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad41a74bd6fbe7346b4389a33103f5d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,457 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEngine;
|
||||
using VRC.Udon.Common.Interfaces;
|
||||
|
||||
using System.Diagnostics;
|
||||
using UnityEngine.Serialization;
|
||||
using VRC.Dynamics;
|
||||
#if VRC_ENABLE_PLAYER_PERSISTENCE || VRC_ENABLE_INSTANCE_PERSISTENCE
|
||||
using VRC.SDK3.Persistence;
|
||||
#endif
|
||||
using VRC.SDKBase;
|
||||
using VRC.SDK3.Data;
|
||||
using VRC.Udon.Serialization.OdinSerializer;
|
||||
|
||||
namespace UdonSharp
|
||||
{
|
||||
public abstract class UdonSharpBehaviour : MonoBehaviour, ISerializationCallbackReceiver, ISupportsPrefabSerialization
|
||||
{
|
||||
// Stubs for the UdonBehaviour functions that emulate Udon behavior
|
||||
|
||||
/// <summary>
|
||||
/// Gets a field from the target UdonSharpBehaviour
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public object GetProgramVariable(string name)
|
||||
{
|
||||
FieldInfo variableField = GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
if (variableField == null)
|
||||
return null;
|
||||
|
||||
return variableField.GetValue(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a field on the target UdonSharpBehaviour.
|
||||
/// <remarks>Make sure you are setting a value on the behaviour with a compatible type to the given <paramref name="value"/>, or you may run into unexpected crashes.</remarks>
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public void SetProgramVariable(string name, object value)
|
||||
{
|
||||
FieldInfo variableField = GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
if (variableField == null)
|
||||
return;
|
||||
|
||||
FieldChangeCallbackAttribute fieldChangeCallback = variableField.GetCustomAttribute<FieldChangeCallbackAttribute>();
|
||||
|
||||
if (fieldChangeCallback != null)
|
||||
{
|
||||
PropertyInfo targetProperty = variableField.DeclaringType.GetProperty(fieldChangeCallback.CallbackPropertyName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
if (targetProperty == null)
|
||||
return;
|
||||
|
||||
MethodInfo setMethod = targetProperty.GetSetMethod(true);
|
||||
|
||||
if (setMethod == null)
|
||||
return;
|
||||
|
||||
setMethod.Invoke(this, new object[] { value });
|
||||
}
|
||||
else
|
||||
{
|
||||
variableField.SetValue(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have no parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.</remarks>
|
||||
/// </summary>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomEvent(string eventName)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (_udonSharpBackingUdonBehaviour != null) // If this is a proxy, we need to check if this is a valid call to SendCustomEvent, since animation events can call it when they shouldn't
|
||||
{
|
||||
StackFrame frame = new StackFrame(1); // Get the frame of the calling method
|
||||
|
||||
// If the calling method is null, this has been called from native code which indicates it was called by Unity, which we don't want on proxies
|
||||
if (frame.GetMethod() == null)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 0);
|
||||
|
||||
if (eventMethod != null)
|
||||
{
|
||||
eventMethod.Invoke(this, new object[] { });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have no parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute.</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName)
|
||||
{
|
||||
SendCustomEvent(eventName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have one parameter.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 1);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have two parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 2);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have three parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 3);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have four parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2, object parameter3)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 4);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2, parameter3 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have five parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2, object parameter3, object parameter4)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 5);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2, parameter3, parameter4 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have five parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2, object parameter3, object parameter4, object parameter5)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 6);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2, parameter3, parameter4, parameter5 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have five parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2, object parameter3, object parameter4, object parameter5, object parameter6)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 7);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a networked call to the method with <paramref name="eventName"/> on the target UdonSharpBehaviour. The target method must be public and have five parameters.
|
||||
/// <remarks>The method is allowed to return a value, but the return value will not be accessible via this method.
|
||||
/// Methods with an underscore as their first character will not be callable via SendCustomNetworkEvent, unless they have a [NetworkCallable] attribute..</remarks>
|
||||
/// </summary>
|
||||
/// <param name="target">Whether to send this event to only the owner of the target behaviour's GameObject, or to everyone in the instance</param>
|
||||
/// <param name="eventName">Name of the method to call</param>
|
||||
[PublicAPI]
|
||||
public void SendCustomNetworkEvent(NetworkEventTarget target, string eventName, object parameter0, object parameter1, object parameter2, object parameter3, object parameter4, object parameter5, object parameter6, object parameter7)
|
||||
{
|
||||
MethodInfo eventMethod = GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).FirstOrDefault(e => e.Name == eventName && e.GetParameters().Length == 8);
|
||||
eventMethod?.Invoke(this, new object[] { parameter0, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes target event after delaySeconds. If 0.0 delaySeconds is specified, will execute the following frame
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="delaySeconds"></param>
|
||||
/// <param name="eventTiming"></param>
|
||||
[PublicAPI]
|
||||
public void SendCustomEventDelayedSeconds(string eventName, float delaySeconds, VRC.Udon.Common.Enums.EventTiming eventTiming = VRC.Udon.Common.Enums.EventTiming.Update) { }
|
||||
|
||||
/// <summary>
|
||||
/// Executes target event after delayFrames have passed. If 0 frames is specified, will execute the following frame. In effect 0 frame delay and 1 fame delay are the same on this method.
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="delayFrames"></param>
|
||||
/// <param name="eventTiming"></param>
|
||||
[PublicAPI]
|
||||
public void SendCustomEventDelayedFrames(string eventName, int delayFrames, VRC.Udon.Common.Enums.EventTiming eventTiming = VRC.Udon.Common.Enums.EventTiming.Update) { }
|
||||
|
||||
/// <summary>
|
||||
/// Disables Interact events on this UdonBehaviour and disables the interact outline on the object this is attached to
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool DisableInteractive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Access the text that shows up on interactable tooltips
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string InteractionText { get; set; }
|
||||
|
||||
[Obsolete("This method is obsolete, use Object.Instantiate(gameObject) instead")]
|
||||
protected static GameObject VRCInstantiate(GameObject original)
|
||||
{
|
||||
return Instantiate(original);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests a network serialization of the target UdonSharpBehaviour.
|
||||
/// <remarks>This will only function if the UdonSharpBehaviour is set to Manual sync mode and the person calling RequestSerialization() is the owner of the object.</remarks>
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public void RequestSerialization() { }
|
||||
|
||||
// Stubs for builtin UdonSharp methods to get type info
|
||||
private static long GetUdonTypeID(System.Type type)
|
||||
{
|
||||
return Internal.UdonSharpInternalUtility.GetTypeID(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the unique ID of the UdonBehavior user type. Will return 0 if the UdonBehavior has no ID, which usually means that it's a graph program.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[PublicAPI]
|
||||
public long GetUdonTypeID()
|
||||
{
|
||||
return GetUdonTypeID(GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type ID for the given T, usually used for checking UdonSharpBehaviour type equality
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public static long GetUdonTypeID<T>() where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonTypeID(typeof(T));
|
||||
}
|
||||
|
||||
private static string GetUdonTypeName(System.Type type)
|
||||
{
|
||||
return Internal.UdonSharpInternalUtility.GetTypeName(type);
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public string GetUdonTypeName()
|
||||
{
|
||||
return GetUdonTypeName(GetType());
|
||||
}
|
||||
|
||||
[PublicAPI]
|
||||
public static string GetUdonTypeName<T>() where T : UdonSharpBehaviour
|
||||
{
|
||||
return GetUdonTypeName(typeof(T));
|
||||
}
|
||||
|
||||
// Method stubs for auto completion
|
||||
[PublicAPI] public virtual void PostLateUpdate() { }
|
||||
[PublicAPI] public virtual void Interact() { }
|
||||
[PublicAPI] public virtual void OnAvatarChanged(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnAvatarEyeHeightChanged(VRC.SDKBase.VRCPlayerApi player, float prevEyeHeightAsMeters) { }
|
||||
[PublicAPI] public virtual void OnDrop() { }
|
||||
[PublicAPI] public virtual void OnOwnershipTransferred(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnMasterTransferred(VRC.SDKBase.VRCPlayerApi newMaster) { }
|
||||
[PublicAPI] public virtual void OnPickup() { }
|
||||
[PublicAPI] public virtual void OnPickupUseDown() { }
|
||||
[PublicAPI] public virtual void OnPickupUseUp() { }
|
||||
[PublicAPI] public virtual void OnPlayerJoined(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerLeft(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnSpawn() { }
|
||||
[PublicAPI] public virtual void OnStationEntered(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnStationExited(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnVideoEnd() { }
|
||||
[PublicAPI] public virtual void OnVideoError(VRC.SDK3.Components.Video.VideoError videoError) { }
|
||||
[PublicAPI] public virtual void OnVideoLoop() { }
|
||||
[PublicAPI] public virtual void OnVideoPause() { }
|
||||
[PublicAPI] public virtual void OnVideoPlay() { }
|
||||
[PublicAPI] public virtual void OnVideoReady() { }
|
||||
[PublicAPI] public virtual void OnVideoStart() { }
|
||||
[PublicAPI] public virtual void OnPreSerialization() { }
|
||||
[PublicAPI] public virtual void OnDeserialization() { }
|
||||
[PublicAPI] public virtual void OnDeserialization(VRC.Udon.Common.DeserializationResult result) { }
|
||||
#if VRC_ENABLE_PLAYER_PERSISTENCE
|
||||
[PublicAPI] public virtual void OnPlayerDataUpdated(VRC.SDKBase.VRCPlayerApi player, VRC.SDK3.Persistence.PlayerData.Info[] infos) { }
|
||||
#endif
|
||||
[PublicAPI] public virtual void OnPlayerRestored(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerTriggerEnter(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerTriggerExit(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerTriggerStay(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerCollisionEnter(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerCollisionExit(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerCollisionStay(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPlayerParticleCollision(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnControllerColliderHitPlayer(VRC.SDK3.ControllerColliderPlayerHit hit) { }
|
||||
[PublicAPI] public virtual void OnPlayerRespawn(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnImageLoadSuccess(VRC.SDK3.Image.IVRCImageDownload result) { }
|
||||
[PublicAPI] public virtual void OnImageLoadError(VRC.SDK3.Image.IVRCImageDownload result) { }
|
||||
[PublicAPI] public virtual void OnStringLoadSuccess(VRC.SDK3.StringLoading.IVRCStringDownload result) { }
|
||||
[PublicAPI] public virtual void OnStringLoadError(VRC.SDK3.StringLoading.IVRCStringDownload result) { }
|
||||
[PublicAPI] public virtual void OnPlayerSuspendChanged(VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnDroneTriggerEnter(VRC.SDKBase.VRCDroneApi drone) { }
|
||||
[PublicAPI] public virtual void OnDroneTriggerExit(VRC.SDKBase.VRCDroneApi drone) { }
|
||||
[PublicAPI] public virtual void OnDroneTriggerStay(VRC.SDKBase.VRCDroneApi drone) { }
|
||||
[PublicAPI] public virtual void OnPostSerialization(VRC.Udon.Common.SerializationResult result) { }
|
||||
[PublicAPI] public virtual bool OnOwnershipRequest(VRC.SDKBase.VRCPlayerApi requestingPlayer, VRC.SDKBase.VRCPlayerApi requestedOwner) => true;
|
||||
|
||||
#region Creator Economy
|
||||
[PublicAPI] public virtual void OnPurchaseConfirmed(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player, bool purchasedNow) { }
|
||||
[PublicAPI] public virtual void OnPurchaseConfirmedMultiple(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player, bool purchasedNow, int quantity) { }
|
||||
[PublicAPI] public virtual void OnPurchaseExpired(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnPurchasesLoaded(VRC.Economy.IProduct[] products, VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnProductEvent(VRC.Economy.IProduct product, VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnListPurchases(VRC.Economy.IProduct[] products, VRC.SDKBase.VRCPlayerApi player) { }
|
||||
[PublicAPI] public virtual void OnListAvailableProducts(VRC.Economy.IProduct[] products) { }
|
||||
[PublicAPI] public virtual void OnListProductOwners(VRC.Economy.IProduct product, string[] owners) { }
|
||||
#endregion
|
||||
|
||||
[PublicAPI] public virtual void MidiNoteOn(int channel, int number, int velocity) { }
|
||||
[PublicAPI] public virtual void MidiNoteOff(int channel, int number, int velocity) { }
|
||||
[PublicAPI] public virtual void MidiControlChange(int channel, int number, int value) { }
|
||||
|
||||
[PublicAPI] public virtual void InputJump(bool value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputUse(bool value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputGrab(bool value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputDrop(bool value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputMoveHorizontal(float value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputMoveVertical(float value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputLookHorizontal(float value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void InputLookVertical(float value, VRC.Udon.Common.UdonInputEventArgs args) { }
|
||||
[PublicAPI] public virtual void OnInputMethodChanged(VRC.SDKBase.VRCInputMethod inputMethod) { }
|
||||
[PublicAPI] public virtual void OnLanguageChanged(string language) { }
|
||||
[PublicAPI] public virtual void OnAsyncGpuReadbackComplete(VRC.SDK3.Rendering.VRCAsyncGPUReadbackRequest request) { }
|
||||
[PublicAPI] public virtual void OnVRCCameraSettingsChanged(VRC.SDK3.Rendering.VRCCameraSettings cameraSettings) { }
|
||||
[PublicAPI] public virtual void OnVRCQualitySettingsChanged() { }
|
||||
[PublicAPI] public virtual void OnScreenUpdate(VRC.SDK3.Platform.ScreenUpdateData data) {}
|
||||
[PublicAPI] public virtual void OnVRCPlusMassGift(VRC.SDKBase.VRCPlayerApi gifter, int numGifts) { }
|
||||
[PublicAPI] public virtual void OnPhysBoneGrabbed(PhysBoneGrabbedInfo physBoneInfo) { }
|
||||
[PublicAPI] public virtual void OnPhysBoneReleased(PhysBoneReleasedInfo physBoneInfo) { }
|
||||
[PublicAPI] public virtual void OnPhysBonePosed(PhysBonePosedInfo physBoneInfo) { }
|
||||
[PublicAPI] public virtual void OnPhysBoneUnPosed(PhysBoneUnPosedInfo physBoneInfo) { }
|
||||
[PublicAPI] public virtual void OnContactEnter(ContactEnterInfo contactInfo) { }
|
||||
[PublicAPI] public virtual void OnContactExit(ContactExitInfo contactInfo) { }
|
||||
|
||||
#if VRC_ENABLE_PLAYER_PERSISTENCE || VRC_ENABLE_INSTANCE_PERSISTENCE
|
||||
[PublicAPI] public virtual void OnPersistenceUsageUpdated() {}
|
||||
#endif
|
||||
#if VRC_ENABLE_PLAYER_PERSISTENCE
|
||||
[PublicAPI] public virtual void OnPlayerDataStorageExceeded(VRCPlayerApi player) {}
|
||||
[PublicAPI] public virtual void OnPlayerDataStorageWarning(VRCPlayerApi player) {}
|
||||
[PublicAPI] public virtual void OnPlayerObjectStorageExceeded(VRCPlayerApi player) {}
|
||||
[PublicAPI] public virtual void OnPlayerObjectStorageWarning(VRCPlayerApi player) {}
|
||||
#endif
|
||||
|
||||
[Obsolete("The OnStationEntered() event is deprecated use the OnStationEntered(VRCPlayerApi player) event instead", true)]
|
||||
public virtual void OnStationEntered() { }
|
||||
|
||||
[Obsolete("The OnStationExited() event is deprecated use the OnStationExited(VRCPlayerApi player) event instead", true)]
|
||||
public virtual void OnStationExited() { }
|
||||
|
||||
[Obsolete("The OnOwnershipTransferred() event is deprecated use the OnOwnershipTransferred(VRCPlayerApi player) event instead", true)]
|
||||
public virtual void OnOwnershipTransferred() { }
|
||||
|
||||
// Used for tracking serialization data in editor
|
||||
// Also allows serializing user data on U# behaviours that is otherwise not supported by Unity, so stuff like jagged arrays and more complex collection types.
|
||||
[SerializeField, HideInInspector]
|
||||
private SerializationData serializationData;
|
||||
|
||||
[SerializeField, HideInInspector, UsedImplicitly]
|
||||
private VRC.Udon.UdonBehaviour _udonSharpBackingUdonBehaviour;
|
||||
|
||||
// Used to preserve backing behaviour on Reset, paste component value calls, and preset applications
|
||||
// http://answers.unity.com/answers/1754330/view.html
|
||||
private VRC.Udon.UdonBehaviour _backingUdonBehaviourDump;
|
||||
|
||||
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||
{
|
||||
UnitySerializationUtility.SerializeUnityObject(this, ref serializationData);
|
||||
_backingUdonBehaviourDump = _udonSharpBackingUdonBehaviour;
|
||||
}
|
||||
|
||||
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||
{
|
||||
UnitySerializationUtility.DeserializeUnityObject(this, ref serializationData);
|
||||
|
||||
if (_backingUdonBehaviourDump)
|
||||
{
|
||||
_udonSharpBackingUdonBehaviour = _backingUdonBehaviourDump;
|
||||
}
|
||||
}
|
||||
|
||||
SerializationData ISupportsPrefabSerialization.SerializationData
|
||||
{
|
||||
get => serializationData;
|
||||
set => serializationData = value;
|
||||
}
|
||||
#pragma warning disable CS0414 // Referenced via reflection
|
||||
[UsedImplicitly]
|
||||
private static bool _skipEvents;
|
||||
#pragma warning restore CS0414
|
||||
|
||||
[UsedImplicitly]
|
||||
private static bool ShouldSkipEvents() => _skipEvents;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c6e5249679282e459858775b10f38d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,160 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using FileInfo = System.IO.FileInfo;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UdonSharp.Updater
|
||||
{
|
||||
internal class UdonSharpDataLocator : ScriptableObject
|
||||
{
|
||||
private const string DEFAULT_DATA_PATH = "Assets/UdonSharp/UdonSharpDataLocator.asset";
|
||||
private const string PROJECT_LOADED_KEY = "UdonSharpDataLocator_HasPostProcessedAssets";
|
||||
|
||||
private static string _cachedDataLocation;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal static bool HasEverPostProcessedAssets
|
||||
{
|
||||
get => SessionState.GetBool(PROJECT_LOADED_KEY, false);
|
||||
set => SessionState.SetBool(PROJECT_LOADED_KEY, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static string DataPath
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (_cachedDataLocation != null)
|
||||
return _cachedDataLocation;
|
||||
|
||||
string[] foundLocatorGuids = AssetDatabase.FindAssets($"t:{nameof(UdonSharpDataLocator)}");
|
||||
List<UdonSharpDataLocator> foundLocators = new List<UdonSharpDataLocator>();
|
||||
|
||||
foreach (string locatorGuid in foundLocatorGuids)
|
||||
{
|
||||
UdonSharpDataLocator locator =
|
||||
AssetDatabase.LoadAssetAtPath<UdonSharpDataLocator>(AssetDatabase.GUIDToAssetPath(locatorGuid));
|
||||
|
||||
if (locator)
|
||||
foundLocators.Add(locator);
|
||||
}
|
||||
|
||||
if (foundLocators.Count > 1)
|
||||
throw new System.Exception(
|
||||
"Multiple UdonSharp data locators found, make sure you do not have multiple installations of UdonSharp and have not duplicated any UdonSharp directories");
|
||||
|
||||
if (foundLocators.Count == 0)
|
||||
{
|
||||
if (!HasEverPostProcessedAssets)
|
||||
{
|
||||
// We can't trust this result, the asset database may be invalid if the Library folder was cleared.
|
||||
// This may be running too early.
|
||||
// Best effort, give back the default path without caching.
|
||||
return Path.GetDirectoryName(DEFAULT_DATA_PATH);
|
||||
}
|
||||
|
||||
foundLocators.Add(InitializeUdonSharpData());
|
||||
}
|
||||
|
||||
_cachedDataLocation = Path.GetDirectoryName(AssetDatabase.GetAssetPath(foundLocators[0]));
|
||||
return _cachedDataLocation;
|
||||
#else
|
||||
throw new System.PlatformNotSupportedException("Cannot get UdonSharp data path outside of the Editor runtime");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private static string GetUtilitiesPath(string locatorPath)
|
||||
{
|
||||
return Path.Combine(Path.GetDirectoryName(locatorPath), "UtilityScripts");
|
||||
}
|
||||
|
||||
private static UdonSharpDataLocator InitializeUdonSharpData()
|
||||
{
|
||||
if (!AssetDatabase.IsValidFolder(Path.GetDirectoryName(DEFAULT_DATA_PATH)))
|
||||
AssetDatabase.CreateFolder("Assets", "UdonSharp");
|
||||
|
||||
string utilsTargetPath = GetUtilitiesPath(DEFAULT_DATA_PATH);
|
||||
|
||||
string utilsSourcePath = Path.Combine(UdonSharpLocator.SamplesPath, "Utilities");
|
||||
|
||||
if (Directory.Exists(utilsSourcePath))
|
||||
DeepCopyDirectory(utilsSourcePath, utilsTargetPath);
|
||||
else
|
||||
Debug.LogWarning("No utilities directory found to copy from for UdonSharp utility scripts");
|
||||
|
||||
UdonSharpDataLocator locator = CreateInstance<UdonSharpDataLocator>();
|
||||
AssetDatabase.CreateAsset(locator, DEFAULT_DATA_PATH);
|
||||
|
||||
Debug.Log("Created UdonSharp data directory", locator);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
return locator;
|
||||
}
|
||||
#endif
|
||||
|
||||
private static void DeepCopyDirectory(string sourcePath, string destinationPath)
|
||||
{
|
||||
string[] sourceDirs = Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string sourceDir in sourceDirs)
|
||||
{
|
||||
Directory.CreateDirectory(sourceDir.Replace(sourcePath, destinationPath));
|
||||
}
|
||||
|
||||
string[] sourceFiles = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string sourceFile in sourceFiles)
|
||||
{
|
||||
string targetFilePath = sourceFile.Replace(sourcePath, destinationPath);
|
||||
File.Copy(sourceFile, targetFilePath, true);
|
||||
new FileInfo(targetFilePath).IsReadOnly = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(UdonSharpDataLocator))]
|
||||
internal class UdonSharpDataLocatorEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Do not delete this file! This is used by UdonSharp to locate its data directory.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
internal class InitUSharpDataOnImport : AssetPostprocessor
|
||||
{
|
||||
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
|
||||
{
|
||||
UdonSharpDataLocator.HasEverPostProcessedAssets = true;
|
||||
|
||||
if (importedAssets.Length <= 0) return;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string importedAsset in importedAssets)
|
||||
{
|
||||
if (Path.GetFileName(importedAsset) == "UdonSharpLocator.asset" &&
|
||||
AssetDatabase.LoadAssetAtPath<UdonSharpLocator>(importedAsset))
|
||||
{
|
||||
string _ = UdonSharpDataLocator.DataPath; // Implicitly initializes the data asset if it doesn't exist
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6769ed80171cc314bb08688a48d812a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,70 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UdonSharp.Updater
|
||||
{
|
||||
/// <summary>
|
||||
/// This scriptable object doesn't store anything, it just acts as an asset that marks the install location of U# similar to how Odin Inspector locates itself
|
||||
/// This is included along with the updater to allow it to compile independently from the other UdonSharp scripts which are liable to fail to compile if the user has messed up the installation.
|
||||
/// </summary>
|
||||
// [CreateAssetMenu(menuName = "U# Locator", fileName = "UdonSharpLocator")]
|
||||
public class UdonSharpLocator : ScriptableObject
|
||||
{
|
||||
private static string _cachedInstallLocation;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the install path for the root of UdonSharp, with a standard install this will be "Assets/UdonSharp"
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string InstallPath
|
||||
{
|
||||
get
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (_cachedInstallLocation != null)
|
||||
return _cachedInstallLocation;
|
||||
|
||||
_cachedInstallLocation = Path.GetDirectoryName("Packages/com.vrchat.worlds/Integrations/UdonSharp/UdonSharpLocator.asset");
|
||||
return _cachedInstallLocation;
|
||||
#else
|
||||
throw new System.PlatformNotSupportedException("Cannot get UdonSharp installation path outside of the Editor runtime");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resources path for U#
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string ResourcesPath => Path.Combine(InstallPath, "Editor", "Resources");
|
||||
|
||||
public static string LocalizationPath => Path.Combine(ResourcesPath, "Localization");
|
||||
|
||||
public static string SettingsPath => Path.Combine(UdonSharpDataLocator.DataPath, "Settings", "UdonSharpSettings.asset");
|
||||
|
||||
public static string SamplesPath => Path.Combine(InstallPath, "Samples~");
|
||||
|
||||
public static string IntermediatePrefabPath => Path.Combine(UdonSharpDataLocator.DataPath, "PrefabBuild");
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[CustomEditor(typeof(UdonSharpLocator))]
|
||||
internal class UdonSharpLocatorEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.HelpBox("Do not delete or move this file! This is used by UdonSharp to locate its installation directory, if you delete it U# will break!", MessageType.Error);
|
||||
EditorGUILayout.HelpBox($"Path: {UdonSharpLocator.InstallPath}\n" +
|
||||
$"Resources Path: {UdonSharpLocator.ResourcesPath}\n" +
|
||||
$"Localization Path: {UdonSharpLocator.LocalizationPath}\n" +
|
||||
$"Settings Path: {UdonSharpLocator.SettingsPath}", MessageType.Info);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49f78320ed7fe0b4f8eb298ff4e9035c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: b7a7abf6cf40e2b44bf7173c3cb2728e, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace UdonSharp
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
public static class UdonSharpInternalUtility
|
||||
{
|
||||
public static long GetTypeID(System.Type type)
|
||||
{
|
||||
SHA256 typeHash = new SHA256CryptoServiceProvider();
|
||||
byte[] hash = typeHash.ComputeHash(Encoding.UTF8.GetBytes(type.FullName));
|
||||
return BitConverter.ToInt64(hash, 0);
|
||||
}
|
||||
public static long GetTypeID(string typeName)
|
||||
{
|
||||
SHA256 typeHash = new SHA256CryptoServiceProvider();
|
||||
byte[] hash = typeHash.ComputeHash(Encoding.UTF8.GetBytes(typeName));
|
||||
return BitConverter.ToInt64(hash, 0);
|
||||
}
|
||||
|
||||
public static string GetTypeName(System.Type type)
|
||||
{
|
||||
return type.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if false
|
||||
public static class UdonSharpUtility
|
||||
{
|
||||
public static long GetTypeID<T>()
|
||||
{
|
||||
return Internal.UdonSharpInternalUtility.GetTypeID(typeof(T));
|
||||
}
|
||||
|
||||
// These may be extended in the future to handle the edge cases with type names
|
||||
public static string GetTypeName(System.Type type)
|
||||
{
|
||||
return Internal.UdonSharpInternalUtility.GetTypeID(type);
|
||||
}
|
||||
|
||||
//public static string GetTypeNamespace(System.Type type)
|
||||
//{
|
||||
// return type.Namespace;
|
||||
//}
|
||||
|
||||
// Placeholder stubs, won't give valid info unless used in the Udon runtime
|
||||
public static int GetUdonScriptVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static System.DateTime GetLastCompileDate()
|
||||
{
|
||||
return System.DateTime.Now;
|
||||
}
|
||||
|
||||
public static string GetCompilerVersionString()
|
||||
{
|
||||
return "v0.0.0+0";
|
||||
}
|
||||
|
||||
// Just assume people are on the correct runtime version for Udon, since other runtimes won't compile anyways
|
||||
public static string GetCompilerName()
|
||||
{
|
||||
return "Roslyn C# compiler";
|
||||
}
|
||||
|
||||
public static int GetCompilerMajorVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetCompilerMinorVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetCompilerPatchVersion()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int GetCompilerBuild()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfea4a50f25cacb44ad6ca62f61a7936
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user