Jump to content
Unity Insider Forum

Input System


Kurumi-chan

Recommended Posts

Guten Morgen,

ich nutze das neue Inputsystem von Unity und habe eine reine Tastatursteuerung. Meine Frage dazu ist jetzt, gibt es irgendeine einfache Möglichkeit Buttons zu gliedern, dass wenn man z.B. 2 Panels mit verschiedenen Buttons hat, nicht Panelübergreifend navigieren kann? Aktuell setze ich die entsprechenden Buttons immer als inaktiv, aber evtl. gibt es ja eine einfachere Lösung. 

Lg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn ich dich richtig verstehe, dann hat das nix mit dem Input-System zu tun. Du benutzt vermutlich UGUI, also einen Canvas mit UI-GameObjects drin, richtig?

@malzbie Es geht darum, dass man nur innerhalb eines Panels navigieren können soll; es sollen also die horizontalen Navigations-Übergänge in diesem Beispiel weg:

grafik.png

@Kurumi-chan Du kannst meines Wissens nach keine Gruppen hierfür anlegen. Zumindest nicht, ohne das EventSystem aufzureißen und darin herumzuwühlen. Was du aber machen kannst, ist die Buttons anders einzustellen. Das EventSystem richtet sich bei der Navigation über die interaktiven UI-Elemente nach den Einstellungen, die sie haben. Anders gesagt: Jeder Button weiß, zu welchen anderen Buttons man von ihm aus navigieren kann. Wenn du dir die Einstellungen einer deiner Buttons anschaust, kannst du mit dem Knopf "Visualize" diese gelben Pfeile anschalten. Mit dem Dropdown-Menü darüber kannst du dann einstellen, woher der Button weiß, wer alles als "Nachbar" gilt. In meinem Beispielbild könnte man bei allen Buttons die "Horizontal"-Option ausschalten, sodass nur noch vertikale Pfeile zugelassen werden. Im Notfall kannst du aber auch auf "explicit" stellen und alle vier Nachbarn selbst bestimmen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

@malzbie Ja, genau wie Sascha es schon gesagt hat meinte ich es auch. Hätte mich da etwas genauer ausdrücken sollen, sorry dafür. Nur weil ich weiß worum es geht, müssen andere das nicht auch 🙂

@Sascha Ja, das mache ich auch schon so, nur sind z.B. Items oder Actors dynamisch mit Instantiate() erstellt worden, weshalb ich da nicht mit explicit arbeiten kann? Deswegen hatte ich ja auf einen besseren Weg gehofft. Sowas wie Layout Sachen usw. habe ich ja alle schon getestet gehabt.

Welchen Grund gäbe es, von einem Panel in ein anderes zu navigieren, dass es nicht von Haus aus schon nicht geht?

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 13 Minuten schrieb Kurumi-chan:

nur sind z.B. Items oder Actors dynamisch mit Instantiate() erstellt worden, weshalb ich da nicht mit explicit arbeiten kann?

Hmja, ich finde da auch gerade nichts. Man könnte da höchstens überlegen, ob man das Button-Layout statisch definiert und dann nur die Inhalte zur Laufzeit anlegt.

vor 16 Minuten schrieb Kurumi-chan:

Welchen Grund gäbe es, von einem Panel in ein anderes zu navigieren, dass es nicht von Haus aus schon nicht geht?

Das ist halt Standard in den allermeisten Spielen. Wenn über Button A Button B ist, dann kannst du da hin navigieren, selbst wenn dazwischen grafisch irgendeine Grenze liegt. Unity hat halt auch kein Konzept für Panels in diesem Sinne. Panels sind einfach nur Image-GameObjects.

Was du halt machen kannst ist, dein eigenes InputModule zu schreiben. Das ersetzt dann das InputModule, das zusammen mit der EventSystem-Komponente auf dem EventSystem-GameObject liegt. Diese Komponente ist es nämlich, die Inputs nimmt und dann irgendwelche Befehle in das UI gibt. Wenn du dein eigenes InputModule schreibst, kannst du darin definieren, was du willst. So kannst du das aktuell markierte Selectable nach seinen Nachbarn fragen und dann auf beliebige Art definieren, ob zu diesem Nachbarn gesprungen werden darf oder nicht. So könntest du eine Komponente namens "GroupPanel" oder so erstellen. Und wenn dein aktueller Button in den Parents ein anderes GroupPanel findet als es der vorgschlagene Nachbar tut, dann wird das move-Event einfach nicht ausgeführt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmm, sehr schade, aber ich habe es mir leider bereits gedacht. Habe ja schon Stunden mit googlen verbracht 🙂

