1、设计模型数据类:需要litjson文件解析数据
using LitJson;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 持久化模型数据类
/// </summary>
public class PersistModelItemData
{
public int Id;//设置id
public Matrix4x4 TransformMatrix;//4x4矩阵
public GameObject go;
public string GoName;
public PersistModelItemData()
{
}
public PersistModelItemData(int id, GameObject go)
{
this.Id = id;
this.go = go;
this.GoName = go.name;
}
/// <summary>
/// 将物体的三种属性转换成矩阵数据
/// </summary>
public void InitMatrix4x4()
{
Matrix4x4 _mat = new Matrix4x4();
_mat.SetTRS(go.transform.position, go.transform.rotation, go.transform.localScale);
TransformMatrix = _mat;
}
/// <summary>
/// 保存json
/// </summary>
/// <returns></returns>
public JsonData ToJson()
{
InitMatrix4x4();
JsonData jsonData = new JsonData();
jsonData["Id"] = Id;
jsonData["GoName"] = GoName;
jsonData["TransformMatrix"] = MatrixToString(TransformMatrix);
return jsonData;
}
/// <summary>
/// 矩阵转换为string数据方法
/// </summary>
/// <param name="matrix4X4"></param>
/// <returns></returns>
private string MatrixToString(Matrix4x4 matrix4X4 )
{
string str = "";
str += matrix4X4.m00.ToString() + ",";
str += matrix4X4.m10.ToString() + ",";
str += matrix4X4.m20.ToString() + ",";
str += matrix4X4.m30.ToString() + ",";
str += matrix4X4.m01.ToString() + ",";
str += matrix4X4.m11.ToString() + ",";
str += matrix4X4.m21.ToString() + ",";
str += matrix4X4.m31.ToString() + ",";
str += matrix4X4.m02.ToString() + ",";
str += matrix4X4.m12.ToString() + ",";
str += matrix4X4.m22.ToString() + ",";
str += matrix4X4.m32.ToString() + ",";
str += matrix4X4.m03.ToString() + ",";
str += matrix4X4.m13.ToString() + ",";
str += matrix4X4.m23.ToString() + ",";
str += matrix4X4.m33.ToString();
return str;
}
/// <summary>
/// 读取Json
/// </summary>
/// <returns></returns>
public void FromJson(JsonData json)
{
this.Id = int.Parse(json["Id"].ToString());
this.GoName = json["GoName"].ToString();
//矩阵
JsonData childJsonData = json["TransformMatrix"];
this.TransformMatrix = StringToMatrix(childJsonData);
}
/// <summary>
/// 读取的json转换为矩阵数据方法
/// </summary>
/// <param name="jsonData"></param>
/// <returns></returns>
public Matrix4x4 StringToMatrix(JsonData jsonData)
{
string str = jsonData.ToString();
string[] strs = str.Split(',');
Vector4 v1 = new Vector4(float.Parse(strs[0]), float.Parse(strs[1]), float.Parse(strs[2]), float.Parse(strs[3]));
Vector4 v2 = new Vector4(float.Parse(strs[4]), float.Parse(strs[5]), float.Parse(strs[6]), float.Parse(strs[7]));
Vector4 v3 = new Vector4(float.Parse(strs[8]), float.Parse(strs[9]), float.Parse(strs[10]), float.Parse(strs[11]));
Vector4 v4 = new Vector4(float.Parse(strs[12]), float.Parse(strs[13]), float.Parse(strs[14]), float.Parse(strs[15]));
Matrix4x4 matrix4X4 = new Matrix4x4(v1, v2, v3, v4);
return matrix4X4;
}
}
2、存储数据和操作数据的类:
using LitJson;
using RsFramework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Sirenix.OdinInspector;
using YYSUI;
/// <summary>
/// 持久化模型数据
/// </summary>
public class PersistModelDataScript : MonoSingleton<PersistModelDataScript>
{
public List<int> IDList = new List<int>();//id列表
public Dictionary<int, PersistModelItemData> _DicPersistModel = new Dictionary<int, PersistModelItemData>();//id对应的模型数据列表
// Start is called before the first frame update
void Awake()
{
Load();
}
private void OnApplicationQuit()
{
Save();
}
/// <summary>
/// 添加到字典集合中
/// </summary>
/// <param name="gameObject">表示持久化数据的模型</param>
public void Add(GameObject go)
{
int id;
if (IDList.Count == 0)
{
id = 1;
}
else
{
id = IDList[IDList.Count - 1] + 1;
}
IDList.Add(id);
PersistModelItemData persistModelItemData = new PersistModelItemData(id, go);
_DicPersistModel.Add(id, persistModelItemData);
}
/// <summary>
/// 从字典集合中移除模型
/// </summary>
/// <param name="gameObject"></param>
public void Remove(GameObject go)
{
PersistModelItemData persistModelItemData = null;
foreach (var item in _DicPersistModel.Values)
{
if (go == item.go)
{
persistModelItemData = item;
}
}
if (persistModelItemData != null)
{
Destroy(persistModelItemData.go);
_DicPersistModel.Remove(persistModelItemData.Id);
IDList.Remove(persistModelItemData.Id);
}
}
/// <summary>
/// 加载持久化模型的数据
/// </summary>
public void Load()
{
//1、获取保存的路径
string JsonPath = Application.streamingAssetsPath + "/PersistModelData" + ".json";
//读取数据,并去除收尾空格
string jsonStr = File.ReadAllText(JsonPath).Trim();
//判空
if (jsonStr.Length != 0)
{
//2、创建json对象,将传过来的数据转换为对象
JsonData jsonData = JsonMapper.ToObject(jsonStr);
//单个数据
//PersistModelItemData persistModelItemData = new PersistModelItemData();
//persistModelItemData.FromJson(jsonData);
//MatrixUtils.Matrix4x4(cube2, persistModelItemData.TransformMatrix);
for (int i = 0; i < jsonData.Count; i++)
{
if (IDList.Contains((int)jsonData[i]["Id"]))
{
}
else
{
PersistModelItemData persistModelItemData = new PersistModelItemData();
persistModelItemData.FromJson(jsonData[i]);
//实例化物体,赋值
GameObject go = ResourcesMgr.GetInstance().LoadAsset("PersistModel/" + persistModelItemData.GoName, true);
persistModelItemData.go = go;
MatrixUtils.Matrix4x4(go.transform, persistModelItemData.TransformMatrix);
IDList.Add(persistModelItemData.Id);
_DicPersistModel.Add(persistModelItemData.Id, persistModelItemData);
}
}
}
Debug.Log("加载拖拽模型数据");
}
/// <summary>
/// 存储持久化模型的数据
/// </summary>
public void Save()
{
//读取
string JsonPath = Application.streamingAssetsPath + "/PersistModelData" + ".json";
//找到当前路径
FileInfo file = new FileInfo(JsonPath);
//判断有没有文件,有则打开文件,没有创建后打开文件
StreamWriter sw = file.CreateText();
JsonData jsonData = new JsonData();
foreach (var item in _DicPersistModel.Values)
{
jsonData.Add(item.ToJson());
}
//单个数据
//PersistModelItemData persistModelItemData = new PersistModelItemData(1,cube1.gameObject);
//将转换好的字符串存进文件
sw.WriteLine(jsonData.ToJson());
//注意释放资源
sw.Close();
sw.Dispose();
Debug.Log("保存拖拽模型数据");
}
}
3、矩阵数据接口,根据矩阵数据获取到模型设置的位置、旋转和缩放:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 矩阵接口,获取物体的位置,旋转和缩放
/// </summary>
internal static class MatrixUtils
{
public static void Matrix4x4(this Transform transfrom, Matrix4x4 matrix4X4)
{
transfrom.localScale = matrix4X4.GetScale();
transfrom.rotation = matrix4X4.GetRotation();
transfrom.position = matrix4X4.GetPosition();
}
/// <summary>
/// 根据矩阵数据获得scale数据
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public static Vector3 GetScale(this Matrix4x4 m)
{
var x = Mathf.Sqrt(m.m00 * m.m00 + m.m01 * m.m01 + m.m02 * m.m02);
var y = Mathf.Sqrt(m.m10 * m.m10 + m.m11 * m.m11 + m.m12 * m.m12);
var z = Mathf.Sqrt(m.m20 * m.m20 + m.m21 * m.m21 + m.m22 * m.m22);
return new Vector3(x, y, z);
}
/// <summary>
/// 根据矩阵数据获得position数据
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public static Vector3 GetPosition(this Matrix4x4 matrix4X4)
{
var x = matrix4X4.m03;
var y = matrix4X4.m13;
var z = matrix4X4.m23;
return new Vector3(x, y, z);
}
/// <summary>
/// 根据矩阵数据获得rotation数据
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
public static Quaternion GetRotation(this Matrix4x4 matrix4X4)
{
float qw = Mathf.Sqrt(1f + matrix4X4.m00 + matrix4X4.m11 + matrix4X4.m22) / 2;
float w = 4 * qw;
float qx = (matrix4X4.m21 - matrix4X4.m12) / w;
float qy = (matrix4X4.m02 - matrix4X4.m20) / w;
float qz = (matrix4X4.m10 - matrix4X4.m01) / w;
return new Quaternion(qx, qy, qz, qw);
}
}
4、对象池使用:
/*
* 内容:UI框架
* 功能:资源加载管理器,增加缓存,不重复加载
*/
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
using System.Collections.Generic;
namespace YYSUI
{
public class ResourcesMgr : MonoBehaviour
{
/* 字段 */
private static ResourcesMgr _Instance; //本脚本私有单例实例
private Hashtable ht = null; //容器键值对集合
/// <summary>
/// 得到实例(单例)
/// </summary>
/// <returns></returns>
public static ResourcesMgr GetInstance()
{
if (_Instance == null)
{
_Instance = new GameObject("_ResourceMgr").AddComponent<ResourcesMgr>();
}
return _Instance;
}
void Awake()
{
ht = new Hashtable();
}
/// <summary>
/// 调用资源(带对象缓冲技术)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <param name="isCatch"></param>
/// <returns></returns>
public T LoadResource<T>(string path, bool isCatch) where T : UnityEngine.Object
{
if (ht.Contains(path))
{
return ht[path] as T;
}
T TResource = Resources.Load<T>(path);
if (TResource == null)
{
Debug.LogError(GetType() + "/Resource 提取的资源找不到,请检查。 path=" + path);
}
else if (isCatch)
{
ht.Add(path, TResource);
}
return TResource;
}
/// <summary>
/// 调用资源(带对象缓冲技术)
/// </summary>
/// <param name="path"></param>
/// <param name="isCatch"></param>
/// <returns></returns>
public GameObject LoadAsset(string path, bool isCatch)
{
GameObject goObj = LoadResource<GameObject>(path, isCatch);
GameObject goObjClone = GameObject.Instantiate<GameObject>(goObj);
goObjClone.name = goObj.name;
if (goObjClone == null)
{
Debug.LogError(GetType() + "/LoadAsset()/克隆资源不成功,请检查。 path=" + path);
}
//goObj = null;//??????????
return goObjClone;
}
public T LoadAsset<T>(string path, bool isCatch) where T : UnityEngine.Object
{
T goObj = LoadResource<T>(path, isCatch);
T goObjClone = GameObject.Instantiate<T>(goObj);
if (goObjClone == null)
{
Debug.LogError(GetType() + "/LoadAsset()/克隆资源不成功,请检查。 path=" + path);
}
//goObj = null;//??????????
return goObjClone;
}
}//Class_end
}
5、使用范例:
5.1:将特殊的模型设置成预制件,放到Resources对应的文件夹下
5.2:在合适的时候实例化特殊的模型,加入到数据字典中(PersistModel是我自己设置的文件夹路径,modelName表示特殊模型预制件的名称与数据中保存的一一对应)
做这一步操作是为了确保程序开始加载数据的时候不会出错,外边套一个gameobject,设置如下,里边的暂没有要求
obj = ResourcesMgr.GetInstance().LoadAsset("PersistModel/" + modelName, true);
加入到数据字典中语句
PersistModelDataScript.Instance.Add(obj);
5.3:在合适的时候调用删除方法,将模型数据移除出数据字典中,移除出数据字典中语句(transformGizmo.target.gameObject表示移除的特殊模型gameobject)
PersistModelDataScript.Instance.Remove(transformGizmo.target.gameObject);
5.4保存的数据如下:
[
{
"Id": 1,
"GoName": "SGBZ_ZBP",
"TransformMatrix": "1,0,0,0,0,1,0,0,0,0,1,0,60.1446,-3.257808E-17,73.35932,1"
},
{
"Id": 2,
"GoName": "SGBZ_AQWL",
"TransformMatrix": "1,0,0,0,0,1,0,0,0,0,1,0,60.4089,-3.604125E-17,81.15768,1"
}
]
5.5、要想程序一开始就执行此代码,需要调用此代码或者将PersistModelDataScript脚本挂载到场景中,就可以实现程序开始记录需要保存的特殊模型的数据,在重新打开程序时,会自动读取之前的模型数据。