Unity中Inventory系统UI随角色上下移动偏移问题求助
Unity Inventory系统UI偏移问题排查
问题现象
已将Main Camera挂载到Player角色,Canvas的Render Camera设为该相机,但角色上下移动时,UI会同向偏移(速度比未跟随相机时慢),左右移动则无此问题。尝试将相机与角色分离后问题依旧。
相关脚本
inventoryUI 脚本
public class inventoryUI : MonoBehaviour { private Inventory inventory; private int EquippedItem; public bool showInventory; public float UItimer; public float UItime; private Transform InventorySlots; private Transform FirstSlotPos; [SerializeField] private Transform ItemSlot; [SerializeField] private Transform EquippedItemSlot; public void SetInventory(Inventory i, int EquippedItem) { inventory = i; this.EquippedItem = EquippedItem; RefreshInventory(); } void Awake() { InventorySlots = transform.Find("InventorySlots"); FirstSlotPos = InventorySlots.transform.Find("FirstSlotPosition"); } [SerializeField]private float SlotSize; public void RefreshInventory() { if (!showInventory) return; foreach (Transform child in FirstSlotPos.transform) { if ((child != FirstSlotPos)) Destroy(child.gameObject); } int x = 0; foreach (ItemData i in inventory.GetInventory()) { RectTransform Slot; if (x == EquippedItem) Slot = Instantiate(EquippedItemSlot, FirstSlotPos).GetComponent<RectTransform>(); else Slot = Instantiate(ItemSlot, FirstSlotPos).GetComponent<RectTransform>(); Slot.gameObject.SetActive(true); Slot.anchoredPosition = new Vector2(x * SlotSize, FirstSlotPos.position.y); Image icon = Slot.transform.Find("ItemIcon").GetComponent<Image>(); icon.sprite = i.itemIcon; TextMeshProUGUI item = Slot.transform.Find("ItemNameDisplay").GetComponent<TextMeshProUGUI>(); item.SetText(i.itemName); item = Slot.transform.Find("ItemAmountDisplay").GetComponent<TextMeshProUGUI>(); item.SetText(i.amount.ToString()); x++; } } void Update() { if (showInventory) { InventorySlots.gameObject.SetActive(true); UItimer -= Time.deltaTime; if (UItimer <= 0) showInventory = false; } else InventorySlots.gameObject.SetActive(false); } }
PlayerInventory 脚本
public class PlayerInventory : MonoBehaviour { [SerializeField] private inventoryUI invUI; public Inventory inv; private int EquippedItem; void Start() { EquippedItem = 0; inv = new Inventory(); invUI.SetInventory(inv, EquippedItem); } void OnTriggerEnter2D(Collider2D col) { ItemObject i = col.GetComponent<ItemObject>(); if (i != null) { inv.AddItem(i.GetItem()); i.DestroyItem(); } invUI.SetInventory(inv, EquippedItem); } void Update() { if (Input.GetKeyDown(KeyCode.Q)) { EquippedItem -= 1; invUI.showInventory = true; invUI.UItimer = invUI.UItime; } if (Input.GetKeyDown(KeyCode.E)) { EquippedItem += 1; invUI.showInventory = true; invUI.UItimer = invUI.UItime; } if (EquippedItem < 0) EquippedItem = inv.GetInventory().Count -1; else if (EquippedItem >= inv.GetInventory().Count) EquippedItem = 0; invUI.SetInventory(inv, EquippedItem); } }
问题原因与修复方案
核心问题
在RefreshInventory方法中,设置Slot的anchoredPosition时,Y轴错误使用了FirstSlotPos.position.y——这是世界空间坐标,而anchoredPosition需要的是相对于父RectTransform的局部锚点坐标。当角色/相机上下移动时,FirstSlotPos的世界Y坐标会变化,导致Slot的Y位置被错误更新,出现偏移。
修复步骤
修改
RefreshInventory中设置anchoredPosition的代码:// 替换原错误代码 Slot.anchoredPosition = new Vector2(x * SlotSize, 0);若
FirstSlotPos本身是RectTransform,也可以取其锚点Y值来保持相对位置:RectTransform firstSlotRect = FirstSlotPos.GetComponent<RectTransform>(); Slot.anchoredPosition = new Vector2(x * SlotSize, firstSlotRect.anchoredPosition.y);额外优化建议
- 避免在
Update中每帧调用invUI.SetInventory(inv, EquippedItem),仅在装备索引变化或物品列表更新时调用,减少不必要的UI刷新 - 检查Canvas的Render Mode:若使用
Screen Space - Camera,确保Plane Distance设置合理,且相机Projection为Orthographic(2D游戏推荐) - 确认
FirstSlotPos的RectTransform锚点和Pivot设置正确,避免自身位置异常
- 避免在
内容的提问来源于stack exchange,提问作者Cu be
相关产品推荐
相关产品推荐

