Garzec 7 Posted January 12 Report Share Posted January 12 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 - https://docs.unity3d.com/ScriptReference/Input-mousePosition.html - https://docs.unity3d.com/ScriptReference/Touch-position.html Ich möchte es aber mit dem neuen System umsetzen. Hier meine Input Map Konfiguration 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 Leider bekomme ich im PlayMode jedes mal, wenn ich die Maus bewege, folgende Fehler: 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? 1 Quote Link to post Share on other sites
Sascha 2,509 Posted January 12 Report Share Posted January 12 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? Quote Link to post Share on other sites
Brighthell96 2 Posted January 12 Report Share Posted January 12 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 Quote Link to post Share on other sites
Garzec 7 Posted January 13 Author Report Share Posted January 13 @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) Quote Link to post Share on other sites
Garzec 7 Posted January 13 Author Report Share Posted January 13 @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 Quote Link to post Share on other sites
Sascha 2,509 Posted January 13 Report Share Posted January 13 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 Quote Link to post Share on other sites
Brighthell96 2 Posted January 13 Report Share Posted January 13 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}"); } } Quote Link to post Share on other sites
Garzec 7 Posted January 13 Author Report Share Posted January 13 @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 Quote Link to post Share on other sites
Garzec 7 Posted January 13 Author Report Share Posted January 13 Ich habe als Grundlage erstmal dieses Video hier genommen und dann eben versucht die "Jump" Funktion zu erweitern. Jump muss ja keine Daten durchreichen, bei mir muss halt noch der V2 durchgereicht werden. Quote Link to post Share on other sites
Brighthell96 2 Posted January 13 Report Share Posted January 13 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. Quote Link to post Share on other sites
Garzec 7 Posted January 13 Author Report Share Posted January 13 Leider passt das nicht ganz.... 1. Das wäre jetzt nur für die Maus, auf Mobile müsste es ja anders sein 2. Jetzt wird das Event durchgehend getriggert. Ich möchte das Event ja nur auslösen, wenn tatsächlich geklickt / getappt wurde Aber danke Quote Link to post Share on other sites
Brighthell96 2 Posted January 15 Report Share Posted January 15 und? hast du eine lösung gefunden? Quote Link to post Share on other sites
Garzec 7 Posted January 15 Author Report Share Posted January 15 @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 Quote Link to post Share on other sites
Sascha 2,509 Posted January 15 Report Share Posted January 15 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 Quote Link to post Share on other sites
Garzec 7 Posted January 15 Author Report Share Posted January 15 Stimmt, ganz vergessen. Geht auch Wobei mein oberstes TODO ist diesen Code natürlich komplett rauszuwerfen, da man es mit dem neuen Input System einfacher und performanter haben kann 👍 Quote Link to post Share on other sites
Garzec 7 Posted January 15 Author Report Share Posted January 15 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 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.