通过把空间中的对象矩阵保存至json,读取数据加载对应的对象

using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System;
using System.Collections;

[Serializable]
public class TransformData
{
    public string name;
    public TransformMatrix matrix;
}

[Serializable]
public class TransformMatrix
{
    public Vector3 position;
    public Vector3 rotation;
    public Vector3 scale;
}

[Serializable]
public class TransformDataWrapper
{
    public List<TransformData> items;
}

/// <summary>
/// 锚点加载
/// </summary>
public class AnchorLoad : MonoBehaviour
{
    [Header("调试设置")]
    [SerializeField] private bool debugMode = true;

    [Header("回调设置")]
    public System.Action<List<TransformData>> OnInitializationComplete;

    private List<TransformData> currentObjectsData = new List<TransformData>();
    private string jsonFilePath => Path.Combine(Application.persistentDataPath, "AnchorData.json");
    private string streamingAssetsFilePath => Path.Combine(Application.streamingAssetsPath, "AnchorData.json");

    void Start()
    {
        StartCoroutine(InitializeJSONSystem());
    }

    /// <summary>
    /// 初始化JSON系统:检查文件是否存在,不存在则从StreamingAssets复制
    /// </summary>
    public IEnumerator InitializeJSONSystem()
    {
        yield return StartCoroutine(CheckAndCopySceneData());

        bool success = false;
        string message = "";
        List<TransformData> loadedData = null;

        if (CheckJSONFileExists())
        {
            try
            {
                LoadObjectsFromJSON();
                loadedData = currentObjectsData;
                success = true;
                message = $"JSON系统初始化成功,加载了 {currentObjectsData.Count} 个对象";
                LogMessage(message);
            }
            catch (Exception e)
            {
                success = false;
                message = $"JSON系统初始化失败: {e.Message}";
                Debug.LogError(message);
                loadedData = new List<TransformData>();
            }
        }
        else
        {
            try
            {
                CreateDefaultJSONFile();
                LoadObjectsFromJSON();
                loadedData = currentObjectsData;
                success = true;
                message = $"已创建默认JSON文件并初始化成功,加载了 {currentObjectsData.Count} 个对象";
                LogMessage(message);
            }
            catch (Exception e)
            {
                success = false;
                message = $"创建默认JSON文件失败: {e.Message}";
                Debug.LogError(message);
                loadedData = new List<TransformData>();
            }
        }

        // 触发初始化完成回调,传递加载的对象数据
        OnInitializationComplete?.Invoke(loadedData);
    }

    /// <summary>
    /// 带回调的初始化方法
    /// </summary>
    public void InitializeWithCallback(System.Action<List<TransformData>> callback)
    {
        if (callback != null)
        {
            OnInitializationComplete += callback;
        }
        StartCoroutine(InitializeJSONSystem());
    }

    /// <summary>
    /// 检查并复制场景数据文件
    /// </summary>
    private IEnumerator CheckAndCopySceneData()
    {
        if (!File.Exists(jsonFilePath))
        {
            LogMessage("PersistentDataPath中未找到sceneObjects.json,检查StreamingAssets...");

            if (Application.platform == RuntimePlatform.Android)
            {
                yield return StartCoroutine(CopyFileAndroid());
            }
            else
            {
                CopyFileStandard();
            }
        }
        else
        {
            LogMessage("PersistentDataPath中已存在sceneObjects.json");
        }
    }

