Files
gold_dolphin/unity/Assets/camera/YSorter.cs
2026-06-28 15:38:02 +08:00

69 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
/// <summary>
/// Y-Sort 排序器 —— 根据物体的Y坐标世界空间动态调整Sprite的sortingOrder。
///
/// 原理:
/// 在2.5D等距视角游戏中Y坐标代表"前后"关系Y越小=越远=越靠后)。
/// 本脚本每帧根据物体的Y坐标计算sortingOrderY值越小排序值越小
/// 这样后面的物体会被前面的物体遮挡,实现正确的前后遮挡关系。
///
/// 用法:
/// 1. 挂到所有需要参与Y-Sort的Sprite物体上玩家、敌人、树木、石头等
/// 2. 设置 baseSortingOrder 区分不同类型的物体(如地面=0角色=1000UI=2000
/// 3. 确保所有参与排序的Sprite在同一个Sorting Layer上
///
/// 注意:
/// - 本脚本假设摄像机从斜上方俯视Y轴代表前后
/// - 所有参与排序的物体必须在同一个Sorting Layer
/// - 建议给不同类型的物体设置不同的baseSortingOrder以避免冲突
/// </summary>
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<SpriteRenderer>();
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;
}
}
}