Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Calling a method on a class that overrides a UdonSharpBehavior method stub causes the compiler to crash Unity. #60

Closed
techanon opened this issue Oct 10, 2020 · 3 comments
Assignees
Labels
not a bug User is doing something that is working as it should, or is that is not yet supported

Comments

@techanon
Copy link

Describe the bug in detail:
I am attempting to have one behavior class act as a proxy manager for various other behavior objects. On this manager class, I have a method that takes in a UdonSharpBehavior as a single parameter (dynamically telling the class to proxy the object). When I save the file with that method being present, unity shuts down/crashes. If I remove/comment-out that single line that does the method call, unity does not crash. If the method call is present when I try to boot up unity, it also crashes during the "Udon Compile" loading bar, preventing it from booting fully. I attempted a type casting to see if coercion would work, to no avail.

Provide steps/code to reproduce the bug:

  • Create a UdonSharpBehavior class.
  • Add a method on that class that receives a single UdonSharpBehavior object as a parameter.
  • Create a second UdonSharpBehavior class.
  • Add a method on the second class that calls the method of the first class, passing the the value this as the parameter (any UdonSharpBehavior type will cause the issue, including this)
  • Save file/trigger UdonSharp compiler.
  • Unity crashes

Expected behavior:
For Unity not to crash and instead produce an error in the console (or more optimistically, for it to successfully compile)

Additional Information:
Unity version: 2018.4.22f
UdonSharp version: 0.18.5

@techanon techanon added the bug Something isn't working label Oct 10, 2020
@MerlinVR MerlinVR self-assigned this Oct 10, 2020
@MerlinVR
Copy link
Owner

MerlinVR commented Oct 10, 2020

Do you have any example scripts? I can't repro this issue following your steps.

public class TestScriptA : UdonSharpBehaviour
{
    public void RunMethod(TestScriptB scriptB)
    {
        Debug.Log(scriptB);
    }
}
public class TestScriptB : UdonSharpBehaviour
{
    public TestScriptA scriptA;

    void Start()
    {
        scriptA.RunMethod(this);
    }
}

These compile correctly

@MerlinVR MerlinVR added the question Further information is requested label Oct 10, 2020
@techanon
Copy link
Author

After some fiddling around, I was able to recreate the crash with new classes. I found there are two things occurring in conjunction which triggers the crash. There was a bit more than my initial discovery found. Here are my sample classes:

Proxy

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class TestProxy : UdonSharpBehaviour
{
    private TestManager manager;
}

Caller

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class TestCaller : UdonSharpBehaviour
{
    private TestManager manager;
    private TestProxy proxy;

    void Start() {
        proxy = transform.Find("Target").GetComponent<TestProxy>();
    }

    public void SwitchContext() {
        // manager.PushContext(proxy); // offending line
    }
}

Manager

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class TestManager : UdonSharpBehaviour
{
    public UdonSharpBehaviour baseContext;
    private UdonSharpBehaviour[] stack = new UdonSharpBehaviour[0];

    void Start()
    {
        if (baseContext == null)
            Debug.Log("Error: A base context needs to be added in the inspector.");
        else PushContext(baseContext);
    }

    public void PushContext(UdonSharpBehaviour ctx) {
        int newStackLength = stack.Length + 1;
        var newStack = new UdonSharpBehaviour[newStackLength];
        for (int i = 0; i < stack.Length; i++) newStack[i] = stack[i];
        newStack[newStackLength] = ctx;
        stack = newStack;
        ctx.SetProgramVariable("manager", this);
    }
    

    public void PopContext()
    {
        if (stack.Length < 2) return; // do not allow the baseContext to be removed.
        int newStackLength = stack.Length - 1;
        var newStack = new UdonSharpBehaviour[newStackLength];
        for (int i = 0; i < newStackLength; i++) newStack[i] = stack[i];
        stack = newStack;
    }
    
// The offending code causing the method call to fail, any one of these

    // public object GetProgramVariable(string name)
    // {
    //     return stack[stack.Length - 1].GetProgramVariable(name);
    // }
    // public void SetProgramVariable(string name, object value)
    // {
    //     stack[stack.Length - 1].SetProgramVariable(name, value);
    // }
    public void SendCustomEvent(string eventName)
    {
        stack[stack.Length - 1].SendCustomEvent(eventName);
    }
    // public void SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget target, string eventName)
    // {
    //     stack[stack.Length - 1].SendCustomNetworkEvent(target, eventName);
    // }
}

Trying to override one of these methods for the sake of proxying to the stack causes the compiler to fail, but ONLY when another class calls one of the methods it seems.. Does not happen when an outside class does a public field assignment, just the method call. Take the code for these three classes and compile them, then uncomment the "offending line" and compile again. The latter should crash.

If the methods cannot be overridden for whatever reason, that's fine. This was merely experimental work. But the crash is where my issue lies.

@techanon techanon changed the title Trying to pass a UdonSharpBehavior object as a method parameter causes compiler to crash Unity. Calling a method on a class that overrides a UdonSharpBehavior method stub causes the compiler to crash Unity. Oct 10, 2020
@MerlinVR
Copy link
Owner

You can only override the methods on UdonSharpBehaviours that are marked virtual. Do not attempt to override any other methods on the behaviour, it is not supported. If you want to emulate them then you need to make your own unique names for them. I will add checking for attempts to override these methods.

@MerlinVR MerlinVR added not a bug User is doing something that is working as it should, or is that is not yet supported and removed bug Something isn't working question Further information is requested labels Oct 10, 2020
MerlinVR added a commit that referenced this issue Oct 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
not a bug User is doing something that is working as it should, or is that is not yet supported
Projects
None yet
Development

No branches or pull requests

2 participants