You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity版本差异下Transform设为根节点子节点失效问题求助

解决Unity 2021中transform.SetParent(transform.root)不生效的问题

核心问题排查

你的脚本存在两个关键问题,和版本差异无关,属于代码本身的疏漏:

  1. Image组件未初始化:img变量仅声明未赋值,运行时会触发空引用异常,导致OnBeginDrag后续代码(包括transform.SetParent)无法执行。
  2. SetParent参数未正确设置:UI元素设置父节点时,默认的worldPositionStays=true会保持物体世界位置,可能导致视觉上无变化,同时transform.root在复杂UI层级下可能不是预期的Canvas根节点。

解决方案步骤

  • 初始化Image组件:在Awake方法中获取当前物体的Image组件,避免空引用报错。
  • 明确指定Canvas为父节点:直接获取场景中的Canvas作为拖拽时的父节点,比transform.root更可靠。
  • 使用SetParent重载方法:调用transform.SetParent(targetParent, false),将worldPositionStays设为false,确保子物体继承父节点局部坐标的同时,保持当前世界位置适配拖拽场景。

修改后的完整脚本

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class InventoryItem : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
    Image img;
    public Transform ParentAfterDrag; // 修正变量名拼写错误

    private void Awake()
    {
        // 初始化Image组件,避免空引用
        img = GetComponent<Image>();
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        img.raycastTarget = false;
        ParentAfterDrag = transform.parent;
        // 绑定到Canvas根节点,同时禁用世界位置保持
        transform.SetParent(GetComponentInParent<Canvas>().transform, false);
        // 强制设为最后一个子物体,确保拖拽时显示在最上层
        transform.SetAsLastSibling();
    }

    public void OnDrag(PointerEventData eventData)
    {
        transform.position = Input.mousePosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        img.raycastTarget = true;
        // 恢复父节点时同样禁用世界位置保持,避免偏移
        transform.SetParent(ParentAfterDrag, false);
    }
}

额外优化说明

  • 修正了变量名ParentAffterDrag的拼写错误,避免潜在逻辑问题。
  • 添加transform.SetAsLastSibling()确保拖拽物品显示在所有UI元素上方,提升交互体验。

内容的提问来源于stack exchange,提问作者Fox_65

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:55:16