using UnityEngine; using UnityEngine.Tilemaps; /// /// Y-Sort 排序器 —— 根据物体的Z坐标(世界空间)动态调整Sprite的sortingOrder。 /// 支持SpriteRenderer和TilemapRenderer。 /// 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,尝试获取TilemapRenderer if (_spriteRenderer == null) { _tilemapRenderer = GetComponentInChildren(); 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; } } } }