반응형

 

 

 

 

인벤토리 구현하는 중에 Toggle과 ToggleGroup을 사용하던 중, 인벤토리를 껐다켜면 첫번째 토글이 무조건 활성화되게 하려고 OnEnable함수에서 toggle.isOn의 값을 변경했는데, onValueChanged와 같은 콜백은 호출이 되지만 ToggleGroup이 작동을하지 않아서 첫번째 토글이 활성화되지 않았다.

찾아보니 Toggle의 OnDisable에서 ToggleGroup에 등록된 자신을 해제한다고한다. (대체 왜..?)

 

즉, 각 Toggle 컴포넌트가 비활성화되면 ToggleGroup에서 자신을 해제하고 활성화되면 재등록이 이루어지는것 같다.

(ToggleGroup에서 OnEnable함수에 m_Toggles.Count의 로그를 찍어보면 0으로 나온다.)

 

결국 ToggleGroup하고 Toggle을 상속받는 새 컴포넌트를 만들어 Toggle의 OnDisable을 override로 재정의해줘서 해결했다.

 

 

Toggle 컴포넌트

using UnityEngine.UI;

public class SlotToggle : Toggle
{
    protected override void OnDisable() { }
}

 

 

ToggleGroup 컴포넌트

using UnityEngine.UI;

public class InventoryToggleGroup : ToggleGroup
{
    protected override void OnEnable()
    {
        var toggle = GetFirstToggle();
        if (toggle != null)
        {
            toggle.isOn = true;
        }
    }

    private Toggle GetFirstToggle()
    {
	if(m_Toggles.Count <= 0)
        {
            return null;
        }
        
        Toggle toggle = m_Toggles[0];
        for(int i = 1; i < m_Toggles.Count; i++)
        {
            if(toggle.transform.GetSiblingIndex() > m_Toggles[i].transform.GetSiblingIndex())
            {
                toggle = m_Toggles[i];
            }
        }

        return toggle;
    }
    
    protected override void OnDisable()
    {
        base.OnDisable();
        for (int i = 0; i < m_Toggles.Count; i++)
        {
            m_Toggles[i].isOn = false;
        }
    }
}
  • GetSiblingIndex의 값을 비교해서 첫번째 Toggle 컴포넌트를 가져온다. (한번씩 Toggle 순서가 뒤섞이는 문제가 발생해서 함수를 추가로 작성했다. 꼭 저렇게할 필요 없이 Sort()함수를 사용해도 무관할듯하다.)
  • OnDisable()에서 게임오브젝트가 비활성화 될 때, 모든 토글의 isOn을 꺼주는 이유는 다시 활성화될 때 특정 토글의 isOn이 켜져있으면 활성화될 때 켜주고싶은 토글의 isOn이 인스펙터창에서 활성화되지 않아 Graphic의 표시가 변경되지 않는다. (OnValueChanged 콜백만 호출됨)

 

 

 

 

반응형

+ Recent posts