Also ich habe jetzt mal versucht den aktuellen Button abzufangen, allerdings ohne Erfolg. Ich habe dazu versucht das Eventsystem über den Inspector zu setzen und das Eventsystem von InputSystemUIInputModule zu übernehmen, indem ich die Inputklasse davon erben lasse.

Ich bekomme auf egal welchem wege immer diese Fehler:

NullReferenceException: Object reference not set to an instance of an object
InputController.test (UnityEngine.EventSystems.EventSystem e) (at Assets/InputController.cs:29)
InputSO.OnNavigate (UnityEngine.InputSystem.InputAction+CallbackContext context) (at Assets/InputSO.cs:29)
UnityEngine.InputSystem.Utilities.DelegateHelpers.InvokeCallbacksSafe[TValue] (UnityEngine.InputSystem.Utilities.CallbackArray`1[System.Action`1[TValue]]& callbacks, TValue argument, System.String callbackName, System.Object context) (at Library/PackageCache/com.unity.inputsystem@1.3.0/InputSystem/Utilities/DelegateHelpers.cs:46)
UnityEngine.InputSystem.LowLevel.<>c__DisplayClass7_0:<set_onUpdate>b__0(NativeInputUpdateType, NativeInputEventBuffer*)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate(NativeInputUpdateType, IntPtr)
NullReferenceException while executing 'started' callbacks of 'Menu/Navigate[/Keyboard/upArrow,/Keyboard/downArrow,/Keyboard/leftArrow,/Keyboard/rightArrow]'
UnityEngine.InputSystem.LowLevel.NativeInputRuntime/<>c__DisplayClass7_0:<set_onUpdate>b__0 (UnityEngineInternal.Input.NativeInputUpdateType,UnityEngineInternal.Input.NativeInputEventBuffer*)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate (UnityEngineInternal.Input.NativeInputUpdateType,intptr)

Das gleiche auch für performed und canceled.

Das dass Eventsystem nicht existiert sehe ich, ich verstehe nur nicht warum?

Vielleicht auch gleich mal die Scripts, ist evtl. dann einfacher zu sehen.

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.EventSystems;

[CreateAssetMenu(menuName = "InputManager")]
public class InputSO : ScriptableObject, InputManager.IMenuActions
{
    private InputManager inputManager;

    public event UnityAction<Vector2> Movement;
    public event UnityAction<EventSystem> e;
    public event UnityAction t;

    private void OnEnable()
    {
        if (inputManager == null) inputManager = new InputManager();
        inputManager.Menu.SetCallbacks(this);
        inputManager.Menu.Enable();
    }

    private void OnDisable()
    {
        inputManager.Menu.Disable();
    }

    public void OnNavigate(InputAction.CallbackContext context)
    {
      	//inputManager = new InputManager(); Zum Testen, da hier null
        Debug.Log(inputManager.GetES()); 
        e?.Invoke(inputManager.GetES());
        Movement?.Invoke(context.ReadValue<Vector2>());
    }

    public void OnSubmit(InputAction.CallbackContext context)
    {
        //throw new System.NotImplementedException();
    }

    public void OnCancel(InputAction.CallbackContext context)
    {
        //throw new System.NotImplementedException();
    }
}

using UnityEngine;
using UnityEngine.EventSystems;

public class InputController : MonoBehaviour
{
    [SerializeField] private InputSO inputReader;
    [SerializeField] private EventSystem es;
    private void OnEnable()
    {
        inputReader.Movement += ReadMovementInput;
        inputReader.e += test;
    }

    private void OnDisable()
    {
        inputReader.Movement -= ReadMovementInput;
    }

    private void ReadMovementInput(Vector2 direction)
    {
        
        Debug.Log(direction);
    }

