jtuchel Geschrieben 22. Juli 2021 Melden Share Geschrieben 22. Juli 2021 Hallo zusammen, in meinem Projekt nutze ich das neue Input System und möchte eine Methode in einem Script testen, das einen Parameter vom Typ InputAction.CallbackContext übergeben bekommt. Innerhalb der Methode lese ich dann von diesem Parameter den Input aus und reagiere dementsprechend. Es ist möglich, diese Methode zu testen (den Output kann ich abfragen), aber dafür muss ich bei Aufruf diesen Parameter übergeben. Wie baue ich denn diesen Parameter mit Input zusammen? Also sagen wir mal über den Input wird ein Vector2 aktualisiert und ich möchte testen, dass dieser Vector2.right ist, wie muss ich mir den Parameter zusammenbauen, damit die Methode den entsprechenden Wert ausliest und ich die beiden Vektoren vergleichen kann? Vielen Dank schon einmal Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
malzbie Geschrieben 22. Juli 2021 Melden Share Geschrieben 22. Juli 2021 Das auszuwerten ist relativ einfach: public void LeftRight(InputAction.CallbackContext context){ links=false; //Testvariablen zum Auswerten in der Update oder so rechts=false; var direction = context.ReadValue<Vector2>(); if(direction[0] <0){ // [0] ist die X-Achse, [1] wäre die Y-Achse links=true; } if(direction[0] >0{ rechts=true; } } Bei diesem Beispiel gehe ich davon aus, dass das InputActionElement eine Komponente an deinem zu steuernden Gamobject ist. Beim Bereich Behavior vom InputAction ist "Invoke Unity Events" eingestellt und im Bereich Events hast du dann für diese Action das entsprechende Script und Methode ausgewählt. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
jtuchel Geschrieben 22. Juli 2021 Autor Melden Share Geschrieben 22. Juli 2021 @malzbie sorry, dann habe ich mich falsch ausgedrückt. Wie rufe ich deine Methode "LeftRight" in meinem Unittest auf, also wie baue ich mir den Parameter so zusammen, dass der erwartete Input "drin steckt"? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
malzbie Geschrieben 22. Juli 2021 Melden Share Geschrieben 22. Juli 2021 Die Methode rufst du nich von deinem Testscript auf. Die wird nur vom Action Event aufgerufen. Da sind doch die 2 Variablen, links und rechts. Wenn die im Script als Public deklariert sind, kannst du sie doch ständig vom Testscript aus abfragen. Du kannst genauso auch einen Sprung rein in eine Methode von deinem Testscript erzeugen, wo du von mir aus den direction-Wert anstatt der Variablenzustände mit übergibst. Der direction-Wertist ein Float im Bereich von -1f bis 1f. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
jtuchel Geschrieben 22. Juli 2021 Autor Melden Share Geschrieben 22. Juli 2021 Ich versuche mal kurz Beispielcode zu zeigen public void Move(InputAction.CallbackContext inputContext) { Vector2 newInput = inputContext.ReadValue<Vector2>(); transform.position += new Vector3(newInput.x, newInput.y); } Dass das kein echter Code ist, ist hoffentlich klar Aber nehmen wir es mal an. Dann könnte ich mit dem Testrunner einen Unit Test aufsetzen, indem ich mir ein leeres GameObject erzeuge, diesem GO das Script hinzufüge, das GO an eine bestimmte Stelle setze, die Move Methode aufrufe und im Test dann überprüfe, ob es sich danach an der erwarteten Position befindet. Dazu muss ich mir aber eine Instanz von InputAction.CallbackContext zusammenbauen, die den zu lesenden Input enthält. Und mir ist anhand der Docs https://docs.unity3d.com/Packages/c....InputSystem.InputAction.CallbackContext.html noch nicht klar, wie ich die erzeugte Instanz so manipuliere, dass die Zeile Vector2 newInput = inputContext.ReadValue<Vector2>(); den Fake Input ausliest. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 22. Juli 2021 Melden Share Geschrieben 22. Juli 2021 @malzbie @jtuchel möchte einen Automation Test (keinen Unit Test!) schreiben, bei dem der Testcode die Spielfigur steuern kann. Damit kann man dann automatisiert testen, ob bestimmte Systeme funktionieren (wie "kann die Figur x Meter hoch springen"). Das Ziel ist hier, dass der Bewegungscode nicht extra erweitert werden muss, um diese "Kontrollübergabe" vom Spieler an den Testcode zu ermöglichen. Ob das Input-System das kann, weiß ich aber nicht. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
jtuchel Geschrieben 23. Juli 2021 Autor Melden Share Geschrieben 23. Juli 2021 Genau, also ich habe das mal erweitert. Das Behaviour wäre public class MovementBehaviour : MonoBehaviour { public void Move(InputAction.CallbackContext inputContext) { Vector2 movementDirection = inputContext.ReadValue<Vector2>(); transform.position += new Vector3(movementDirection.x, movementDirection.y, transform.position.z); } } und der Test dazu wäre zb [TestFixture] public class MovementBehaviourTests { [Test] public void ItShouldMove() { GameObject gameObject = new GameObject(); MovementBehaviour movementBehaviour = gameObject.AddComponent<MovementBehaviour>(); // movementBehaviour.Move(); // pass in Vector2.right Assert.AreEqual(gameObject.transform.position, Vector3.right); } } Mir ist halt nicht klar, wie ich im Test den Parameter richtig übergebe. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
malzbie Geschrieben 23. Juli 2021 Melden Share Geschrieben 23. Juli 2021 Wie der Parameter richtig übergeben wird, kann ich dir auch nicht sagen. Das ist jedenfalls ein Json Ausdruck. Aber vielleicht kriegst du das raus, denn du kannst, wenn du ein Input Action Asset erstellt hast, im Inspector bei dem Asset einen haken setzen. Dadurch wird ein c# Script mit gleichem Namen wie dein Asset erzeugt. Wenn du dir das mal anschaust, kommst du vielleicht dahinter. Ich steige da nicht ganz so durch. Jedenfalls kannst du auch mittels dieses Scripts eine andere Art der Inputabfrage erzeugen. Siehst du unten im Script. Wie dem auch sei. Du willst ja eigentlich nur über ein Testscript Werte in deinen player rein bringen und so tun als ob du ein Input bekommen würdest. So habe ich es jedenfalls verstanden. Warum willst du dafür unbedingt in die Methode rein springen, die ein InputAction.CallbackContext erwartet. Bau dir doch eine public Methode, die dein Vector2 aufnehmen kann und dann genauso die Bewegung des Players bedient. So etwa: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class InputTester : MonoBehaviour { GameControls controls; public Vector2 movementDirection; // falls du die Werte abfragen willst void Awake() { controls = new GameControls(); // input Kontrollen erstellen controls.Gameplay.XAxis.performed += ctx => MoveLR(ctx); controls.Gameplay.XAxis.canceled += ctx => MoveLR(ctx); } private void OnEnable() { controls.Gameplay.Enable(); } private void OnDisable() { controls.Gameplay.Disable(); } private void Update() { transform.position += new Vector3(movementDirection.x, movementDirection.y, transform.position.z); } void MoveLR(InputAction.CallbackContext context) { var direction = context.ReadValue<Vector2>(); movementDirection = direction; } public void TesteLR(Vector2 direction) // hier springt der Tester rein { movementDirection = direction; } } In der Update wird movementDirection für das setzen der Position genutzt. Ob die Variable nun in der Methode beschrieben wurde, die vom Input angesprochen wird, oder von der Methode, die dein Tester anspricht. Ist doch eigentlich egal, oder? Aber vielleicht habe ich es immer noch nicht richtig vertstanden...oder du willst/kannst das Playerscript nicht mit einer weiteren Methode bestücken. Na ja. Vielleicht hilft's ja doch. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.