Unity Event 청취자 수 없음

6018 단어 UnityC#

개요


Unity Event에 Unity Action 유형의 청취자를 등록하고 사용합니다.
이들 청중의 행위는 등록 방법에 따라 다소 다르다.
이번에 우리는 등록을 받지 못한 청취자 수, 원인과 대책을 총결하였다.

Unity Event 청취자 종류


Unity Event
* 영구 청중
* 비영구적 청중
라는 두 가지 유형이 있다.

영구 청중


검사기에서 영구적인 청중을 등록합니다.
UGUI의 Buttton의 OnClick에 등록하고 싶습니다.

직접 만든 반이라도 엄숙해진 유니티 이벤트라면 검사기에 등록할 수 있다.
매개변수가 있는 유니티 이벤트(Unity Event<T0> 등)의 학급을 물려받았고, Serializable Attribute를 더하면 OK다.
이 영구적인 청중은 실행 중에 등록, 삭제할 수 없지만 State가 존재하기 때문에 ON/OFF가 가능합니다.
https://docs.unity3d.com/jp/current/ScriptReference/Events.UnityEventCallState.html

청중


비영구적인 청중은 스크립트에서 등록합니다.event.AddListener(action);이런 식으로 로그인합니다.
상반되다event.RemoveListener(action)에서 청자를 삭제합니다.

청취자 수를 얻지 못하다


스크립트에서 로그인한 청취자 수를 얻었습니다. 청중이 존재할 때 청취자 처리를 하고 싶고, 존재하지 않을 때 다른 처리를 하고 싶었지만 0이 되어 청취자 수를 얻지 못했습니다.

까닭


GetPersistent Event Count 방법을 사용하면 청중 수를 얻을 수 있지만 영구 청중 수와 비영구 청중 수는 얻을 수 없다.나 못해.안돼.

처리하다.


어떻게든 얻으려면 유닛 이벤트에 로그인할 때 로그인 수를 계산하는 랩 함수나 클래스를 만드는 것이 좋다.
그러나 비영구적인 청중은 등록할 때 중복을 점검하지 않고 삭제할 때 중복된 부분을 모두 삭제하는데, 추가·삭제의 성공·실패 등을 이룰 수 없기 때문에 해시셋적인 별도 관리 액션의 구조가 필요하다.

총결산

  • Unity Event 청중은 검사기에서 등록된 영구 청중, 스크립트에서 등록된 비영구 청중이 있습니다.
  • 영구 청중의 수량은 스크립트에서 얻을 수 있지만 비영구 청중의 수량은 얻을 수 없다.
  • 비지구성 청중의 로그인 수는 랩류 등을 만들어 스스로 계산해야 한다.
  • 추기(3/1122:43) 반사로 획득


    나는 강제로 반사를 통해 얻었다.
    퍼포먼스에서는 하고 싶은 일에 맞지 않지만, 에디터에서 사용하거나 상자를 축소하면 못 쓰는 것도 아닌 것 같다.
    public static int GetRuntimeEventCount(this UnityEventBase unityEvent) 
    {
        Type unityEventType = typeof(UnityEventBase);
    
        Assembly libAssembly = Assembly.GetAssembly(unityEventType);
    
        Type invokableCallListType = libAssembly.GetType("UnityEngine.Events.InvokableCallList");
        Type baseInvokableCallType = libAssembly.GetType("UnityEngine.Events.BaseInvokableCall");
        Type listType = typeof(List<>);
        Type baseInvokableCallListType = listType.MakeGenericType(baseInvokableCallType);
    
        FieldInfo callsField = unityEventType.GetField("m_Calls", BindingFlags.Instance | BindingFlags.NonPublic);
        FieldInfo runtimeCallsField = invokableCallListType.GetField("m_RuntimeCalls", BindingFlags.Instance | BindingFlags.NonPublic);
    
        var calls = callsField.GetValue(unityEvent);
        var runtimeCalls = runtimeCallsField.GetValue(calls);
        PropertyInfo countProperty = baseInvokableCallListType.GetProperty("Count");
    
        return (int)countProperty.GetValue(runtimeCalls, null);
    }
    

    좋은 웹페이지 즐겨찾기