    private void test(EventSystem e)
    {
     	Debug.Log(es.currentSelectedGameObject);
        Debug.Log(e.currentSelectedGameObject);
    }
}

Der erst hier ist der Standard, der von Unity erstellt wurde
public partial class @InputManager : InputSystemUIInputModule, IInputActionCollection2, IDisposable
{
  	public EventSystem GetES()
    {
        return eventSystem;
        //Debug.Log(eventSystem.currentSelectedGameObject);
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmm... ich mag mich irren, aber das sieht so aus, als wärst du wieder im Input-System gelandet. Das ist aber nicht der Plan.

Du machst eher eine Klasse

public class MyInputModule : BaseInputModule

und überschreibst die Process()-Methode. Da besorgst du dir auf beliebige Weise deinen Input und machst damit, was du willst.

Mit

eventSystem.currentSelectedGameObject

holst du dir das aktuell selektierte UI-Element. Dann holst du dir mit

GetComponent<Selectable>()

die Selectable-Komponente davon. Du schaust, in welche Richtung der Input zeigt und holst dir, z.B. mit FindSelectable, den Nachbarn in diese Richtung. Dann noch zweimal GetComponentInParent und ein Vergleich. Am Ende sendest du, wenn ein neues Objekt angewählt werden soll, mit

ExecuteEvents.Execute()

das moveEvent. Etwa so:

var data = new AxisEventData(eventSystem);
data.moveVector = inputDirection;
data.moveDir = moveDirection;
return ExecuteEvents.Execute(currentlySelectedGameObject, data, ExecuteEvents.moveHandler);

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Oha, vielen dank Sascha, dass werde ich sofort mal ausprobieren ☺️

Dann bleibt nur noch die Frage, soll ich dazu quasi InputSystemUIInputModule überschreiben, bzw. brauche ich das dann nicht mehr, oder soll ich das einfach in 

public partial class @InputManager IInputActionCollection2, IDisposable

 realisieren? Das ist ja das Script, was mir von Unity erstellt wurde, als ich die Keybindings gemacht habe, also die Actionmap quasi.

Und wo kann ich das neue Script dann einbinden, den im EventSystem im Inspector kann ich das Script ja leider nicht verändern und damit wäre ja dann auch jede meiner Änderungen wirkungslos?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Joa, da musst du ein bisschen schauen. Ich weiß nicht, ob man sinnvoll eine der nicht-abstrakten InputModule-Klassen überschreiben kann. In jedem Fall musst du das aktuelle InputModule vom EventSystem-GO runterschmeißen und stattdessen dein eigenes drauftun.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dumm ist halt auch, das in InputSystemUIInputModule ziemlich alles private ist. Selbst ProcessNavigation(ref m_NavigationState) geht schon nicht und das ist fast die einzige Funktion in Process 😂 Würde ja schon gerne so viel es geht übernehmen.

Dann bin ich mal gespannt, ob ich das schaffe. Wirkt imo sehr schwer, aber ich freue mich drauf 😁

Und ich dachte mir so zum lernen fängst mal mit dem leichtesten an - dem Menu. Dann bin ich mal gespannt, was sonst noch so auf mich zukommt 🤔

Link zu diesem Kommentar
Auf anderen Seiten teilen

Naja, ein Menü mit zur Laufzeit generierten UI-Elementen ist schon ganz fix nicht mehr "was leichtes" :)

Eine andere Idee hab ich sonst noch: Du kannst dein eigenes UI-Element machen, das (iirc) von Selectable erbt. Das stellt dann ein gesamtes Panel dar und fängt Navigations-Inputs ab. Wenn es die schluckt, dann navigierst du auch nicht zu einem anderen Selectable. Dann hast du da drin deine Buttons (die aber gar keine Selectables sind) und das Panel kümmert sich darum, was ausgewählt sein soll.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok, das verstehe ich gerade nicht wirklich^^

Zitat

Naja, ein Menü mit zur Laufzeit generierten UI-Elementen ist schon ganz fix nicht mehr "was leichtes" :)

Naja, bisher eigentlich schon. Also es war jetzt nicht mega leicht oder so, aber bisher hat alles sehr gut funktioniert. Was mich sehr überrascht hat. Das einzige Problem ist gerade echt die Sache mit dem navigieren durchs Menu. Das hätte ich mir tatsächlich nicht so krampfig vorgestellt.

