Jump to content
Unity Insider Forum

'InvalidOperationException' thrown from state change monitor 'InputActionState' on 'Vector2:/Mouse/position'


Garzec

Recommended Posts

Ich habe ein neues Projekt angelegt und das neue Input System installiert. Ich möchte einfach nur die Klick (Desktop)/Tap (Mobile) Position abspeichern.
 
Ich weiß, dass das alte System schon etwas liefert
 
 
Ich möchte es aber mit dem neuen System umsetzen. Hier meine Input Map Konfiguration
 
O62dt.png
 
aqKzt.png
 
qnxBy.png
 
WlXoV.png
 
qoPma.png
 
ikLuX.png
 
Nds8N.png
 
Hier ein Script für Tests
 
public class FooBar : MonoBehaviour
{
    public void Select(InputAction.CallbackContext context)
    {
        Vector2 selectPosition = context.ReadValue<Vector2>();
        Debug.Log($"Select position is: {selectPosition.x}|{selectPosition.y}");
    }
}

In der Szene habe ich dann ein leeres GameObject dahingehend konfiguriert

JtQSH.png
 
Leider bekomme ich im PlayMode jedes mal, wenn ich die Maus bewege, folgende Fehler:
 
cmnPp.png 
Ich schätze mal, dass meine Input Konfiguration falsch ist.
 
Weiß jemand, wie man die Input Map dahingehend konfiguriert, dass man entweder bei einem Klick oder einem Tap die Position durchgereicht bekommt?
Link zu diesem Kommentar
Auf anderen Seiten teilen

Sehr schöner Post mit vielen Infos, sieht man auch nicht alle Tage :)

Leider kann ich nicht genau sagen... oder auch nur vernünftig vermuten, was da los ist.

Deine Zeile will ja eindeutig einen Vector2 haben und kein float. Wenn du die zweite Fehlermeldung anklickst und dir in der Konsole den Stacktrace ansiehst, hast du nicht zufällig genügend Schritte, um zu schauen, wo da Code nach einem float-Wert fragt?

Link zu diesem Kommentar
Auf anderen Seiten teilen

verstehe ich das richtig dass du einen Mauscklick erfassen willst und seine Position in einer variable Speichern willst? wenn das alles ist brauchst du nur folgende Line:

Vector2 selectedPosition = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());

zumindest Klappt das für die Maus. mit Touchscreen hab ich mich nicht befasst aber da gibts safe auch eine Methode die ähnlich aussieht. Musst dafür auch keine Actions für deine Map festlegen aber würde sich je nachdem anbieten wenn du verschiedene Controls benutzt.

 

Edit: für den Touchscreen wäre das Äquivalent wohl:

Vector2 selectedPosition = Camera.main.ScreenToWorldPoint(Touchscreen.current.position.ReadValue());

bzw 

Vector2 selectedPosition = Camera.main.ScreenToWorldPoint(Touchscreen.current.startPosition.ReadValue());

