# Technical Notes

Some highly specific technical details, problems and solutions

# Detecting a User About to Type on InputField

Due to VRChat not being the most consistent with sent UI events, especially between desktop and VR, it can be difficult to reliably detect when a user is about to start typing on a UI InputField.

During the development of [Udonity](https://github.com/Varneon/VUdon-Udonity "https://github.com/Varneon/VUdon-Udonity") I faced this specific issue with the fields on the inspectors and editor windows where values on the input fields are being updated per frame to display accurate information about the inspected objects.

In this scenario detecting the intentions of a user about to start typing on a field is necessary in order to pause the values being brute forced in while typing, which would result in user's input being rejected.

####  

#### InputFields with no [VRCInputFieldKeyboardOverride](https://docs.vrchat.com/docs/vrchat-202222p3#features-changes-fixes-and-improvements "https://docs.vrchat.com/docs/vrchat-202222p3#features-changes-fixes-and-improvements")

Since VRChat 2022.2.2p3, clicking any field will display VRChat's own in-game keyboard for typing, and *so far* I've found one reliable solution for detecting when a user is about to start typing on a field:

1. Add **Event Trigger** to the same object as the ****InputField:****
    
    [![image.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/scaled-1680-/WLAimage.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/WLAimage.png)
2. Click **Add New Event Type** &gt; **InitializePotentialDrag**: 
    
    [![image.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/scaled-1680-/h3Kimage.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/h3Kimage.png)
3. Set up any events that you want to be invoked when someone is about to start typing:[![image.png](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/scaled-1680-/I3Rimage.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2022-12/I3Rimage.png)

# Rebuilding UI Layout

If you are using [Unity UI](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/index.html "https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/index.html") [Auto Layout](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/comp-UIAutoLayout.html "https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/comp-UIAutoLayout.html") components on your UI, you may face problematic situations where the elements are getting stuck in weird positions due to layout not being rebuilt when necessary.

In these cases you can simply call [**LayoutRebuilder.ForceRebuildLayoutImmediate**](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/api/UnityEngine.UI.LayoutRebuilder.html?q=layout%20rebuilder#UnityEngine_UI_LayoutRebuilder_ForceRebuildLayoutImmediate_UnityEngine_RectTransform_ "https://docs.unity3d.com/Packages/com.unity.ugui@1.0/api/UnityEngine.UI.LayoutRebuilder.html?q=layout%20rebuilder#UnityEngine&#95;UI&#95;LayoutRebuilder&#95;ForceRebuildLayoutImmediate&#95;UnityEngine&#95;RectTransform&#95;"), which should be able to fix the problem in many scenarios:

```c#
// Call this static method with the root of the layout as a parameter. E.g:
UnityEngine.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent<RectTransform>());
```

If your UI consists of complex nested layout groups, sometimes calling the method above more than once have been able to solve the problem.

# Reading TMP_Dropdown Value in Udon

TMP_Dropdown isn't exposed in Udon, so we're unable to read its value by default. Here is a workaround to receive an event in Udon when a player selects an item on the dropdown, after which we can read the value from a proxy.

<details><summary>1) Create new TextMeshPro Dropdown</summary>

Right click on the element you wish to add the dropdown to, and navigate to `UI` &gt; `Dropdown - TextMeshPro`

[![image.png](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image.png)
  
</details>

<details><summary>2) Create proxy dropdown</summary>

Right click on the TPM dropdown object and add new empty GameObject
  
[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672826649272.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672826649272.png)
  
Add Dropdown component on the created proxy GameObject
  
[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672826783230.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672826783230.png)

Set up the proxy dropdown
  
* Transition: `None`
* Navigation: `None`
* Make sure proxy dropdown has the same number of options as the TMP dropdown

[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672827148667.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672827148667.png)
  
[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672827386201.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672827386201.png)
  
</details>

<details><summary>3) Add OnValueChanged event on TMP dropdown to set the value of the proxy dropdown</summary>

[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672828344891.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672828344891.png)
  
</details>

<details><summary>4) Create a dropdown handler UdonBehaviour</summary>

```csharp
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;

namespace Varneon.Examples
{
    [UdonBehaviourSyncMode(BehaviourSyncMode.None)]
    public class TMPDropdownTest : UdonSharpBehaviour
    {
        [SerializeField]
        private Dropdown proxyDropdown;

        public void OnDropdownValueChanged()
        {
            // value is the index of the item selected in the dropdown
            int value = proxyDropdown.value;
        }
    }
}
```
  
Add the script above to the TPM dropdown object and assign the proxy dropdown to the field
  
[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672828159308.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672828159308.png)
  
Add OnValueChanged event on the proxy dropdown to invoke the public method on the UdonBehaviour
  
[![](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/scaled-1680-/image-1672828255833.png)](https://vrclibrary.com/wiki/uploads/images/gallery/2023-01/image-1672828255833.png)

Done! - You should now be able to execute any code you want based on the value from the proxy dropdown
  
</details>