Da kannst du es mal sehen, es sind 3 verschiedene Menus. Einmal das obere, dann die Items und noch das der Actors. 

Unbenannt-1.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Alle UI-Elemente, mit denen du interagieren kannst, sind Selectables. Buttons, Slider, Checkboxen. Wenn du einen Button markiert hast und "rechts" drückst, dann sagt der Button "interessiert mich nicht", und das EventSystem schaut, ob rechts neben dem Button ein anderes Selectable ist, zu dem navigiert werden kann.

Wenn du allerdings einen (horizontalen!) Slider markiert hast und dann "rechts" drückst, dann schluckt der Slider das Event und sagt "damit kann ich was anfangen!". Der Knopf bewegt sich ein Stück nach rechts damit hat sichs. Da das Event nämlich geschluckt wurde, versucht das Event-System nicht mehr, das zu verarbeiten. Der Slider hat ja schon selbst darauf reagiert.

Und genau so könntest du ein Panel-Element bauen. Einfach ein Grid, in dem Buttons drin sind, die aber gar keine echten Buttons sind. Sie sehen nur so aus - aber welcher markiert ist und was beim Bestätigen passiert, das entscheidet alles das Panel. Es schluckt alle vier Bewegungs-Events und ändert, welcher seiner Buttons markiert ist. Aus dem Panel heraus kommt man dann aber nicht, solange das Panel die Events weiter schluckt. Kannst du ja implementieren, dass es das macht, selbst wenn du schon den äußersten Button markiert hast.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok, ich glaube ich kann dir folgen. Wäre auch ein Versuch wert, dass mal zu probieren. Zumindest bei dynamischen Listen. Wäre dann ja quasi auch sowas, als würde ich das Inputsystem neuschreiben, nur dann halt nicht mehr für Inputs, wenn ich das so richtig verstanden habe. Der Button selbst wäre ja dann nur die gesamte Liste. Das Panel müsste man dann inaktiv setzen, damit man nicht mehr navigieren kann und sobald man zurück möchte, würde man einfach wieder aktiv setzen und könnte ganz normal weiter machen. Wenn ich das so richtig verstanden habe 😅

Ach und dann auch mal eine Frage zum Slider. Die Items haben aktuell noch keinen, brauchen sie aber logischerweise noch. In dem Fall müsste ich den Slider selektieren und nicht das Item? Weil dort hatte ich auch schon das Problem, dass es nicht funktionierte, habe es aber erstmal hinten angestellt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du in deinem kontrollsüchtigen Panel noch verschiedene Elemente pro Item unterbringen willst, dann muss das Panel sich vermutlich darum kümmern, dass diese bedienbar sind. Wäre schon elegant, wenn du da ganz normale UI-Elemente einbauen könntest, und das Panel versteht die und leitet Events an die weiter, ohne dass sie selektiert werden. Ob das überhaupt geht, weiß ich nicht. Kann ich mir aber vorstellen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also technisch gesehen habe ich das Problem gelöst, nur kann ich leider das Inputsystem nicht unterbrechen und in der Canceled Phase sieht man den Button wieder zurückspringen. Also er geht erst auf das neue Element und wird anschließend zurück zu seinem Ursprung gesetzt. Die "OK" Ausgabe erfolgt immer so, wie ich es mir vorgestellt habe.

Gibt es irgendeine Möglichkeit an der Stelle das Inputsystem zu unterbrechen, das er nicht selbst dann noch das ausführt, wodurch mein move halt für die Tonne ist? Mit Enable, oder SetActive kann man zwar pausieren, aber sobald man wieder aktiviert, macht er einfach da weiter, wo er aufgehört hat 😓

