多场景跳转场景物品信息保存

本文介绍了在游戏开发中如何在场景切换时保存和恢复物品的位置信息,以确保玩家体验的一致性。通过创建一个SerializableVector3类来解决Vector3无法序列化的问题,并利用物品管理器存储每个场景的物品列表。在切换场景时,先保存当前场景的物品信息,然后在加载新场景时根据保存的数据实例化物品,从而实现无缝场景切换。
摘要由CSDN通过智能技术生成

在进行场景切换的时候,经常会遇到需求保存上一个场景里所有的物品信息和他们的位置。再次切换回场景的时候场景里物品的布局就如自己离开时一样,避免了穿帮和玩家体验优化。通常是需要在不被关闭的主场景添加一个物品管理器,在物品管理器里创建字典<string,List<Item>>字典的key为激活的场景名字,值为物品列表。在卸载当前场景之前发送消息提醒管理器让其收集物品信息。需要注意的是vector3无法序列化存储,这样在创建物品信息时需要修改坐标的存储方法。可以用一个类来存储,在类里创建x,y,z三个参数并创建其构造方法,内部做vector3的返回方法。

public class SerializableVector3
{
    public float x,y,z;

    public SerializableVector3(Vector3 pos)
    {
        this.x = pos.x;
        this.y = pos.y;
        this.z = pos.z;
    }
    public Vector3 ToVector3()
    {
        return new Vector3(x,y,z);
    }
    public Vector2Int ToVecotr2Int()
    {
        return new Vector2Int((int)x,(int)y);
    }
}

public class SceneItem
{
    public int itemId;
    public SerializableVector3 position;
}

物品信息中坐标参数用以上类作为参数,在循环场景中物品的时候只需要把游戏物体position赋值给物体信息的position即可实现存储。使用时再使用ToVector3进行转换即可变为拿来直接用于坐标的赋值。场景切换时会把显示的场景设为激活场景 而SceneManager.GetActiveScene()方法可以直接获取当前激活的场景,可以用场景.name直接赋值字典的key,而Item列表就只需要遍历场景中挂载了物品脚本的游戏物体即可。最后在加载场景的时候再根据当前激活场景的名字获取场景的物品列表再进行遍历然后实例化物品。

        // 卸载场景前的信息存储
        private void GetAllSceneItems()
        {
            List<SceneItem> currentSceneItems = new List<SceneItem>();
            foreach (var item in FindObjectsOfType<Item>())
            {
                SceneItem sceneItem = new SceneItem();
                sceneItem.itemId = item.itemId;
                sceneItem.position = new SerializableVector3(item.transform.position);
                currentSceneItems.Add(sceneItem);
            }
           if(sceneItemData.ContainsKey(SceneManager.GetActiveScene().name))
           {
               sceneItemData[SceneManager.GetActiveScene().name] = currentSceneItems;
           }
           else
           {
               sceneItemData.Add(SceneManager.GetActiveScene().name,currentSceneItems);
           }
        }
      

        // 加载场景时的实例化
        private void RecreateAllItems()
        {
            List<SceneItem> currentSceneItems = new List<SceneItem>();
            if(sceneItemData.TryGetValue(SceneManager.GetActiveScene().name,out currentSceneItems))
            {
                if(currentSceneItems != null)
                {
                    // 先清空场景中所有的物品
                    foreach (var item in FindObjectsOfType<Item>())
                    {
                        Destroy(item.gameObject);
                    }   
                    foreach (var item in currentSceneItems)
                    {
                        Item newItem = Instantiate(itemPrefab,item.position.ToVector3(),Quaternion.identity,ItemParent);
                        newItem.Init(item.itemId);// 根据id修改展示图片或模型
                    }
                }
            }
        }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值