MerlinVR/UdonSharp

Changing a constant in one class doesn't recompile other classes that reference it

omgitsraven opened this issue · 1 comments

Describe the bug in detail:
If you make one class reference a constant in another class, and then only change the other class, the first class will have a stale value until you force it to recompile.

Provide steps/code to reproduce the bug:

  1. Make the following U# script and put it on a UdonBehaviour in the scene:
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class ConstHaver : UdonSharpBehaviour{
	public const int myVal = 3;
}
  1. Make the following U# script and put it on a UdonBehaviour in the scene:
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class ConstPrinter : UdonSharpBehaviour{
	
	public const int doubleVal = ConstHaver.myVal * 2;
	
	void Start(){
		Debug.Log(doubleVal);
	}
	
}
  1. Enter play mode, and note that the console says 6. Exit play mode.

  2. Edit ConstHaver and change its myVal value to 5.

  3. Enter play mode, and note that the console still says 6. Exit play mode.

  4. Edit ConstPrinter and add Debug.Log("hi"); on a new line after the existing Debug.Log

  5. Enter play mode, and note that the console now says 10 (and then hi).

Expected behavior:
I expected that either the constants would either be set at runtime, or changing one would cause all of the scripts that reference it to be recompiled (or that the readme would warn about this behaviour).

This a specific interaction between constant variables and field initializers. All scripts do get recompiled, but U# field initializers use the assemblies compiled by Unity to evaluate constants and such. So what happens is you change your script -> U# compile gets triggered using old Unity assemblies with the old constant value -> unity compile runs and reloads assemblies. Of note is that this will not be an issue when you upload the world, since world upload requires that you have the assemblies compiled and forces a compile for the world upload.

This may be addressed in the future if the underlying handling for field initializers changes significantly.