    /// <summary>
    /// 标准文件复制方法(非Android平台)
    /// </summary>
    private void CopyFileStandard()
    {
        if (File.Exists(streamingAssetsFilePath))
        {
            try
            {
                // 确保目标目录存在
                string directory = Path.GetDirectoryName(jsonFilePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                File.Copy(streamingAssetsFilePath, jsonFilePath, false);
                LogMessage("已从StreamingAssets复制sceneObjects.json到PersistentDataPath");
            }
            catch (System.Exception e)
            {
                Debug.LogError($"复制文件时出错: {e.Message}");
            }
        }
        else
        {
            LogMessage("StreamingAssets中也未找到sceneObjects.json");
        }
    }

    /// <summary>
    /// Android平台文件复制方法
    /// </summary>
    private IEnumerator CopyFileAndroid()
    {
        using (UnityEngine.Networking.UnityWebRequest www =
               UnityEngine.Networking.UnityWebRequest.Get(streamingAssetsFilePath))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityEngine.Networking.UnityWebRequest.Result.Success)
            {
                try
                {
                    string directory = Path.GetDirectoryName(jsonFilePath);
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }
                    File.WriteAllBytes(jsonFilePath, www.downloadHandler.data);
                    LogMessage("已从StreamingAssets复制sceneObjects.json到PersistentDataPath (Android)");
                }
                catch (System.Exception e)
                {
                    Debug.LogError($"复制文件时出错: {e.Message}");
                }
            }
            else
            {
                LogMessage("StreamingAssets中未找到sceneObjects.json (Android)");
            }
        }
    }

    /// <summary>
    /// 检查JSON文件是否存在
    /// </summary>
    private bool CheckJSONFileExists()
    {
        bool exists = File.Exists(jsonFilePath);
        LogMessage($"检查文件存在: {exists}");
        return exists;
    }

    /// <summary>
    /// 创建默认的JSON文件
    /// </summary>
    private void CreateDefaultJSONFile()
    {
        try
        {
            string directory = Path.GetDirectoryName(jsonFilePath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
                LogMessage($"创建目录: {directory}");
            }

            TransformDataWrapper wrapper = new TransformDataWrapper { items = currentObjectsData };
            string jsonString = JsonUtility.ToJson(wrapper, true);
            File.WriteAllText(jsonFilePath, jsonString);

            LogMessage("默认JSON文件创建成功!");
            LogMessage($"文件路径: {jsonFilePath}");
            LogMessage($"文件内容: {jsonString}");
        }
        catch (Exception e)
        {
            Debug.LogError($"创建JSON文件失败: {e.Message}");
            throw; 
        }
    }

    /// <summary>
    /// 从JSON加载对象
    /// </summary>
    private void LoadObjectsFromJSON()
    {
        try
        {
            if (!File.Exists(jsonFilePath))
            {
                return;
            }

            string jsonString = File.ReadAllText(jsonFilePath);
            TransformDataWrapper wrapper = JsonUtility.FromJson<TransformDataWrapper>(jsonString);

            if (wrapper != null && wrapper.items != null)
            {
                currentObjectsData = wrapper.items;
                LogMessage($"成功加载 {currentObjectsData.Count} 个对象");
            }
            else
            {
                Debug.LogError("JSON解析失败或数据为空");
                currentObjectsData = new List<TransformData>();
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"加载JSON失败: {e.Message}");
            currentObjectsData = new List<TransformData>();
            throw; 
        }
    }

    /// <summary>
    /// 检查对象是否存在,存在则更新,不存在则添加
    /// </summary>
    public void AddOrUpdateObject(string objectName, Vector3 position, Vector3 rotation, Vector3 scale)
    {
        TransformData existingData = currentObjectsData.Find(data => data.name == objectName);

        if (existingData != null)
        {
            existingData.matrix.position = position;
            existingData.matrix.rotation = rotation;
            existingData.matrix.scale = scale;
            LogMessage($"更新对象: {objectName}");
        }
        else
        {
            TransformData newData = new TransformData
            {
                name = objectName,
                matrix = new TransformMatrix
                {
                    position = position,
                    rotation = rotation,
                    scale = scale
                }
            };
            currentObjectsData.Add(newData);
            LogMessage($"添加新对象: {objectName}");
        }

        SaveToJSON();
    }

    /// <summary>
    /// 动态添加新对象(在现有数据后追加)
    /// </summary>
    public void AddNewObject(string objectName, Vector3 position, Vector3 rotation, Vector3 scale)
    {
        LoadObjectsFromJSON();
        if (CheckObjectExists(objectName))
        {
            LogMessage($"对象已存在: {objectName},使用更新方法替代");
            UpdateObject(objectName, position, rotation, scale);
            return;
        }
        TransformData newData = new TransformData
        {
            name = objectName,
            matrix = new TransformMatrix
            {
                position = position,
                rotation = rotation,
                scale = scale
            }
        };

        currentObjectsData.Add(newData);

        SaveToJSON();

        LogMessage($"成功添加新对象: {objectName}");
        LogMessage($"当前对象总数: {currentObjectsData.Count}");
    }

    /// <summary>
    /// 批量添加多个对象(在现有数据后追加)
    /// </summary>
    public void AddMultipleObjects(List<TransformData> newObjects)
    {
        LoadObjectsFromJSON();

        int addedCount = 0;
        int updatedCount = 0;

        foreach (TransformData newObject in newObjects)
        {
            TransformData existingData = currentObjectsData.Find(data => data.name == newObject.name);

            if (existingData != null)
            {
                existingData.matrix = newObject.matrix;
                updatedCount++;
                LogMessage($"更新对象: {newObject.name}");
            }
            else
            {
                currentObjectsData.Add(newObject);
                addedCount++;
                LogMessage($"添加新对象: {newObject.name}");
            }
        }
        SaveToJSON();

        LogMessage($"批量添加完成 - 新增: {addedCount}, 更新: {updatedCount}, 总计: {currentObjectsData.Count}");
    }

    /// <summary>
    /// 从现有JSON文件读取数据,然后追加新数据
    /// </summary>
    public void AppendToExistingJSON(string objectName, Vector3 position, Vector3 rotation, Vector3 scale)
    {
        LoadObjectsFromJSON();
        AddOrUpdateObject(objectName, position, rotation, scale);
    }

    /// <summary>
    /// 更新已存在的对象
    /// </summary>
    public void UpdateObject(string objectName, Vector3 position, Vector3 rotation, Vector3 scale)
    {
        TransformData existingData = currentObjectsData.Find(data => data.name == objectName);

        if (existingData != null)
        {
            existingData.matrix.position = position;
            existingData.matrix.rotation = rotation;
            existingData.matrix.scale = scale;
            SaveToJSON();
            LogMessage($"更新对象: {objectName}");
        }
        else
        {
            LogMessage($"未找到对象: {objectName},无法更新");
        }
    }

    /// <summary>
    /// 删除指定对象
    /// </summary>
    public void DeleteObject(string objectName)
    {
        // 先加载最新数据
        LoadObjectsFromJSON();

        int removedCount = currentObjectsData.RemoveAll(data => data.name == objectName);

        if (removedCount > 0)
        {
            SaveToJSON();
            LogMessage($"删除对象: {objectName}");
        }
        else
        {
            LogMessage($"未找到对象: {objectName},无法删除");
        }
    }

    /// <summary>
    /// 检查对象是否存在
    /// </summary>
    public bool CheckObjectExists(string objectName)
    {
        return currentObjectsData.Exists(data => data.name == objectName);
    }

    /// <summary>
    /// 获取指定对象的数据
    /// </summary>
    public TransformData GetObjectData(string objectName)
    {
        return currentObjectsData.Find(data => data.name == objectName);
    }

    /// <summary>
    /// 保存到JSON文件
    /// </summary>
    public void SaveToJSON()
    {
        try
        {
            TransformDataWrapper wrapper = new TransformDataWrapper { items = currentObjectsData };
            string jsonString = JsonUtility.ToJson(wrapper, true);
            File.WriteAllText(jsonFilePath, jsonString);
            LogMessage("JSON文件已保存");
        }
        catch (Exception e)
        {
            Debug.LogError($"保存JSON失败: {e.Message}");
        }
    }

    /// <summary>
    /// 重新创建JSON文件(重置为默认)
    /// </summary>
    public void RecreateJSONFile()
    {
        LogMessage("重新创建JSON文件...");
        if (File.Exists(jsonFilePath))
        {
            File.Delete(jsonFilePath);
            LogMessage("已删除旧文件");
        }
        CreateDefaultJSONFile();
    }

    /// <summary>
    /// 显示JSON文件内容(用于调试)
    /// </summary>
    public void DisplayJSONContent()
    {
        if (File.Exists(jsonFilePath))
        {
            string content = File.ReadAllText(jsonFilePath);
            LogMessage($"JSON内容:\n{content}");
        }
        else
        {
            LogMessage("JSON文件不存在");
        }
    }

    /// <summary>
    /// 获取原始JSON数据字符串
    /// </summary>
    public string GetRawJSONData()
    {
        if (File.Exists(jsonFilePath))
        {
            return File.ReadAllText(jsonFilePath);
        }
        return "{}";
    }

    /// <summary>
    /// 日志输出
    /// </summary>
    private void LogMessage(string message)
    {
        if (debugMode)
        {
            Debug.Log($"[JSONManager] {message}");
        }
    }

    /// <summary>
    /// 获取当前对象数量(用于UI显示)
    /// </summary>
    public int GetObjectCount()
    {
        return currentObjectsData?.Count ?? 0;
    }

    /// <summary>
    /// 获取JSON文件路径(用于UI显示)
    /// </summary>
    public string GetJSONFilePath()
    {
        return jsonFilePath;
    }

    /// <summary>
    /// 获取所有对象名称列表(用于UI显示)
    /// </summary>
    public List<string> GetAllObjectNames()
    {
        List<string> names = new List<string>();
        if (currentObjectsData != null)
        {
            foreach (var data in currentObjectsData)
            {
                names.Add(data.name);
            }
        }
        return names;
    }

    /// <summary>
    /// 获取所有对象数据(用于外部处理)
    /// </summary>
    public List<TransformData> GetAllObjectData()
    {
        LoadObjectsFromJSON();
        return new List<TransformData>(currentObjectsData);
    }

    /// <summary>
    /// 添加初始化完成回调
    /// </summary>
    public void AddInitializationCallback(System.Action<List<TransformData>> callback)
    {
        if (callback != null)
        {
            OnInitializationComplete += callback;
        }
    }

    /// <summary>
    /// 移除初始化完成回调
    /// </summary>
    public void RemoveInitializationCallback(System.Action<List<TransformData>> callback)
    {
        if (callback != null)
        {
            OnInitializationComplete -= callback;
        }
    }

    /// <summary>
    /// 清除所有初始化回调
    /// </summary>
    public void ClearAllInitializationCallbacks()
    {
        OnInitializationComplete = null;
    }

    /// <summary>
    /// 强制重新初始化并触发回调
    /// </summary>
    public void ReinitializeWithCallback(System.Action<List<TransformData>> callback = null)
    {
        if (callback != null)
        {
            OnInitializationComplete += callback;
        }
        StartCoroutine(InitializeJSONSystem());
    }
}

 使用案例如下:

using GameLogic;
using System.Collections;
using System.Collections.Generic;
using Unity.XR.PXR;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.XR;

public class MRSeeThrough : MonoBehaviour
{
    AnchorLoad jsonMgr;
    [SerializeField]
    GameObject prefab;
    bool butY = false; 
    bool btnA = false;
    bool isClick = false;
    int num = 0;

    void Start()
    {
        PXR_Manager.EnableVideoSeeThrough = true; // 启用视频透视
        jsonMgr = FindObjectOfType<AnchorLoad>();
        jsonMgr.AddInitializationCallback(OnJSONInitialized);
    }
   
    // 处理按键事件
    private void ProcessKeyEvent()
    {
        InputDevices.GetDeviceAtXRNode(XRNode.LeftHand).TryGetFeatureValue(CommonUsages.primaryButton, out butY);
        InputDevices.GetDeviceAtXRNode(XRNode.RightHand).TryGetFeatureValue(CommonUsages.primaryButton, out btnA);
        if (btnA && butY) 
        {
            if (!isClick)
            {
                num++;
                var go = Instantiate(prefab);
                var spatialAnchor = go.GetComponent<PXRSample_SpatialAnchor>();
                go.transform.position = Vector3.zero;
                go.transform.rotation = Quaternion.Euler(Vector3.zero);
                go.name = "新增点"+ num;
                spatialAnchor.curName = go.name;
                Debug.Log("两个按钮同时按下");
            }
            isClick = true;
           
        }
        else {
            isClick = false;
        }
        
    }
    private void OnJSONInitialized(List<TransformData> objectData)
    {
        foreach (TransformData data in objectData)
        {
            CreateSingleObject(data);
        }
    }

    /// <summary>
    /// 创建单个对象
    /// </summary>
    private void CreateSingleObject(TransformData data)
    {
        var go = Instantiate(prefab);
        var spatialAnchor = go.GetComponent<PXRSample_SpatialAnchor>();
        go.transform.position = data.matrix.position;
        go.transform.rotation = Quaternion.Euler(data.matrix.rotation);
        go.name = data.name;
        spatialAnchor.curName = data.name;
    }
    private void Update()
    {
        ProcessKeyEvent();
    }
    void OnDestroy()
    {
        if (jsonMgr != null)
        {
            jsonMgr.RemoveInitializationCallback(OnJSONInitialized);
        }
    }
}

更多推荐