wenn du nur die Position des Fingers brauchst als du den Touchscreen das erste mal berührt hast. (ändert sich nicht wenn du den Finger bewegst wärend Touch.

Das ganze kannst du auch hier nachlesen: https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Touch.html

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Sascha

Hier der Stacktrace von der zweiten Meldung, lässt mich aber leider nicht schlauer werden

Zitat

InvalidOperationException: Cannot read value of type 'float' from control '/Mouse/position' bound to action 'Player/Select[/Mouse/position,/Mouse/position]' (control is a 'Vector2Control' with value type 'Vector2')
UnityEngine.InputSystem.InputActionState.ReadValue[TValue] (System.Int32 bindingIndex, System.Int32 controlIndex, System.Boolean ignoreComposites) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:2038)
UnityEngine.InputSystem.InputActionState.ReadCompositePartValue[TValue,TComparer] (System.Int32 bindingIndex, System.Int32 partNumber, System.Boolean* buttonValuePtr, System.Int32& controlIndex, TComparer comparer) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:2101)
UnityEngine.InputSystem.InputBindingCompositeContext.ReadValueAsButton (System.Int32 partNumber) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputBindingCompositeContext.cs:252)
UnityEngine.InputSystem.Composites.ButtonWithOneModifier.ReadValue (UnityEngine.InputSystem.InputBindingCompositeContext& context) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/Composites/ButtonWithOneModifier.cs:84)
UnityEngine.InputSystem.Composites.ButtonWithOneModifier.EvaluateMagnitude (UnityEngine.InputSystem.InputBindingCompositeContext& context) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/Composites/ButtonWithOneModifier.cs:97)
UnityEngine.InputSystem.InputActionState.ComputeMagnitude (System.Int32 bindingIndex, System.Int32 controlIndex) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:1914)
UnityEngine.InputSystem.InputActionState.IsActuated (UnityEngine.InputSystem.InputActionState+TriggerState& trigger, System.Single threshold) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:1886)
UnityEngine.InputSystem.InputInteractionContext.ControlIsActuated (System.Single threshold) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputInteractionContext.cs:85)
UnityEngine.InputSystem.Interactions.PressInteraction.Process (UnityEngine.InputSystem.InputInteractionContext& context) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/Interactions/PressInteraction.cs:63)
UnityEngine.InputSystem.InputActionState.ProcessInteractions (UnityEngine.InputSystem.InputActionState+TriggerState& trigger, System.Int32 interactionStartIndex, System.Int32 interactionCount) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:1335)
UnityEngine.InputSystem.InputActionState.ProcessControlStateChange (System.Int32 mapIndex, System.Int32 controlIndex, System.Int32 bindingIndex, System.Double time, UnityEngine.InputSystem.LowLevel.InputEventPtr eventPtr) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:933)
UnityEngine.InputSystem.InputActionState.UnityEngine.InputSystem.LowLevel.IInputStateChangeMonitor.NotifyControlStateChanged (UnityEngine.InputSystem.InputControl control, System.Double time, UnityEngine.InputSystem.LowLevel.InputEventPtr eventPtr, System.Int64 mapControlAndBindingIndex) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/Actions/InputActionState.cs:833)
UnityEngine.InputSystem.InputManager.FireStateChangeNotifications (System.Int32 deviceIndex, System.Double internalTime, UnityEngine.InputSystem.LowLevel.InputEvent* eventPtr) (at Library/PackageCache/com.unity.inputsystem@1.0.1/InputSystem/InputManager.cs:2914)
UnityEngine.InputSystem.LowLevel.<>c__DisplayClass7_0:<set_onUpdate>b__0(NativeInputUpdateType, NativeInputEventBuffer*)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate(NativeInputUpdateType, IntPtr) (at /home/bokken/buildslave/unity/build/Modules/Input/Private/Input.cs:120)

image.thumb.png.535d38602aa4be1a2ee05331dd345602.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Brighthell96

vielen Dank für den Ansatz! :) Leider habe ich dort Probleme, die mir Unity schon lösen würde

1. Ich muss selbst noch Code schreiben, auf welcher Plattform ich mich gerade befinde

2. Das Ganze ist nicht eventbasiert, das heißt, ich würde im Update 1x pro Frame den Wert abfragen, was nicht notwendig ist, wenn mir Unity ein Event triggern kann

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es wäre nicht so schwer, das selber zu coden, aber ich bin da ganz bei dir: Wenn man das krasse-dolle-neue Input-System schon benutzt, dann soll das gefälligst auch den gesamten Input erledigen.

Der Stacktrace bietet tatsächlich leider nicht wirklich eine Lösung - aber man kann sehen, dass da nirgendwo Code aus deinem Projekt drin ist, sondern alles aus UnityEngine.Blub kommt. Das heißt, dass da entweder ein Bug drinsteckt oder deine Einstellung im Input-Fenster schlecht sind - wobei diese Fehlermeldung ohne Aufschluss über das Problem wiederum ein Fehler auf Unitys Seite wäre.

So oder so weist der Stacktrace darauf hin, dass noch andere das Problem haben dürften, und siehe da:

https://stackoverflow.com/questions/58469484/cannot-read-value-of-type-float-from-control

Ist da ein Hinweis dabei, der dir hilft? Obwohl du alles so sorgfältig gepostet hast, steige ich durch das UI vom Inputsystem nie durch... muss man wohl mal selber richtig benutzt haben :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 47 Minuten schrieb Garzec:

2. Das Ganze ist nicht eventbasiert, das heißt, ich würde im Update 1x pro Frame den Wert abfragen, was nicht notwendig ist, wenn mir Unity ein Event triggern kann

okay das stimmt natürlich. aber du hast ja bereits eine Action auf deiner Map die du per event triggern kannst:

public void Select(InputAction.CallbackContext context)
    {
		if(//Device ist Maus) {
        	Vector2 selectedPosition = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());
       		Debug.Log($"Select position is: {selectPosition.x}|{selectPosition.y}");
		}
		else if(//Device ist Touchscreen) {
			Vector2 selectedPosition = Camera.main.ScreenToWorldPoint(Touchscreen.current.position.ReadValue());
       		Debug.Log($"Select position is: {selectPosition.x}|{selectPosition.y}");	
		}
    }

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Sascha

