public class DontDestroy<T> : MonoBehaviour where T : DontDestroy<T>
{
    private static T instance;
    private void Awake()
    {
        if (instance == null)
            instance = this as T;
        else
            Destroy(gameObject);
        DontDestroyOnLoad(gameObject);
    }
}
    public IEnumerator FadeIn(float time)              
    {
        Color color = image.color;
        while (color.a > 0f)
        {
            color.a -= Time.deltaTime / time;
            image.color = color;
            yield return null;
        }
    }
    
        public IEnumerator FadeOut(float time)
    {
        Color color = image.color;
        while (color.a < 1f)
        {
            color.a += Time.deltaTime / time;
            image.color = color;
            yield return null;
        }
    }
public abstract class GenericSingleTon<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;
    public static T instance
    {
        get
        {
            if (_instance == null)
            {
                T[] objectList = Resources.FindObjectsOfTypeAll<T>();
                if (objectList.Length > 0)
                    (objectList[0] as GenericSingleTon<T>).Awake();
            }
            return _instance;
        }
    }

    private void Awake()
    {
        if (_instance == null)
            _instance = this as T;
    }
}

게임의 튜토리얼을 제작하다가 다른 input은 무시하고 정해진 버튼만 클릭할 수 있게 해야 하는 상황이 생겼다.

여러가지 방법을 고민해봤다. 나의 경우는 ScrollRect와 Grid Layout Group을 사용해서 버튼 오브젝트의 parent를 바꾸거나 버튼의 sibling을 추가하면 안됐다. 그러다가 내린 결론.

Canvas의 최상단에 주어진 버튼의 rect만 제외하고는 Raycast Target인 투명한 이미지로 가려서 해당 버튼만 눌릴 수 있게..

 

예시 (이후 투명하게 변경)

이렇게 하기 위해서는 총 4개(좌측, 우측, 상단, 하단)의 이미지 오브젝트가 필요하다.

#주의 Canvas의 최상단에 있어야 input을 막을 수 있다.

 

이미지 오브젝트들의 anchor와 pivot은 다음과 같이 설정해준다.

좌측 블럭
우측 블럭
상단 블럭
하단 블럭

 

코드는 다음과 같다.

 

    [SerializeField]
    private RectTransform[] _blocks; // 4개의 이미지 객체들
    
    private enum Block
    {
        Left,
        Right,
        Top,
        Bottom
    }
    
    // targetRectTM : 유저가 터치하길 원하는 오브젝트의 RectTransform
    public void BlockInputExceptRect(RectTransform targetRectTM)
    {
        _blocks[(int)Block.Left].sizeDelta = new Vector2(targetRectTM.position.x - targetRectTM.rect.width / 2, 0);
        _blocks[(int)Block.Right].sizeDelta = new Vector2(Screen.width - targetRectTM.position.x - targetRectTM.rect.width / 2, 0);
        _blocks[(int)Block.Top].sizeDelta = new Vector2(0, Screen.height - targetRectTM.position.y - targetRectTM.rect.height / 2);
        _blocks[(int)Block.Bottom].sizeDelta = new Vector2(0, targetRectTM.position.y - targetRectTM.rect.height / 2);
        for (int i = 0; i < _blocks.Length; i++)
            _blocks[i].gameObject.SetActive(true);
    }

    public void HideBlocks()
    {
        for (int i = 0; i < _blocks.Length; i++)
            _blocks[i].gameObject.SetActive(false);
    }

 

_blocks에는 Inspector에서 좌측, 우측, 상단, 하단 블럭을 순서대로 넣어준다.

#주의 버튼 오브젝트의 Scale이 (1, 1, 1)일 떄만 적용 가능!

 

결과

아주 잘 작동한다!!

# anchoredPosition

Canvas 사이즈가 720 * 1280 일 때
앵커 설정에 따른 Position 값의 변화에 주목!

anchoredPosition은 Inspector에 나와있는 Position과 같다.

anchor가 top/left 이면 anchoredPosition은 ( Screen.width / 2 , - Screen.height / 2)이 된다.

만약 ahchor가 bottom/left가 된다면? ahchorePosition은 ( Screen.width / 2. Screen.height / 2) 가 된다.

즉 anchor를 기준으로 한 자신의 pivot 위치


# rect.width / rect.height / rect.size

말그대로 이미지 객체의 넓이와 높이 (픽셀)

rect.size는 Vector2 ( rect.width , rect.height )


# rect.sizeDelta

size : (200, 200) / sizeDelta : (200, 200)

anchor가 위와 같이 middle/center라면 sizeDelta는 rect.size와 같다.

하지만 anchor가 strectch라면 이야기가 달라진다.

 

size : (200, 200) / sizeDelta : (-520. 200)

위 경우에는 이미지 객체의 부모 즉 Canvas의 크기가 720 * 1280 이므로

sizeDelta.x = - Screen.width + rect.width = -720 + 200 = -520

sizeDelta.y = rect.height = 200

즉 부모와 비교했을 때 width / height가 얼마나 크거나 작은지를 나타낸게 sizeDelta이다.

size : (720. 200) / sizeDelta : (0, -1080)

따라서 위 경우는 이미지의 넓이가 Canvas와 똑같으므로 sizeDelta.x는 0이고

sizeDelta.y는 -1280 + 200 = -1080이다. 즉 Canvas의 height보다 이미지 객체의 height가 1080 픽셀만큼 작다.

즉 부모보다 크기가 얼마나 작거나 큰지를 나타낸 값


# rect.xMin / rect.xMax / rect.yMin / rect.yMax

xMin : -250, xMax : 250, yMin : -100, yMax : 100

이미지 객체를 pivot이 중심인 하나의 좌표계로 봤을때 x, y 좌표의 최대최소 값들이다. 위와 같은 경우는 pivot이 (0.5, 0.5) 즉가운데이다.

xMin : -500. xMax : 0, yMin : -200 , yMax : 0

pivot이 (1, 1) 즉 오른쪽 상단이면 위와 같이 된다.

즉 pivot을 중심으로 한 x, y 좌표의 최대 최소 값

+ Recent posts