# Migration to v0.4.0

{% hint style="warning" %}
Since version 0.4.0 UdonToolkit requires UdonSharp 0.18 and above!
{% endhint %}

### Migration Guide

* Grab the [latest U# release here](https://github.com/MerlinVR/UdonSharp/releases) and import that first!
* Create a new empty scene and open it
* Click File -> Save Project
* Download the [latest UdonToolkit release here](https://github.com/orels1/UdonToolkit/releases)
* Remove the UdonToolkit folder completely while you are in that test scene
* Import the new UdonToolkit and wait for everything to compile
* Open `Edit` -> `Project Settings` -> `UdonSharp` and in the `Default Behaviour Editor` select `UdonToolkit Editor`
* Open your scene again and everything should work as expected

{% hint style="warning" %}
If you are using the **CameraSystem** - it is recommended to check that the `Start Sphere` and all the `Sphere` objects inside `VR Controls` have `Area Trigger` program assets assigned, unity seems to occasionally lose references to that particular asset
{% endhint %}

You will notice a `Legacy` folder inside UdonToolkit now which hosts all the old controllers and the legacy editor

### Controller Migration Guide

{% hint style="info" %}
You can take a look at all the U# behaviours in the **Misc** folder to see how you can use UdonToolkit now
{% endhint %}

Starting with v0.4.0 you don't need controllers anymore, and you can use all the UdonToolkit's attributes directly in the U# code!

There are some small differences mainly centered around Udon's limited support for things like Enums and cases where you want to perform some complex editor logic.

> All variables that you want to use UdonToolkit attributes with must have a `[UTEditor]` attribute on them that is last in the group

```csharp
// This will work
[SectionHeader("General")] [UTEditor]
public bool active = true;

// This won't work
[SectionHeader("Some other group")]
public float test = 0.01f;
```

This is due to some limitations of unity PropertyDrawers that do not allow proper modifier stacking

{% hint style="info" %}
Popup attribute now has new udon-friendly versions that use string names instead of Enums
{% endhint %}

```csharp
// Using an Animator source type to auto fetch Triggers from the `animator` variable
[Horizontal("AnimationTrigger")] [Popup("animator, "@animator", true)] [UdonPublic]
public string somePopupVar;
```

More examples in the [Popup attribute documentation](https://github.com/orels1/UdonToolkit/wiki/Attributes#popup)

{% hint style="danger" %}
If you want to execute editor only code in case of OnValueChanged, etc. you need to use directives
{% endhint %}

It is pretty rare that you'll have to use `#if`, but sometimes its unavoidable, especially when you want to use things like [OnValueChanged](https://github.com/orels1/UdonToolkit/wiki/Attributes#onvaluechanged) attribute.

Basically the logic behind this is as follows: you should use `#if !COMPILER_UDONSHARP && UNITY_EDITOR` if:

* You want to work with methods and types not exposed to udon
* You want to execute some logic in editor outside of playmode

In other cases - you should never need `#if` around your attribute related code

```csharp
[OnValueChanged("ToggleLights")] [UTEditor]
public bool lightsActive;

#if !COMPILER_UDONSHARP && UNITY_EDITOR
public void ToggleLights(SerializedProperty value) {
  // get the value of expected type first
  var val = value?.boolValue;
  if (value) {
    // do something here
  } else {
    // do something here
  }
}
#endif
```

As usual, check behaviours in the `Misc` folder as a reference to how things should be built. [UniversalAction](https://ut.orels.sh/v0.x/behaviours/misc-behaviours#universal-action) is a good overall example.
