Skip to content

Commit

Permalink
Add compile error for GetComponent<T>() on VRCSDK3 components
Browse files Browse the repository at this point in the history
- GetComponent<T>() on SDK3 components has thrown a runtime error since forever so it has never been usable anyways. Instead provide a compile error until VRC fixes it since it's difficult to fix consistently because GetComponents variants return a `Component[]` which is not trivially assignable to T[].
  • Loading branch information
MerlinVR committed Jan 19, 2021
1 parent 054d5e9 commit a6f0a71
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Assets/UdonSharp/Editor/UdonSharpExpressionCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,18 @@ private void PopRecursiveStack(SymbolDefinition[] popSymbols)
visitorContext.uasmBuilder.AppendCommentedLine("", "");
}

private static readonly HashSet<System.Type> _brokenGetComponentTypes = new HashSet<System.Type>()
{
typeof(VRC.SDKBase.VRC_AvatarPedestal), typeof(VRC.SDK3.Components.VRCAvatarPedestal),
typeof(VRC.SDKBase.VRC_Pickup), typeof(VRC.SDK3.Components.VRCPickup),
typeof(VRC.SDKBase.VRC_PortalMarker), typeof(VRC.SDK3.Components.VRCPortalMarker),
//typeof(VRC.SDKBase.VRC_MirrorReflection), typeof(VRC.SDK3.Components.VRCMirrorReflection),
typeof(VRC.SDKBase.VRCStation),typeof(VRC.SDK3.Components.VRCStation),
typeof(VRC.SDK3.Video.Components.VRCUnityVideoPlayer),
typeof(VRC.SDK3.Video.Components.AVPro.VRCAVProVideoPlayer),
typeof(VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer),
};

private SymbolDefinition InvokeExtern(SymbolDefinition[] invokeParams)
{
// We use void as a placeholder for a null constant value getting passed in, if null is passed in and the target type is a reference type then we assume they are compatible
Expand Down Expand Up @@ -1700,6 +1712,10 @@ private SymbolDefinition InvokeExtern(SymbolDefinition[] invokeParams)
bool isGetComponent = targetMethod.Name.StartsWith("GetComponent") && genericTypeArguments != null;
bool isUserTypeGetComponent = isGetComponent && genericTypeArguments.First().IsSubclassOf(typeof(UdonSharpBehaviour));

if (isGetComponent && _brokenGetComponentTypes.Contains(genericTypeArguments.First()))
throw new System.Exception($"{targetMethod.Name}<T>() is currently broken in Udon for SDK3 components (<b><i> https://vrchat.canny.io/vrchat-udon-closed-alpha-bugs/p/getcomponentst-functions-are-not-defined-internally-for-vrcsdk3-components </i></b>)\n" +
$"Until this is fixed by VRC, try using: <b>((T){targetMethod.Name}(typeof(T)))</b> instead of <b>{targetMethod.Name}<T>()</b>");

// Now make the needed symbol definitions and run the invoke
if (!targetMethod.IsStatic && !(targetMethod is ConstructorInfo)/* && targetMethod.Name != "Instantiate"*/) // Constructors don't take an instance argument, but are still classified as an instance method
{
Expand Down

0 comments on commit a6f0a71

Please sign in to comment.