2022.1.21SaveGridBuild效果2:持久存储建筑

想做个存档功能,但是JSON一直没看懂,也不会用,就想试试先用PlayerPrefs实现一下存档功能

先说想达到的效果,我要存档的游戏物体就是上一篇中做出来的可建造对象,它有三个属性,x坐标,z坐标,和建筑代号。至于为什么不用二维数组,因为PlayerPrefs只能存int、string、float、三种数据,这篇文章就是要用PlayerPrefs模拟出一个二维数组。

最终期望的效果很简单,就是希望这次建造完退出游戏,下次再进来时会在原有的位置生成原来的建筑。

要存储这个建筑,其实只需存储它的三种属性,有了这三种属性,就可以根据条件来重新生成这个建筑。不过PlayerPrefs每次只能存储一个数据,而我的网格是10*10的,也就是说最多要存300个数据,才能在填满网格的情况下重新生成建筑,显然工作量太大,我们可以用编码的方式,一个整数即可代表一个建筑的三种属性,在读取的时候进行解码,仍然获得完整的数据。

2022.1.21

经过纠错,目前已达成期望效果,这种保存方式确实可行

下一个目标是做出多网格建筑的建造功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
///-----------------------------------------------------------------------------------------          
///   Founction:	
///   Author:               	AttouchAusturo
///   LatestReviseTime:	        2022.1.24
///-----------------------------------------------------------------------------------------
 
public class BuildAndSavePlus : MonoBehaviour
{
    //建筑的代号
    public int buildingID;
    //建筑预制件
    public GameObject tentPrefab;
    public GameObject boxPrefab;
    //要建造的建筑和建筑实例
    public GameObject objectToBuild;
    public GameObject objectToReBuild;
    public GameObject buildings;
 
    //编码内容
    public int positionX = 0, positionZ, reBuildBuildingID;
 
    //公有的建筑码
    public int allCode;
    //建筑码存储地址 /编码后转字符串
    public int theAddress;
    public string strTheAddress;
 
    //射线获取坐标
    private Ray ray;
    private RaycastHit hit;
    private Vector3 target;//鼠标点击位置的世界坐标
    //坐标转换
    private Vector3 groundArea;
 
    private void OnGUI()
    {
        GUILayout.BeginHorizontal("box");
        GUILayout.Label("选择建筑");
        if (GUILayout.Button("小帐篷")) buildingID = 1;//选择建筑
        if (GUILayout.Button("储物匣")) buildingID = 2;
        GUILayout.EndHorizontal();
    }
 
    private void Start()
    {
        //ClearAllBuildings();//清除存档内容为0
        TryingMyRebuildMethodWithPlayerPrefs();//再次运行时重建
    }
 
    private void Update()
    {
        buildingID = CreateBuilding(buildingID);//建造功能函数 /包含 射线检测 坐标取整 生成建筑 生成编码并保存
    }
 
    //建造功能
    private int CreateBuilding(int buildingID)
    {
        if (buildingID == 1) objectToBuild = tentPrefab;
        if (buildingID == 2) objectToBuild = boxPrefab;
 
        //如何区分两个因果关系的点击为两次点击
        if (buildingID != 0)
        {
            //当点击鼠标右键时
            if (Input.GetMouseButtonDown(1))
            {
                //鼠标在屏幕的位置
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                if (Physics.Raycast(ray, out hit))
                {
                    //绘制出一条从相机射出的红色射线
                    Debug.DrawLine(Camera.main.transform.position, hit.point, Color.red);
                }
                target = hit.point;//获取点击位置的世界坐标
 
                groundArea = new Vector3((int)target.x / 10 * 10 + 5, 0, (int)target.z / 10 * 10 + 5);//坐标取整并移至格子中心 /取整:/10*10 /取中:+5
                buildings = Instantiate(objectToBuild, groundArea, Quaternion.identity) as GameObject;//在格子中央生成该物体
 
                //将新建筑编码
                allCode = (int)target.x / 10 * 10000 + (int)target.z / 10 * 100 + buildingID;
                //保存
                TryingMyNewSavingMethodWithPlayerPrefs();
 
                return buildingID = 0;
            }
        }
        return buildingID;
    }
 
    //清除所有建筑
    private void ClearAllBuildings()
    {
 
        for (int i = 1; i < 11; i++)
        {
            for (int j = 1; j < 11; j++)
            {
                theAddress = 10000 + (i * 100) + j;
                strTheAddress = theAddress.ToString();
                PlayerPrefs.SetInt(strTheAddress, 0);
            }
        }
 
    }
 
    //保存建筑 /将Code解码来确定将其放入哪个地址中
    private void TryingMyNewSavingMethodWithPlayerPrefs()
    {
 
        for(int i = 1; i < 11; i++)
        {
            for(int j = 1; j < 11; j++)
            {
                if (allCode / 10000 == i - 1 && allCode % 10000 / 100 == j - 1)
                {
                    theAddress = 10000 + (i * 100) + j;
                    strTheAddress = theAddress.ToString();
                    PlayerPrefs.SetInt(strTheAddress, allCode);
                }
            }
        }
 
    }
 
    //取出所有地址中的值,赋给Code并进行解码
    private void TryingMyRebuildMethodWithPlayerPrefs()
    {
        int allCode;
 
        for (int i = 1; i < 11; i++)
        {
            for (int j = 1; j < 11; j++)
            {
                theAddress = 10000 + (i * 100) + j;
                strTheAddress = theAddress.ToString();
                allCode = PlayerPrefs.GetInt(strTheAddress);
                AnalyzeCode(allCode);//解码
            }
        }
 
    }
 
    //解码 并生成建筑
    private void AnalyzeCode(int allCode)
    {
        if (allCode != 0)
        {
            positionX = allCode / 10000;
            positionZ = allCode % 10000 / 100;
            reBuildBuildingID = allCode % 100;
            if (reBuildBuildingID == 1) objectToReBuild = tentPrefab;
            if (reBuildBuildingID == 2) objectToReBuild = boxPrefab;
            buildings = Instantiate(objectToReBuild, new Vector3(positionX * 10 + 5, 0, positionZ * 10 + 5), Quaternion.identity) as GameObject;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值