using UnityEngine; /// /// Y-Sort 排序器 —— 根据物体的Y坐标(世界空间)动态调整Sprite的sortingOrder。 /// /// 原理: /// 在2.5D等距视角游戏中,Y坐标代表"前后"关系(Y越小=越远=越靠后)。 /// 本脚本每帧根据物体的Y坐标计算sortingOrder,Y值越小排序值越小, /// 这样后面的物体会被前面的物体遮挡,实现正确的前后遮挡关系。 /// /// 用法: /// 1. 挂到所有需要参与Y-Sort的Sprite物体上(玩家、敌人、树木、石头等) /// 2. 设置 baseSortingOrder 区分不同类型的物体(如地面=0,角色=1000,UI=2000) /// 3. 确保所有参与排序的Sprite在同一个Sorting Layer上 /// /// 注意: /// - 本脚本假设摄像机从斜上方俯视(Y轴代表前后) /// - 所有参与排序的物体必须在同一个Sorting Layer /// - 建议给不同类型的物体设置不同的baseSortingOrder以避免冲突 /// public class YSorter : MonoBehaviour { [Tooltip("基础排序值,用于区分不同类型的物体(如地面=0,角色=1000)")] [SerializeField] private int baseSortingOrder = 0; [Tooltip("Y坐标到sortingOrder的缩放系数(值越大,前后物体排序差异越明显)")] [SerializeField] private float scaleFactor = 100f; [Tooltip("是否每帧更新(关闭则只在移动时更新,性能更好)")] [SerializeField] private bool updateEveryFrame = true; private SpriteRenderer _spriteRenderer; private Vector3 _lastPosition; private void Awake() { _spriteRenderer = GetComponentInChildren(); if (_spriteRenderer == null) { Debug.LogWarning($"YSorter: 物体 {gameObject.name} 没有找到SpriteRenderer组件"); } _lastPosition = transform.position; } private void LateUpdate() { if (_spriteRenderer == null) return; // 如果设置了不是每帧更新,只在位置改变时更新 if (!updateEveryFrame && transform.position == _lastPosition) return; UpdateSortingOrder(); _lastPosition = transform.position; } private void UpdateSortingOrder() { // Y值越小(越远),sortingOrder越小 // 使用负号是因为Unity中Y轴向上为正,但我们需要Y越小=越靠后 int sortingOrder = baseSortingOrder - Mathf.RoundToInt(transform.position.y * scaleFactor); if (_spriteRenderer.sortingOrder != sortingOrder) { _spriteRenderer.sortingOrder = sortingOrder; } } }