80 lines
2.6 KiB
C#
80 lines
2.6 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Tilemaps;
|
|
|
|
/// <summary>
|
|
/// Y-Sort 排序器 —— 根据物体的Z坐标(世界空间)动态调整Sprite的sortingOrder。
|
|
/// 支持SpriteRenderer和TilemapRenderer。
|
|
/// </summary>
|
|
public class YSorter : MonoBehaviour
|
|
{
|
|
[Tooltip("基础排序值,用于区分不同类型的物体(如地面=0,角色=1000)")]
|
|
[SerializeField] private int baseSortingOrder = 0;
|
|
|
|
[Tooltip("Z坐标到sortingOrder的缩放系数(值越大,前后物体排序差异越明显)")]
|
|
[SerializeField] private float scaleFactor = 100f;
|
|
|
|
[Tooltip("是否每帧更新(关闭则只在移动时更新,性能更好)")]
|
|
[SerializeField] private bool updateEveryFrame = true;
|
|
|
|
private SpriteRenderer _spriteRenderer;
|
|
private TilemapRenderer _tilemapRenderer;
|
|
private Vector3 _lastPosition;
|
|
|
|
private void Awake()
|
|
{
|
|
// 尝试获取SpriteRenderer
|
|
_spriteRenderer = GetComponentInChildren<SpriteRenderer>();
|
|
|
|
// 如果没有SpriteRenderer,尝试获取TilemapRenderer
|
|
if (_spriteRenderer == null)
|
|
{
|
|
_tilemapRenderer = GetComponentInChildren<TilemapRenderer>();
|
|
|
|
if (_tilemapRenderer == null)
|
|
{
|
|
Debug.LogWarning($"YSorter: 物体 {gameObject.name} 没有找到SpriteRenderer或TilemapRenderer组件");
|
|
}
|
|
}
|
|
|
|
_lastPosition = transform.position;
|
|
}
|
|
|
|
private void LateUpdate()
|
|
{
|
|
// 如果没有任何渲染器,返回
|
|
if (_spriteRenderer == null && _tilemapRenderer == null) return;
|
|
|
|
// 如果设置了不是每帧更新,只在位置改变时更新
|
|
if (!updateEveryFrame && transform.position == _lastPosition)
|
|
return;
|
|
|
|
UpdateSortingOrder();
|
|
_lastPosition = transform.position;
|
|
}
|
|
|
|
private void UpdateSortingOrder()
|
|
{
|
|
// 使用物体中心(transform.position)的Z坐标作为排序依据
|
|
float sortZ = transform.position.z;
|
|
|
|
// Z值越大(离相机越远),sortingOrder越大
|
|
int sortingOrder = baseSortingOrder + Mathf.RoundToInt(sortZ * scaleFactor);
|
|
|
|
// 更新对应的渲染器
|
|
if (_spriteRenderer != null)
|
|
{
|
|
if (_spriteRenderer.sortingOrder != sortingOrder)
|
|
{
|
|
_spriteRenderer.sortingOrder = sortingOrder;
|
|
}
|
|
}
|
|
else if (_tilemapRenderer != null)
|
|
{
|
|
if (_tilemapRenderer.sortingOrder != sortingOrder)
|
|
{
|
|
_tilemapRenderer.sortingOrder = sortingOrder;
|
|
}
|
|
}
|
|
}
|
|
}
|