public void test(InputActionPhase phase)
    {
        var moveVector = inputDirection;
        if (phase == InputActionPhase.Started)
        {
            currentBtn = EventSystem.current.currentSelectedGameObject;
            currentParent = EventSystem.current.currentSelectedGameObject.transform.parent;
        }
        else if (phase == InputActionPhase.Performed)
        {
            newSelectable = EventSystem.current.currentSelectedGameObject.GetComponent<Selectable>().FindSelectable(moveVector);
            if (newSelectable != currentBtn)
            {
                newParent = newSelectable.transform.parent;
                if (newParent != currentParent)
                {
                    EventSystem.current.SetSelectedGameObject(currentBtn);
                    Debug.Log("OK");
                }
            }
        }
        else if (phase == InputActionPhase.Canceled)
        {
            EventSystem.current.SetSelectedGameObject(currentBtn);
        }
    }

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Jeah, nach gut 20 Stunden Arbeit bin ich nun fertig und es funktioniert völlig fehlerfrei. Hätte ich nie gedacht und wollte schon aufgeben 😂 ☺️

Wer möchte kann das Script gerne nutzen, vielleicht hat ja auch noch jemand bedarf an sowas. Dazu einfach das Input Script dem EventSystem unter das "Input System UI Input Module"(Wichtig, da darf nichts anderes dazwischen sein) geben und die Tags "Horizontal Menu" und "Vertical Menu" hinzufügen und den entsprechenden Panels zuweisen. Das InputModule, welches man erstellt muss man entweder umbenennen in InputManager, oder in Script InputSO alle "InputManger" durch was anderes ersetzen. Das gleich gilt auf für die ActionMaps. Bei mehr als einer wird man allerdings noch mehr Anpassungen vornehmen müssen, sofern diese die Funktionalität auch benötigen.

Wenn noch jemand Anmerkungen und Verbesserungen hat, gerne her damit 😁

Input.cs
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.UI;
using UnityEngine.UI;

internal struct NavigationModel
{
    public Vector2 move;
    public int consecutiveMoveCount;
    public MoveDirection lastMoveDirection;
    public float lastMoveTime;
    public AxisEventData eventData;

    public void Reset()
    {
        move = Vector2.zero;
    }
}

public class Input : BaseInputModule
{
    public InputSO inputSO;
    private NavigationModel m_NavigationState;
    private string parentTag;
    private bool isDynamicList;

    protected override void OnEnable()
    {
        base.OnEnable();
        inputSO.moveVector += SetInputDirection;
        inputSO.navigate += CheckDynamicListObject;
        inputSO.submit += SetParentOnSubmit;
    }

    protected override void OnDisable()
    {
        base.OnDisable();
        inputSO.moveVector -= SetInputDirection;
        inputSO.navigate -= CheckDynamicListObject;
        inputSO.submit -= SetParentOnSubmit;
    }

    public void OnClick()
    {
        eventSystem.SetSelectedGameObject(eventSystem.firstSelectedGameObject);
    }

