Unity中Tile模式Sprite Renderer基于导入枢轴动态定位问题
Unity Tile模式Sprite Renderer 自定义枢轴位置偏移修正方案
问题场景
将Sprite Renderer设置为**Tile(平铺)**模式,Sprite导入时配置了自定义枢轴(pivot)与自定义边框,需要在OnValidate中动态调整Renderer位置,确保无论平铺尺寸变化,都能相对于父物体和导入枢轴保持目标位置。现有代码逻辑接近预期,但增大Renderer高度时偏移量存在轻微偏差。
现有代码
float spriteWorldHeight = groundRenderer.sprite.bounds.size.y; float rendererHeight = groundRenderer.size.y; float diff = rendererHeight - spriteWorldHeight; //Getting the normalized pivot set in the import settings float pivotY = groundRenderer.sprite.pivot.y / groundRenderer.sprite.rect.height; float y = diff * (0.5f - pivotY); groundRenderer.transform.localPosition = new Vector2(0, y);
问题根源
现有代码直接使用Sprite的bounds.size.y作为基础高度,但忽略了**自定义边框(Border)**的影响:Tile模式下,只有去除边框后的区域会被重复平铺,原Sprite的上下边框只显示一次,不会参与重复。因此用整个Sprite的尺寸计算偏移会导致误差。
修正后的代码
using UnityEngine; [ExecuteInEditMode] public class TileSpritePositioner : MonoBehaviour { public SpriteRenderer groundRenderer; private void OnValidate() { if (groundRenderer == null || groundRenderer.sprite == null) return; var sprite = groundRenderer.sprite; // 获取导入设置中的边框像素值 var border = sprite.border; // 计算平铺时的有效像素高度(去除上下边框) float effectivePixelHeight = sprite.rect.height - border.top - border.bottom; // 转换为世界空间下的有效高度 float effectiveWorldHeight = effectivePixelHeight / sprite.pixelsPerUnit; float rendererHeight = groundRenderer.size.y; float diff = rendererHeight - effectiveWorldHeight; // 基于原Sprite像素尺寸的归一化枢轴Y值 float pivotY = sprite.pivot.y / sprite.rect.height; // 计算修正后的Y轴偏移 float yOffset = diff * (0.5f - pivotY); groundRenderer.transform.localPosition = new Vector2(0, yOffset); } }
关键修正说明
- 有效高度计算:通过
sprite.rect.height - border.top - border.bottom得到实际参与平铺的像素高度,再除以pixelsPerUnit转换为世界空间尺寸,这是修正偏移的核心。 - 空值防护:添加了
groundRenderer和sprite的空值判断,避免编辑模式下出现空引用异常。 - 保留原枢轴逻辑:基于导入设置的归一化枢轴计算逻辑是正确的,仅替换了错误的基础高度值。
内容的提问来源于stack exchange,提问作者s_marcell
相关产品推荐
相关产品推荐

