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

使用列表跨场景移动对象(MoveGameObjectToScene)- Unity入门问题

解决方案

1. 先修改SceneTransitionManager.cs(修复原有逻辑问题+增加跨场景暂存字段)

原有代码存在两个问题:一是要传递的对象没有设置切场景不销毁,会在加载新场景时被自动删除;二是没有等场景加载完成就执行对象移动操作,会导致移动失败。修改后的代码如下:

public class SceneTransitionManager : Singleton<SceneTransitionManager>
{
    // 新增:公共字段暂存跨场景传递的对象,供其他脚本读取
    public List<GameObject> transferredObjects;
    private AsyncOperation sceneAsync;
 
    public void GoToScene(string sceneName, List<GameObject> objectsToMove)
    {
        // 暂存要传递的对象
        transferredObjects = objectsToMove;
        // 标记对象切场景不销毁
        foreach(var obj in objectsToMove)
        {
            DontDestroyOnLoad(obj);
        }
        StartCoroutine(LoadScene(sceneName, objectsToMove));
    }
 
    private IEnumerator LoadScene(string sceneName, List<GameObject> objectsToMove)
    {
        // 等待场景完全加载完成
        sceneAsync = SceneManager.LoadSceneAsync(sceneName);
        while(!sceneAsync.isDone)
        {
            yield return null;
        }

        Scene newScene = SceneManager.GetSceneByName(sceneName);
        SceneManager.SetActiveScene(newScene);
        
        // 场景加载完成后再移动对象到新场景
        foreach (GameObject obj in objectsToMove)
        {
            SceneManager.MoveGameObjectToScene(obj, newScene);
        }
    }
}

2. 编写CaptureSceneManager.cs的逻辑

你需要的获取对象、赋值到SerializedField的逻辑直接写在Start里即可,因为新场景加载完成后才会执行当前脚本的Start方法:

public class CaptureSceneManager : PocketDroidsSceneManager
{
    // 你要挂载droid的空GameObject,在Inspector里提前拖入赋值即可
    [SerializeField] private GameObject droidContainer;
    // 存储当前传递过来的droid,供后续捕获逻辑使用
    private GameObject currentDroid;

    private void Start()
    {
        // 从单例的暂存列表里读取droid
        if(SceneTransitionManager.Instance.transferredObjects != null 
            && SceneTransitionManager.Instance.transferredObjects.Count > 0)
        {
            // 你每次只传一个droid,直接取列表第一个元素即可
            currentDroid = SceneTransitionManager.Instance.transferredObjects[0];
            // 把droid设为你指定空GameObject的子物体
            currentDroid.transform.SetParent(droidContainer.transform, false);
            // 用完清空列表,避免下次切场景逻辑冲突
            SceneTransitionManager.Instance.transferredObjects.Clear();
        }
        else
        {
            Debug.LogWarning("未检测到传递过来的Droid对象");
        }
    }

    // 补全父类要求实现的抽象方法,按你自己的需求写逻辑即可
    public override void playerTapped(GameObject player)
    {
        
    }

    public override void droidTapped(GameObject droid)
    {
        
    }
}

补充说明

  • 原来捕获场景里的占位符droid prefab可以直接删除,现在加载的是你从世界场景点击的实际droid对象
  • 如果需要保留droid的原位置、旋转、缩放属性,把SetParent的第二个参数改为true即可
  • 如果后续需要传递多个对象,遍历transferredObjects列表按标签、名称筛选即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 02:18:03