项目需求为:
1.实现存档列表,显示存档截图,可以查看之前保存的所有存档
2.点击存档直接加载到场景
首先,定义两个类,用于声明存档列表和存档所需要的List
[System.Serializable]
public class SaveData
{
//存储目标物的位置和朝向
public List<Vector3> targetPosition = new List<Vector3>();
public List<Quaternion> targetRotation = new List<Quaternion>();
//保存截图
public string targetImg;
}
[System.Serializable]
public class SaveList
{
//存档列表存储各个存档的地址
public List<string> DataPath = new List<string>();
}
存储存档列表、存档
//存档
public void TestSave()
{
//取当前时间来做存档的名字
string now = DateTime.Now.ToString("yyyy-M-d-HH-mm-ss");
string path = Application.dataPath + "/StreamingFile/" + now;
//调用存档方法
SaveData saveData = CreatSave(path);
//利用jsonutility将savedata转为json
string saveJson = JsonUtility.ToJson(saveData);
//将json写入文件
//新建StreamWriter,写入json
StreamWriter streamWriter = new StreamWriter(path + ".json");
streamWriter.Write(saveJson);
//关闭StreamWriter
streamWriter.Close();
TestListSave(path);
Debug.Log("保存成功");
}
/// <summary>
/// 存储存档列表
/// </summary>
/// <param name="pathname"></param>
void TestListSave(string pathname)
{
SaveList sl = new SaveList();
string path = Application.dataPath + "/StreamingFile/list.list";
//alllist是临时List,用于存所有的存档个数
alllist.Add(pathname);
sl.DataPath = alllist;
//将所有的存档个数打包保存(覆盖式)
string saveList = JsonUtility.ToJson(sl);
StreamWriter streamWriter = new StreamWriter(path);
streamWriter.Write(saveList);
streamWriter.Close();
}
/// <summary>
/// 创建Save对象,存储当前状态
/// </summary>
/// <returns></returns>
private SaveData CreatSave(string path)
{
SaveData saveTest = new SaveData();
//all是所有的目标物的父物体,将位置和旋转存入list
for (int i = 0;i < all.childCount;i++)
{
saveTest.targetPosition.Add(all.GetChild(i).position);
saveTest.targetRotation.Add(all.GetChild(i).rotation);
}
//将存档截图地址保存
saveTest.targetImg = path;
//截图功能
CameraCapture(path, main, new Rect(0, 0, Screen.width, Screen.height));
return saveTest;
}
截图相关代码
//指定相机指定范围
public static void CameraCapture(string i, Camera camera, Rect rect)
{
string path = Path.Combine(i, $"{i}.png");
int w = (int)rect.width;
int h = (int)rect.height;
RenderTexture rt = new RenderTexture(w, h, 0);
//将相机渲染内容存到指定RenderTexture
camera.targetTexture = rt;
camera.Render();
//激活指定RenderTexture
RenderTexture.active = rt;
//参数4:mipchain多级渐远纹理
Texture2D t2D = new Texture2D(w, h, TextureFormat.ARGB32, true);
//防止截黑屏,可能会报错
//yield return new WaitForEndOfFrame();
//把RenderTexture像素读到texture2d
t2D.ReadPixels(rect, 0, 0);
t2D.Apply();
//存成PNG
byte[] bytes = t2D.EncodeToPNG();
File.WriteAllBytes(path, bytes);
//用完重置、销毁
camera.targetTexture = null;
RenderTexture.active = null;
GameObject.Destroy(rt);
}
public static Sprite LoadShot(string i)
{
string shotPath = Application.dataPath + "/StreamingFile/Shot";
var path = Path.Combine(shotPath, $"{i}.png");
Texture2D t = new Texture2D(640, 360);
t.LoadImage(GetImgByte(path));
return Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0.5f, 0.5f));
}
static byte[] GetImgByte(string path)
{
FileStream s = new FileStream(path, FileMode.Open);
byte[] imgByte = new byte[s.Length];
s.Read(imgByte, 0, imgByte.Length);
s.Close();
return imgByte;
}
public static void deleteShot(string i)
{
string shotPath = Application.dataPath + "/StreamingFile/Shot";
var path = Path.Combine(shotPath, $"{i}.png");
if (File.Exists(path))
{
File.Delete(path);
Debug.Log($"删除{i}");
}
}
读取存档列表和存档
//读档
public void LoadTest(Text text)
{
string filepath = Application.dataPath + "/StreamingFile/" + text.text + ".json";
if (File.Exists(filepath))
{
//创建StreamReader,读取json
StreamReader streamReader = new StreamReader(filepath);
//将json赋值给string
string json = streamReader.ReadToEnd();
//关闭
streamReader.Close();
//将字符串json转换为savedata对象
SaveData saveData = JsonUtility.FromJson<SaveData>(json);
SetLoadSave(saveData);
}
else
{
Debug.Log("没有存档");
}
}
/// <summary>
/// 根据列表加载存档处理数据
/// </summary>
/// <param name="pathname"></param>
void TestListLoad()
{
string path = Application.dataPath + "/StreamingFile/list.list";
if (File.Exists(path))
{
//创建StreamReader,读取json
StreamReader streamReader = new StreamReader(path);
//将json赋值给string
string json = streamReader.ReadToEnd();
//关闭
streamReader.Close();
//将字符串json转换为SaveList对象
SaveList saveList = JsonUtility.FromJson<SaveList>(json);
if(saveList != null)
{
for (int i = 0; i< saveList.DataPath.Count; i++)
{
根据数据显示scroll view下的物体并将数据赋过去
var obj = list.transform.GetChild(0).GetChild(0).GetChild(i);
obj.gameObject.SetActive(true);
obj.GetComponent<Image>().sprite = LoadShot(saveList.DataPath[i]);
string str = saveList.DataPath[i].Split("/")[5];
obj.GetChild(2).GetComponent<Text>().text = str.Substring(0, 18);
//读档时候将之前的列表内容读到临时list暂存
alllist.Add(saveList.DataPath[i]);
}
}
}
}
/// <summary>
/// 将savedata数据赋值给当前场景
/// </summary>
/// <param name="saveData"></param>
private void SetLoadSave( SaveData saveData)
{
if (saveData != null)
{
for (int i = 0; i < all.childCount; i++)
{
all.GetChild(i).position = saveData.targetPosition[i];
all.GetChild(i).rotation = saveData.targetRotation[i];
}
}
}