✅ 기능
Unity에서 MeshRenderer가 아닌 SpriteRenderer(이미지 렌더러)는 파이프라인에서 카메라 정면 방향을 기준으로 3D세계의 정점(벡터)의 위치가 아닌 단순히 Sorting 및 Order에 의해 렌더링 되는 순서가 달라집니다. 이는 Canvas에서 Order을 정하는 방식과 유사합니다. SpriteRenderer을 이용하여 월드를 구성할 때, Ordering을 적절히 해야 자연스러운 연출이 가능합니다. 자연스러운 Ordering을 하기 위한 간단한 방법과 스크립트를 정리하였습니다.
✅ 적용 전
✅ 흐름도
런타임 도중 움직이는 대상과, 움직이지 않는 대상에 대하여 서로 다른 알고리즘을 사용합니다.
✅ 사용(적용) 예시
✅ 구현
1. 런타임 중 움직이지 않는 물체
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : Singleton<GameManager>
{
[SerializeField] private int mSortingOrderGap = 100;
public int SortingOrderGap
{
get
{
return mSortingOrderGap;
}
}
private void Awake()
{
SortingSpriteOrder();
}
private void SortingSpriteOrder()
{
foreach(SpriteRenderer renderer in FindObjectsOfType<SpriteRenderer>())
{
renderer.sortingOrder = -(int)(renderer.gameObject.transform.position.z * mSortingOrderGap) + renderer.sortingOrder;
}
}
}
[SerializeField] private int mSortingOrderGap = 100;
- Z좌표를 기준으로 Sorting을 할 때, 소수점 단위를 올려주기 위한 수 입니다.
- 예를들어 Z좌표가 1.05f, 1.50f인 SpriteRenderer가 두개 있을때, Ordering을 하면 모두 1로 나오게 됩니다.
- 이를 해결하고 더욱 정밀하게 Sorting을 하기 위해 Gap을 사용합니다.
private void SortingSpriteOrder()
- GameManager.cs에서 Awake에 의해 호출됩니다.
- 씬 내의 모든 SpriteRenderer을 찾고, 해당 오브젝트의 위치를 기반으로 Order in Layer가 정렬됩니다.
2. 런타임 중 움직이지 않는 물체
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpriteSortingOrder : MonoBehaviour
{
private SpriteRenderer[] mSpriteRenderers;
private int[] mOriginSortingOrders;
private void Awake()
{
mSpriteRenderers = GetComponentsInChildren<SpriteRenderer>(true);
mOriginSortingOrders = new int[mSpriteRenderers.Length];
for(int i = 0; i < mSpriteRenderers.Length; ++i)
{
mOriginSortingOrders[i] = mSpriteRenderers[i].sortingOrder;
}
}
private void OnEnable()
{
Sort();
}
private void Update()
{
Sort();
}
private void Sort()
{
for(int i = 0; i < mSpriteRenderers.Length; ++i)
{
mSpriteRenderers[i].sortingOrder = -(int)(mSpriteRenderers[i].gameObject.transform.position.z * GameManager.Instance.SortingOrderGap) + mOriginSortingOrders[i];
}
}
}
private SpriteRenderer[] mSpriteRenderers;
private int[] mOriginSortingOrders;
- 자식 오브젝트의 SpriteRenderer을 저장하고, 미리 지정되어있는 Sorting Order을 저장합니다.
- OriginSortingOrder가 있어야 런타임 도중 미리 지정해둔 순서가 변형되지 않습니다.
private void Sort()
- Order을 정렬합니다. GameManager.cs에서 다룬 정렬과 같은 알고리즘입니다.
✅ 도움받은곳 (References)
'unity game modules' 카테고리의 다른 글
[유니티] 인벤토리 시스템(2) - 아이템(ScriptableObject) (0) | 2022.12.26 |
---|---|
[유니티] 인벤토리 시스템(1) - 인벤토리 관리자 (0) | 2022.12.26 |
[유니티] 애니메이션 랜덤으로 재생하기(StateMachineBehaviour) (0) | 2022.11.23 |
[유니티] 편리하게 소리를 담당하는 사운드 매니저 구현 (0) | 2022.11.21 |
[유니티] NavMesh를 응용하여 '내비게이션(경로 시각화)' 만들기 (0) | 2022.10.22 |
✅ 기능
Unity에서 MeshRenderer가 아닌 SpriteRenderer(이미지 렌더러)는 파이프라인에서 카메라 정면 방향을 기준으로 3D세계의 정점(벡터)의 위치가 아닌 단순히 Sorting 및 Order에 의해 렌더링 되는 순서가 달라집니다. 이는 Canvas에서 Order을 정하는 방식과 유사합니다. SpriteRenderer을 이용하여 월드를 구성할 때, Ordering을 적절히 해야 자연스러운 연출이 가능합니다. 자연스러운 Ordering을 하기 위한 간단한 방법과 스크립트를 정리하였습니다.
✅ 적용 전
✅ 흐름도
런타임 도중 움직이는 대상과, 움직이지 않는 대상에 대하여 서로 다른 알고리즘을 사용합니다.
✅ 사용(적용) 예시
✅ 구현
1. 런타임 중 움직이지 않는 물체
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : Singleton<GameManager>
{
[SerializeField] private int mSortingOrderGap = 100;
public int SortingOrderGap
{
get
{
return mSortingOrderGap;
}
}
private void Awake()
{
SortingSpriteOrder();
}
private void SortingSpriteOrder()
{
foreach(SpriteRenderer renderer in FindObjectsOfType<SpriteRenderer>())
{
renderer.sortingOrder = -(int)(renderer.gameObject.transform.position.z * mSortingOrderGap) + renderer.sortingOrder;
}
}
}
[SerializeField] private int mSortingOrderGap = 100;
- Z좌표를 기준으로 Sorting을 할 때, 소수점 단위를 올려주기 위한 수 입니다.
- 예를들어 Z좌표가 1.05f, 1.50f인 SpriteRenderer가 두개 있을때, Ordering을 하면 모두 1로 나오게 됩니다.
- 이를 해결하고 더욱 정밀하게 Sorting을 하기 위해 Gap을 사용합니다.
private void SortingSpriteOrder()
- GameManager.cs에서 Awake에 의해 호출됩니다.
- 씬 내의 모든 SpriteRenderer을 찾고, 해당 오브젝트의 위치를 기반으로 Order in Layer가 정렬됩니다.
2. 런타임 중 움직이지 않는 물체
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpriteSortingOrder : MonoBehaviour
{
private SpriteRenderer[] mSpriteRenderers;
private int[] mOriginSortingOrders;
private void Awake()
{
mSpriteRenderers = GetComponentsInChildren<SpriteRenderer>(true);
mOriginSortingOrders = new int[mSpriteRenderers.Length];
for(int i = 0; i < mSpriteRenderers.Length; ++i)
{
mOriginSortingOrders[i] = mSpriteRenderers[i].sortingOrder;
}
}
private void OnEnable()
{
Sort();
}
private void Update()
{
Sort();
}
private void Sort()
{
for(int i = 0; i < mSpriteRenderers.Length; ++i)
{
mSpriteRenderers[i].sortingOrder = -(int)(mSpriteRenderers[i].gameObject.transform.position.z * GameManager.Instance.SortingOrderGap) + mOriginSortingOrders[i];
}
}
}
private SpriteRenderer[] mSpriteRenderers;
private int[] mOriginSortingOrders;
- 자식 오브젝트의 SpriteRenderer을 저장하고, 미리 지정되어있는 Sorting Order을 저장합니다.
- OriginSortingOrder가 있어야 런타임 도중 미리 지정해둔 순서가 변형되지 않습니다.
private void Sort()
- Order을 정렬합니다. GameManager.cs에서 다룬 정렬과 같은 알고리즘입니다.
✅ 도움받은곳 (References)
'unity game modules' 카테고리의 다른 글
[유니티] 인벤토리 시스템(2) - 아이템(ScriptableObject) (0) | 2022.12.26 |
---|---|
[유니티] 인벤토리 시스템(1) - 인벤토리 관리자 (0) | 2022.12.26 |
[유니티] 애니메이션 랜덤으로 재생하기(StateMachineBehaviour) (0) | 2022.11.23 |
[유니티] 편리하게 소리를 담당하는 사운드 매니저 구현 (0) | 2022.11.21 |
[유니티] NavMesh를 응용하여 '내비게이션(경로 시각화)' 만들기 (0) | 2022.10.22 |