Ich sehe den Fehler erst einmal bei meiner Konfiguration. Ich werde das Ganze nochmal konfigurieren, muss aber gestehen, dass ich das System als Neuling gar nicht so einfach zu konfigurieren finde.

 

@Brighthell96

Das stimmt zwar alles, aber im Code möchte ich nicht mehr wissen, von wo der Input kommt :) Wenn Unity das alles schon kann, dann muss ich selbst weniger Code warten / Tests schreiben :) 

Link zu diesem Kommentar
Auf anderen Seiten teilen

hast du es mal mit "passh through" probiert? funktioniert wunderbar bei mir. Hier die Klasse:

public class FooBar : MonoBehaviour, InputManager.IMouseClickTestActions {

    private InputManager input;

    void Awake() {
        input = new InputManager();
        input.MouseClickTest.SetCallbacks(this);
    }

    public void OnClick(InputAction.CallbackContext context) {
            Vector2 selectPosition = Camera.main.ScreenToWorldPoint(context.ReadValue<Vector2>());
        Debug.Log($"Select position is: {selectPosition.x}|{selectPosition.y}");
    }

    private void OnEnable() {
        input.MouseClickTest.Enable();
    }

    private void OnDisable() {
        input.MouseClickTest.Disable();
    }
}

(das Interface heißt natürlich anders bei dir) dasselbe kannst du natürlich auch über die Player Input Component machen anstatt über das interface. mir ist das interface einfach lieber.

Unbenannt.thumb.PNG.80d41b702defdefd98f8ab0a64c43f5c.PNG

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Brighthell96 nein, noch nicht. Da ich das Input System nur dafür brauche, sieht mein momentaner Schlachtplan wie folgt aus...

Das Ganze wird mit dem alten System umgesetzt, das heißt, ich prüfe 1x pro Update, auf welcher Plattform ich mich befinde, je nachdem ziehe ich mir dann den Vector2 und überschreibe die Variable.

Schlechte Lösung, ist aber klein und hat keine Abhängigkeiten. Besser (sobald Lösung da ist):

- Neues Input System installieren

- Klick/Tap für Desktop/Mobile konfigurieren

- Update Code komplett wegwerfen

- Select Methode als Event Handler definieren

Damit ist mir dann die Plattform egal und der Code läuft nur, wenn er tatsächlich gebraucht wird :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb Garzec:

ich prüfe 1x pro Update, auf welcher Plattform ich mich befinde

Ich bin gerade mit dem Kopf nicht in dem Problem drin, aber bei der Aussage gilt generell: Das muss man nie. Man kann dem Compiler sagen, dass er beim Android-Build bitte diesen Code und beim Windows-Build einen anderen usw. kompilieren soll.

#if UNITY_ANDROID || UNITY_IOS
  DoTouchStuff();
#elif UNITY_STANDALONE
  DoMouseStuff();
#endif

Das kannst du überall im Code machen. Damit kannst du Zeilen, ganze Methoden oder gar ganze Klassen aus deinem Code rausschmeißen lassen, wenn die Bedingung nicht erfüllt ist. Hier hast du eine schöne Liste mit all den Flags, die Unity für dich hat: https://docs.unity3d.com/Manual/PlatformDependentCompilation.html

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hier nur mal zur Info, so sieht momentan der Workaround Code aus. Auch damit ihr mal sehen könnt, wie klein dieses "Feature" eigentlich ist, ich möchte es eben nur mit dem neuen Input System noch kleiner machen ;)

 

    public sealed class SelectedPositionStateController : MonoBehaviour
    {
        private void Update()
        {
#if UNITY_ANDROID || UNITY_IOS
            if (UnityEngine.Input.touchCount > 0)
            {
                Touch touch = UnityEngine.Input.GetTouch(0);

                // hier touch.position an meine ECS Simulation übergeben
            }
#elif UNITY_STANDALONE
            if (UnityEngine.Input.GetMouseButtonDown(0))
            {
                // hier UnityEngine.Input.mousePosition an meine ECS Simulation übergeben
            }
#endif
        }
    }

Weil den Code hier

public sealed class SelectedPositionStateController : MonoBehaviour
{
    public void Select(InputAction.CallbackContext context)
    {
        Vector2 selectedPosition = context.ReadValue<Vector2>();
        // hier selectedPosition an meine ECS Simulation übergeben
    }
}

Kann ich viel einfacher testen :P

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...