    private void ProcessNavigation(ref NavigationModel navigationState)
    {
        var usedSelectionChange = false;
        if (eventSystem.currentSelectedGameObject != null)        
        {
            var data = GetBaseEventData();
            ExecuteEvents.Execute(EventSystem.current.currentSelectedGameObject, data, ExecuteEvents.updateSelectedHandler);
            usedSelectionChange = data.used;
        }

        if (!eventSystem.sendNavigationEvents) return;

        var movement = navigationState.move;
        if (!usedSelectionChange && (!Mathf.Approximately(movement.x, 0f) || !Mathf.Approximately(movement.y, 0f)))
        {
            var time = Time.unscaledTime;
            var moveVector = navigationState.move;

            var moveDirection = MoveDirection.None;
            if (moveVector.sqrMagnitude > 0)
            {
                if(parentTag == "Horizontal Menu")
                {
                    if (Mathf.Abs(moveVector.x) > Mathf.Abs(moveVector.y))
                        moveDirection = moveVector.x > 0 ? MoveDirection.Right : MoveDirection.Left;
                }
                else if (parentTag == "Vertical Menu")
                {
                    if (Mathf.Abs(moveVector.x) < Mathf.Abs(moveVector.y))
                        moveDirection = moveVector.y > 0 ? MoveDirection.Up : MoveDirection.Down;
                }
                else if (Mathf.Abs(moveVector.x) > Mathf.Abs(moveVector.y))
                    moveDirection = moveVector.x > 0 ? MoveDirection.Right : MoveDirection.Left;
                else
                    moveDirection = moveVector.y > 0 ? MoveDirection.Up : MoveDirection.Down;
            }

            if (moveDirection != m_NavigationState.lastMoveDirection) m_NavigationState.consecutiveMoveCount = 0;

            if (moveDirection != MoveDirection.None)
            {
                var allow = true;
                if (m_NavigationState.consecutiveMoveCount != 0)
                {
                    if (m_NavigationState.consecutiveMoveCount > 1)
                        allow = time > m_NavigationState.lastMoveTime + GetComponent<InputSystemUIInputModule>().moveRepeatRate;
                    else
                        allow = time > m_NavigationState.lastMoveTime + GetComponent<InputSystemUIInputModule>().moveRepeatDelay;
                }
                if (allow)
                {
                    Selectable newBtn = eventSystem.currentSelectedGameObject.GetComponent<Selectable>().FindSelectable(moveVector);
                    if (newBtn.transform.parent.tag != parentTag) return;

                    var eventData = m_NavigationState.eventData;
                    if (eventData == null)
                    {
                        eventData = new AxisEventData(eventSystem);
                        m_NavigationState.eventData = eventData;
                    }
                    eventData.Reset();

                    eventData.moveVector = moveVector;
                    eventData.moveDir = moveDirection;

                    ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, eventData, ExecuteEvents.moveHandler);
                    usedSelectionChange = eventData.used;

                    m_NavigationState.consecutiveMoveCount = m_NavigationState.consecutiveMoveCount + 1;
                    m_NavigationState.lastMoveTime = time;
                    m_NavigationState.lastMoveDirection = moveDirection;
                }
            }
            else
                m_NavigationState.consecutiveMoveCount = 0;
        }
        else m_NavigationState.consecutiveMoveCount = 0;
       
        if (!usedSelectionChange && EventSystem.current.currentSelectedGameObject != null)
        { 
            var submitAction = GetComponent<InputSystemUIInputModule>().submit?.action;
            var cancelAction = GetComponent<InputSystemUIInputModule>().cancel?.action;
            var data = GetBaseEventData();            
            if (cancelAction != null && cancelAction.WasPressedThisFrame())
                ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler);
            if (!data.used && submitAction != null && submitAction.WasPressedThisFrame())
                ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler);
        }
    }

    public override void Process()
    {
        ProcessNavigation(ref m_NavigationState);
        
        if (parentTag != "Horizontal Menu" && parentTag != "Vertical Menu")
        {
            parentTag = eventSystem.currentSelectedGameObject.transform.parent.tag;
            UnityEditorInternal.ComponentUtility.MoveComponentDown(this);
            isDynamicList = false;
        }
    }

    public void SetInputDirection(Vector2 moveVector)
    {
        m_NavigationState.move = moveVector;
    }

    public void CheckDynamicListObject()
    {
        parentTag = eventSystem.currentSelectedGameObject.transform.parent.tag;
        if (!isDynamicList)
        {
            if (parentTag == "Horizontal Menu" || parentTag == "Vertical Menu")
            {
                isDynamicList = true;
                UnityEditorInternal.ComponentUtility.MoveComponentUp(this);
            }
        }
    }

    public void SetParentOnSubmit()
    {
        parentTag = eventSystem.currentSelectedGameObject.transform.parent.tag;
    }
}

InputSO.cs
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

[CreateAssetMenu(fileName = "AdvancedInput")]
public class InputSO : ScriptableObject, InputManager.IMenuActions
{
    public InputManager InputManager;

    public event UnityAction navigate;
    public event UnityAction<Vector2> moveVector;
    public event UnityAction submit;

    private void OnEnable()
    {
        if (InputManager == null) InputManager = new InputManager();
        InputManager.Menu.SetCallbacks(this);
        InputManager.Menu.Enable();
    }

    private void OnDisable()
    {
        InputManager.Menu.Disable();
    }

    public void OnCancel(InputAction.CallbackContext context)
    {
        //throw new System.NotImplementedException();
    }

    public void OnNavigate(InputAction.CallbackContext context)
    {
        navigate?.Invoke();
        moveVector?.Invoke(context.ReadValue<Vector2>());
        
    }

    public void OnSubmit(InputAction.CallbackContext context)
    {
        submit?.Invoke();
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...