当前位置: 首页 > article >正文

麦田物语学习笔记:保存和加载场景中的物品

目录

基本流程

1.代码思路

2.代码实现

最终效果

补充知识点

1.序列化

2.委托


基本流程

        现在在切换场景后,场景中的物品即使被拾取了,也还是会被重新加载出来,所以本篇文章的任务是在切换场景前后能保留当前场景的数据

1.代码思路

        (1)为了保留处在地上的物品数据,就需要保存物品的坐标,以及这个物品是什么,所以在卸载场景之前读取要卸载的场景中的物品都有什么,重新加载场景的时候,按照之前的进度把物品再生成出来

        (2)创建一个存储数据的字典,这个字典需要把场景的名字和物品的信息存储在一起,由于一个场景里有多个物品,那么就需要一个列表来保存

2.代码实现

新增和修改ItemManager.cs的代码

private Dictionary<string, List<SceneItem>> sceneItemDict = new Dictionary<string, List<SceneItem>>();

private void OnEnable()
{
    EventHandler.InstantiateItemInScene += OnInstantiateItemInScene;
    EventHandler.BeforeSceneUnloadEvent += OnBeforeSceneUnloadEvent;
    EventHandler.AfterSceneLoadedEvent += OnAfterSceneLoadedEvent;
}

private void OnDisable()
{
    EventHandler.InstantiateItemInScene -= OnInstantiateItemInScene;
    EventHandler.BeforeSceneUnloadEvent -= OnBeforeSceneUnloadEvent;
    EventHandler.AfterSceneLoadedEvent -= OnAfterSceneLoadedEvent;
}

private void OnBeforeSceneUnloadEvent()
{
    GetAllSceneItems();
}

private void OnAfterSceneLoadedEvent()
{
    itemParent = GameObject.FindWithTag("ItemParent").transform;
    RecreateAllItems();
}

/// <summary>
/// 获得当前场景所有Item
/// </summary>
private void GetAllSceneItems()
{ 
    List<SceneItem> currentSceneItems = new List<SceneItem>();

    foreach (var item in FindObjectsOfType<Item>())
    {
        SceneItem sceneItem = new SceneItem
        { 
            itemID = item.itemID,
            position = new SerializableVector3(item.transform.position)
        };
        currentSceneItems.Add(sceneItem);
    }

    if (sceneItemDict.ContainsKey(SceneManager.GetActiveScene().name))
    {
        //找到数据就更新Item数据列表
        sceneItemDict[SceneManager.GetActiveScene().name] = currentSceneItems;
    }
    else //如果是新场景
    {
        sceneItemDict.Add(SceneManager.GetActiveScene().name, currentSceneItems);
    }
}

/// <summary>
/// 刷新重建当前场景的物品
/// </summary>
private void RecreateAllItems()
{
    List<SceneItem> currentSceneItems = new List<SceneItem>();

    if (sceneItemDict.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);
            }
        }
    }
}

DataCollection新增可序列化坐标和场景中的物品

[System.Serializable]
//可序列化的坐标
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 ToVector2Int()
    {
        return new Vector2Int((int)x, (int)y);
    }
}

[System.Serializable]
public class SceneItem
{
    public int itemID;
    public SerializableVector3 position;
}

 对调TransitionManager中呼叫加载场景之后的事件以及场景淡出效果的顺序

private IEnumerator Transition(string sceneName, Vector3 targetPosition)
{
    //呼叫卸载场景之前要做的事
    EventHandler.CallBeforeSceneUnloadEvent();

    yield return Fade(1);

    yield return SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());

    yield return LoadSceneSetActive(sceneName);

    //移动人物坐标
    EventHandler.CallMoveToPosition(targetPosition);

    //呼叫加载场景之后的事件
    EventHandler.CallAfterSceneLoadedEvent();

    yield return Fade(0);
}

最终效果

拾取物品切换场景后,场景中的物品并不存在

 

补充知识点

1.序列化

        序列化,简单来说就是将对象转化为可传输的字节序列的过程叫做序列化,

        这里的对象指的任意脚本Unity文件,

        可以将对象转换为字节序列后,存储在数据库,内存或者文件
        

        我通过这个视频了解的

2.委托

        虽然在该专栏里的其他文章中补充过该知识,但是该视频是我遇到过的把委托讲的最通透的

因此再次提出并记录在这个文章中

        视频在这 

        up主的其他视频也非常高质量,推荐观看  


http://www.kler.cn/a/513302.html

相关文章:

  • STM32 FreeRTOS 任务挂起和恢复---实验
  • vue3+ts+uniapp 微信小程序(第一篇)—— 微信小程序定位授权,位置信息权限授权
  • SDL2:arm64下编译使用 -- SDL2多媒体库使用音频实例
  • Chrome 132 版本新特性
  • C语言之装甲车库车辆动态监控辅助记录系统
  • 二十三种设计模式-装饰器模式
  • StyleGAN - 基于样式的生成对抗网络
  • 低度酒真的是酒精勾兑的吗?
  • 2024人工智能AI+制造业应用落地研究报告汇总PDF洞察(附原数据表)
  • 【Java数据结构】排序
  • 前端之移动端
  • 解锁Java中的国密算法:安全保障的密钥
  • Arweave的经济学模型
  • TiDB与Oracle:数据库之争,谁能更胜一筹?
  • HTML语言的数据结构
  • git常见知识点
  • 使用tritonserver完成clip-vit-large-patch14图像特征提取模型的工程化。
  • 记录一下OpenCV Contrib 编译踩的坑
  • 美国采取行动扩大人工智能出口限制
  • Go-Gin Web 框架完整教程
  • 【音视频开发】变速与硬解码
  • 【Linux系统编程】—— 从零开始实现一个简单的自定义Shell
  • 基于昇腾300I-Duo推理卡部署Embedding与Rerank模型
  • 【Linux环境变量与命令行参数】常见环境变量 | 环境变量的全局属性 | 命令行参数
  • logback日志自定义占位符
  • redis热Key问题