Unity2D 스프라이트 그리기 순서를 LINQ로 정규화

6296 단어 Unity2DLINQUnity

필요성



지금 카드 게임 같은 것을 만들고 있는데, Unity2D의 Sprite는 그리기 순서를 레이어(Sorting Layer)로 관리하면서 같은 레이어 내에서는 Order in Layer의 작은 순서로 그리는 것은 아시다시피.


그리고, 카드 게임이나, Windows의 윈도우와 같이, 선택한 것을 맨 위에 가져오는 조작(레이즈 조작)을 하려면 어떻게 할까.

그것은 간단하고, Order in Layer의 값에 1만이라든지 2만이라든지 더해 버리면 우선, 꼭대기에 올 것이다(요즘 많거나, 이상한 수치 넣지 않는 한)

덧붙여서 Inspector라고 Order in Layer입니다만, 스크립트상에서는 Renderer의 멤버의 sortingOrder입니다.

코드로 하면 이런 느낌
    public void Raise(int num) {
        var spr = GetComponent<SpriteRenderer>();
        spr.sortingOrder += num;
    }

이것으로 좋은가?



하지만 이 방법에는 물론 문제가 있어 원래 원래 sortingOrder가 10의 객체를 Raise(1000); 1000); 하지만 1005이므로 맨 위에 오지 않는다! 어떻게 해!

마침내 주제



그래서 SortingOrder의 정규화가 필요합니다.
라고, 정규화등이라고 어렵게 말했습니다만, 차례는 그대로 숫자를 되돌리는 것뿐입니다.
BASIC에서 말하면 RENUM 명령이란 것입니다 (얼마나의 사람이 핀이라고 오는지)

LINQ를 무리하게 사용해!


  • 지정된 sortingLayerID를 가진 SpriteRenderer를
  • sortingOrder 값으로 정렬 한 다음
  • 번호 다시

  • 평소에 쓰면 적당히 길다!
    그것이 LINQ라면
  • 지정한 sortingLayerID를 가진 SpriteRenderer → Where
  • sortingOrder의 값으로 정렬한 후 → OrderBy
  • 번호 다시

  • 되기 때문에,
        public void SortOrderNomalize(int targetLayer)
        {
            int cnt = 0;
            foreach (var card in FindObjectsOfType<SpriteRenderer>().Where(sr => sr.sortingLayerID == targetLayer).OrderBy(c => c.sortingOrder))
            {
                card.sortingOrder = cnt++;
            }
        }
    

    에서! 짧은! 대단해!

    일단 이것만으로 지정한 레이어의 sortingOrder를 0부터 다시 되돌려줍니다.

    덧붙여서, 단지 행수를 줄인다고 하는 방침이라면 foreach를 Array.ForEach 사용하는 손도 있습니다만, Array.ForEach는 배열 한정이므로 ToArray()를 달릴 필요가 있으므로 메모리적으로 불리한 생각이 듭니다 .

    일단 쓰면
        public void SortOrderNomalize2(int targetLayer)
        {
            int cnt = 0;
            Array.ForEach(FindObjectsOfType<SpriteRenderer>().Where(sr => sr.sortingLayerID == targetLayer).OrderBy(c => c.sortingOrder).ToArray(),spr=>spr.sortingOrder = cnt++);
        }
    

    입니다. 뭐, 짧으면 좋다고 하는 것이 아니다.

    한화휴제



    이것을 방금 전의 Raise 메소드와 함께
        public void Raise(int num) {
            var spr = GetComponent<SpriteRenderer>();
            spr.sortingOrder += num;
            SortOrderNormalize(spr.sortingLayerID);//sortingOrder振り直し
        }
    

    라고 해주면 좋지 않을까요.

    물론



    FindObjectsOfType이라든지 결코 가벼운 처리는 아니기 때문에 도중에 증감하지 않는 한 Start라든지 확보해 두는 것을 추천합니다.

    이것만 해



    실은 sortingOrder의 재검토가 이미 Unity에 의해 준비되어 있나요? 사라토 찾은 느낌은 없었습니다만.

    그렇다면 알려주세요. 부끄럽기 때문에 기사 지우기 때문에.

    좋은 웹페이지 즐겨찾기