카테고리 없음

Vive Input, List<action>으로 관리해보기.

BaekNohing 2022. 3. 14. 00:04

Vive Input을 다룰 때, 여러가지 Input을 다뤄야 하는데. 각 버튼의 상태를 

public SteamVR_Action_Boolean Bumper;
...
if (Bumper.GetState(SteamVR_Input_Sources.Any))

같은 느낌으로 하나하나 체크해 줘야 하는 모양이다..  이게 인스펙터상에서 추가 + 제거가 얼마든지 일어날 수 있기 때문에 (임의로 window>steamVR Input 인터페이스에서, 사용할 버튼들을 매핑할 수 있다) 스크립트 안에 동작을 바로 넣는 것은 좋지 않은 방법 같았고 (나중에 쓸 버튼을 바꾸거나. 동작에 대한 기획이 바뀌면 골치가 아파질 것 같으니까) 

고민하다가, Dictionary로 Btn마다 event를 할당해서, 버튼이 눌릴 때 마다 실행되도록 하는게 좋을 것 같다고 생각했다. event는 싱글톤으로 구현해서, "버튼이 눌렸을 때 이런걸 하면 좋겠는데.." 하는 부분들을 자유롭게 접근해서 추가/제거 할 수 있도록 말이다. 

문제는 Dictionary<string, event> 따위의 형식 선언이 불가능하다는 점이었는데, 어떻게 할까 하다가 List<action>을 사용해서 action을 쭉 붙여서, 버튼을 눌렀을 때 List를 훑으면서 실행할 수 있도록 했다. 

<delegateManager.cs>


public class delegateManager : Singletone<delegateManager>
{
	private Dictionary<string, List<System.Action>> inputDelegate = new Dictionary<string, List<System.Action>>();
    
    public Dictionary<string, List<System.Action>> getInputDelegate() { return inputDelegate; }
    public void setInputDelegate(string name, System.Action function)
    {
        List<System.Action> actions;

        if (!inputDelegate.TryGetValue(name, out actions))
        {
            actions = new List<System.Action>();
            inputDelegate.Add(name, actions);
        }
        actions.Add(function);
    }
}

이걸로 Action리스트를 관리하고.

private void btnAction(actionName actionName)
{
    Debug.Log($"btnAction : {actionName}");
    if (delegateManager.instance.getInputDelegate().
        TryGetValue(actionName.ToString(), out List<System.Action> actions))
        foreach (System.Action action in actions)
            action?.Invoke();
}

버튼이 눌렸을 때, 할당 된 action들이 있다면 Invoke()해 줄 수 있도록 했다. 

actionName은 enum이기 때문에, Dictionary<int, ...>를 할까 고민했었는데. 테스트나 이런걸 위해 임시로 Action을 넣어야 할 때 String형식으로 명식적인 형태의 이름을 붙이는게 좋을 것 같아서. (좀 낭비가 될 수 있겠지만) string으로 받도록 했다. 

delegateManager.instance.setInputDelegate(actionName.bumper, testDebug);

나중에 뭔가 추가하고싶으면, 이런식으로 추가하면 된다.