Hello i am using the MRTK 2.7.3 and I am trying the read the value from a UI_KeyboardInputField object but seems something is wrong on my code
using Microsoft.MixedReality.Toolkit.Experimental.UI;
public void onSubmit()
{
GameObject username = GameObject.Find("Username");
UI_KeyboardInputField inputUsername = username.GetComponent<UI_KeyboardInputField>();
Debug.Log("username" + inputUsername.Text); <<<ERROR
}
'UI_KeyboardInputField' does not contain a definition for 'Text' and no accessible extension method 'Text' accepting a first argument of type 'UI_KeyboardInputField' could be found (are you missing a using directive or an assembly reference?)
Maybe my approach is wrong how can i get the text value from this field ?
thanks
From UI_KeyboardInputField
Only used in Unity 2018.4. No longer used in Unity 2019.3 and later versions (becomes an empty MonoBehaviour and is only around for compatibility) and you can safely remove it if you wish
And also
A component that can be added to InputField to make it work with Windows Mixed Reality's system keyboard.
Sounds to me like this is/was only a helper component for forwarding the virtual keyboard input and the actual thing is all happening in a usual InputField component attached to the same GameObject and you rather want to access the .text of that one.
Related
I am trying to use Unity3D's UIToolkit with Visual Scripting Graph...
Typically, I can Query for the proper element, and then add the necessary function to the callback... However, as I am new to Visual Scripting, I am not sure how to get to this point. I've got the 'clickable' object of the button isolated, but I'm not sure how to assign the follow-up execution in the graph.
Usually in the code, I would do something like
clickable.clicked += ExampleFunction();
What I am messing up in the graph, is how to access the '.clicked' part. I can get the proper button element, and I can isolate it's clickable property, but I can't figure out how to assign some kind of functionality to react to the button getting clicked.
I could use a custom node to make this work, but I am looking for a way to do this with built-in nodes, if possible.
Alright... I had to write a custom node, but I figured this out. Here is the graph for the solution.
You have to grab the UIDocument from whichever GameObject it is attached to... You then need to get the Root Visual Element, do NOT clone or instantiate it. You then need to Query for the desired button, using the name you gave it in the UI Builder. It is easier if you use the U Query Extensions nodes... After that, I just made a custom node to subscribe the functionality. I am not familiar of any nodes that do this.
Here is the 'Subscribe Start Result' node code:
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
public class SubscribeStartResult : Unit
{
[DoNotSerialize]
[PortLabelHidden]
public ControlInput inputTrigger;
[DoNotSerialize]
[PortLabelHidden]
public ValueInput element;
protected override void Definition()
{
element = ValueInput<Button>("element");
inputTrigger = ControlInput("inputTrigger", (flow) =>
{
flow.GetValue<Button>(element).clicked += () =>
{
Debug.Log("Button clicked");
};
return null;
});
}
}
With this setup, clicking the 'Start Button' in play-mode will log "Button clicked" in the Console.
The 'return null;' line is an artifact of the lambda. It is required to continue the control flow in the event this node has a follow-up... Otherwise, this combination of nodes and code allow you to assign callbacks for the UI Builder elements, using the Visual Scripting Graph.
I created 3 components which have the exact same implementation with only 1 difference:
The 1st component (MyTest) is implemented in the same project as its parent component
The 2nd one (Component1) is from a different (but same solution)
The 3rd (CSInput) is imported from a NuGet package. Below are the invokation of all 3 in the same parent.
The razor component implementation is as followed:
<input disabled="#Disabled">
#code {
[Parameter]
public bool Disabled { get; set; }
}
The snippet of the parent implementation:
// The Disabled property is coded as boolean
<MyTest Disabled="#DisableMyTest"/>
<RazorClassLibrary1.Component1 Disabled="#DisableMyTest" />
<CSInput Disabled="#DisableMyTest"/>
#code{
private bool DisableMyTest = false;
}
For an unknown reason, the compiler issued a CS1503 (cannot convert from 'bool' to 'string') on the Disabled property from CSInput. Any idea why? Many Thanks!
figured it out. The weird behavior is caused by me not incrementing the version of the nuget. Whenever you install a Nuget, VS keeps a copy of it in the .nuget\packages directory. If you don't clean up that directory, VS will keep use what it has. Now, where can I get wig....
I have a list in RoomSO that contains premade ButtonSOs that i created in the editor and dragged and dropped into the list. RoomSO is also premade (made in the editor) Then at runtime i create an instance of a ButtonSO and tried adding it to RoomSO buttons. I look at the RoomSO in the editor and i get "Type mismatch". I canĀ“t understand why?
RoomSO script:
[CreateAssetMenu(fileName = "New Room", menuName = "Rooms/Room")]
public class RoomSO : ScriptableObject
{
public List<ButtonSO> buttons;
public void AddButton()
{
ButtonSO bt = (ButtonSO) ScriptableObject.CreateInstance<ButtonSO>() as ButtonSO;
bt.buttonText = "Hello";
buttons.Add(bt)
}
}
My ButtonSO script:
[CreateAssetMenu(fileName = "New Button", menuName = "Rooms/Button")]
public class ButtonSO : ScriptableObject
{
public string buttonText;
}
You issue isn't really an "issue".
What happens is that usually Unity expects a ScriptableObject asset reference assigned to the fields in the Inspector. Because the actual use-case of ScriptableObject is to have certain exchangeable data/behaviour container assets.
What you are doing is creating instances on runtime. These instances are only stored in the temporary memory since you never actually store them as assets into your project.
You will see the type mismatch in the Inspector, but actually this means there is a valid reference - otherwise it would say either None (ButtonSO) or Missing (ButtonSO), it only won't be saved once the Playmode ends. The later Missing (ButtonSO) you will see after ending the Play Mode since the List<ButtonSO> will still exist, also the items within it - but the according references you created during runtime will be destroyed.
Your runtime code should still work as expected as long as the Play mode is running.
The same happens btw if you assign e.g. a GameObject field within a ScriptableObject with a reference from the Scene during runtime.
In general though: If you create these instances on runtime - why do they need to be ScriptableObjects? You could just use a normal class.
So I want to be able to use the 'Interactable' script in MRTKv2 for some of my gameobjects. I've had success when attaching the 'Interactable' and 'NearInteractionTouchable' script to the corresponding gameobject, but not when attempting to add the same functionality dynamically in the script.
Since the 'Microsoft.MixedReality.Toolkit.UI' isn't currently defined, I know I can't reference the 'Interactable' script in the script directly, but in using the 'IMixedRealityFocusHandler', 'IMixedRealityPointerHandler', 'IMixedRealityTouchHandler', and 'IMixedRealityInputHandler' interfaces instead I still haven't had success in receiving any input.
The namespaces currently defined by MRTKv2
All of the namespaces in MRTKv2
Event mapping from HL1 to HL2
Any ideas on a step that I'm missing to recreate the functionality of the 'Interactable' script that can be attached to gameobjects dynamically?
Interactable does exist in the MRTK namespace under using Microsoft.MixedReality.Toolkit.UI; perhaps you are missing references to your projects? The following code works for me, using the latest mrtk_development:
using Microsoft.MixedReality.Toolkit.Input;
using Microsoft.MixedReality.Toolkit.UI;
using UnityEngine;
public class AddInteractableTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
gameObject.AddComponent<Interactable>();
gameObject.AddComponent<NearInteractionTouchable>();
}
}
I've been working on this solidly for hours and can't seem to get anywhere, so your help will be much appreciated.
I have created a few TextMeshPro UI InputFields in Unity and can't seem to access the text after a user has inputted something. I can do it when it's a normal InputField but not with the TM Pro version. I've created a Serializefield of type TMP_InputField which I have hooked up in the inspector (also including using TMPro namespace).
Could somebody please outline the steps required to get the text into a variable because I am stumped! The script is currently sitting on a different GameObject. I have an array of type TMP_InputField called theFields and when I debug theFields[0].name that seems to work fine (using FindObjectsOfType<>) but when I try to just access a specificField.text it throws a null reference objection when trying to edit the field during the game. Any tutorials/support would be very welcome!
Did you try with UnityEvents fields on the Inspector of TMP_InputField?
I make a simple script and it combines with TMP_InputField
using UnityEngine;
public class InputfieldListener : MonoBehaviour
{
public void OnChangedInputField(string input)
{
Debug.Log("[OnChangedInputField] " + input);
}
public void OnEndedInputField(string input)
{
Debug.Log("[OnEndedInputField] " + input);
}
public void OnSelectedInputField(string input)
{
Debug.Log("[OnSelectedInputField] " + input);
}
public void OnDeslectedInputField(string input)
{
Debug.Log("[OnDeslectedInputField] " + input);
}
}
Then you can find the log of each event.
FYI, the creator has a youtube channel and there is a related video tutorial.
using TMPro;
public TMP_InputField TMP_IF;
TMP_IF.interactable = true;
TMP_IF.text = "whatever you want";
For those interested in year 2020 :)
Seems that property interactable is instantly disabled, solution was to enable it so it text could be updated...
I just code it up and then in the editor drag the TMP_InputField object into the corresponding slots in the script.
So, code-wise, I would have script like Milorad Zivanovic shows.
If you want multiple ones you might have:
public TMP_InputField [] myInputs;
In the editor (as described above in my first sentence) you just hit the plus button and drag them in. Or just highlight them all and drag in all at once. If you lock your object in the editor to do this (little lock icon up top right) don't forget to unlock it.
To access in your code you either loop or use an index. Like to get the first one you would do this:
{//... in some method
myInputs[0].text = "something";
}
PS: I did not have to explicitly set the interactable field.
PPS: The answer that HyoJin KIM gave is great and best if you like using Unity's Event. I just gave this answer so you'd have an additional way of doing it that might match your original attempt(s).
Be aware that if you do choose this latter approach it is very easy to make the mistake of choosing the static version of the same method (they are listed twice!) Many times I make this mistake. Choose the top one (non-static, aka Dynamic) for most cases!