游戏的存档和读档和一些注意点

本文介绍了Unity中的协程使用、物体旋转控制、OnTriggerEnter/OnCollisionEnter的区别、动画Clip、PlayerPrefs数据存储以及二进制、JSON和XML存档与读档的方法,为开发者提供实用的编程参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.通过协程 使怪物生成,通过 协程里面包含方法(有协程启动)来实现多个协程的效果

IEnumerator TimeBulid()
    {
        yield return new WaitForSeconds(Random.Range(1,5));
        RangeBulid();
    }
    private void MosterDead()
    {
        if(moster != null)
        {
            moster.GetComponent<BoxCollider>().enabled=false;
            moster.SetActive(false);
            moster=null;
        }
        StartCoroutine("TimeBulid");
    }

2.控制对象随鼠标旋转

transform.eulerAngles是Unity中的一个属性,用于获取或设置物体的欧拉角(Euler Angles)。欧拉角是一种表示物体旋转的方式,通过三个角度(分别对应x、y、z轴)来描述物体的旋转状态。

在使用transform.eulerAngles时,有一些注意事项:

  1. 不要直接对eulerAngles的某个轴进行赋值,例如eulerAngles.x = 10。这样做会导致旋转的不稳定和意外的旋转效果。
  2. 如果需要设置新的欧拉角值,应该同时设置所有的轴,例如transform.eulerAngles = new Vector3(x, y, z)。
  3. Unity会将欧拉角转换为存储在Transform.rotation中的旋转值,并在需要时将其转换回欧拉角。

Mathf.Clamp方法的语法如下:

public static float Clamp(float value, float min, float max);
其中,value表示要限制的值,min表示限制范围的最小值,max表示限制范围的最大值。如果value小于min,则返回min;如果value大于max,则返回max;否则返回value本身。

//分别求出鼠标在x和y上位置占屏幕大小的比例
            float xPosPrecent=Input.mousePosition.x/Screen.width;
            float yPosPrecent = Input.mousePosition.y /Screen.height;
        //设定对象的x和y的角度 
            float xAngle=-Mathf.Clamp(yPosPrecent*maxXrotation,minXrotation,maxXrotation)+15;
            float yAngle = Mathf.Clamp(xPosPrecent * maxYrotation, minYrotation, maxYrotation)-60;

           transform.eulerAngles=new Vector3(xAngle,yAngle,0); 

3.Collison和它的碰撞对象 ColliderOnTriggerEnterOnCollisionEnter的区别和用法

Collider是Collison这个类里面的一个变量(碰撞对象)

OnTriggerEnterOnCollisionEnter的区别和用法

OnCollisionEnter方法要求碰撞的发起方必须拥有刚体,而被碰撞方有没有刚体并不重要。OnTriggerEnter方法则对此没有要求,只需要碰撞双方有一个具有刚体即可触发。即刚体是一个判断是否实现碰撞的是与否的标志。
刚体对于系统的开销是很大的,所以在使用刚体时,根据可能发生的碰撞触发事件,适当的减少刚体,是一个减少资源消耗的好办法。 比如地面就可以不设置刚体,因为地面是永远不动的,把人物设置刚体就可以实现真实的物理碰撞效果了。           
原文链接:https://blog.csdn.net/tianyao9hen/article/details/53141141

4.Animation的Clip(默认动画

5.https://blog.csdn.net/pixel_nplance/article/details/80759122

6.PlayerPrefs数据存储

PlayerPrefs使用的是类似字典的存储方式。

玩家进行数据存储时,需要输入一个Key参数以及一个Value参数,也就是键和值。每个键对应一个将要存储到硬盘中的值。

   public void MusicSwitch()
    {
        if(musicToggle.isOn == false)
        {
        
            musicAudio.enabled = false;
            PlayerPrefs.SetInt("MusicOn", 0);
        }
        else
        {
            
            musicAudio.enabled = true;
            PlayerPrefs.SetInt("MusicOn", 1);

        }
        PlayerPrefs.Save();
    }

很适合用来存储那些即使丢失了也无所谓的数据。

  • 首先当然是玩家的偏好设置,比如音乐音量 是否全屏等设置选项。

  • 第二 则是一些简单的数据。比如玩家的得分列表。

  • 第三 是在制作游戏原型时暂时的数据存储。

注意完事之后要保存 

7.二级制存档和读档

大致思路

首先按创建一个类 加上可序列化代码 不需要继承自 MonoBehaviour  用这个类创建对象,再用二进制格式化程序的方法来序列化对象     读档则相反

一些概念:

1.在Unity中,  Application.dataPath  是一个用于访问项目中"Assets"文件夹的字符串变量。它表示了项目在文件系统中的路径,  我们可以通过它来读取或写入项目中的资源和文件。

2.文件和流 从零开始的Unity学习_15. 文件和流(上) - 技术专栏 - Unity官方开发者社区icon-default.png?t=N7T8https://developer.unity.cn/projects/63bcce43edbc2a3ec331cc75

存档流程和代码:

    private void SavebyBin()
    {
        SaveDate saveDate=savedata();
        //创建一个二进制格式化程序
        BinaryFormatter bf=new BinaryFormatter();
        //创建一个文件流
        FileStream fileStream = File.Create(Application.dataPath + "/StreamingFile" + "/dataByBin.txt");
        //二进制格式化程序的方法来序列化对象 参数:创建的文件流 需要序列化的对象
        bf.Serialize(fileStream, saveDate);
        //关闭流
        fileStream.Close();
    }

读档流程和代码

   private void LoadByBin()
    {
        if(File.Exists(Application.dataPath + "/StreamingFile" + "/dataByBin.txt"))
        {
            //加载游戏
            //反序列化 打开一个文件流
            BinaryFormatter bf = new BinaryFormatter();
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/dataByBin.txt", FileMode.Open);
            SaveDate saveDate = (SaveDate)bf.Deserialize(fileStream);
            fileStream.Close();
            SetGame(saveDate);
           

        }
        else
        {
            UIManager._instance.Showtext("存档文件不存在");
        }

    }

8.JSON存档和读档

和二进制差不多,用了插件省略了一些步骤

存档:

 private void SavebyJsion()
    {
        SaveDate Save=savedata();
        string filePath = Application.dataPath + "/StreamingFile" + "/dataByJson.json";
        //调用JsonMapper.ToJson()方法把对象转化为JSON字符串
        string saveJsonstr = JsonMapper.ToJson(Save);
        //StreamWriter  Write()把字符串写入文件中
        StreamWriter sw = new StreamWriter(filePath);
        sw.Write(saveJsonstr);
        sw.Close();
        UIManager._instance.Showtext("保存成功");
    }

读档:

    private void LoadByBin()
    {
        if(File.Exists(Application.dataPath + "/StreamingFile" + "/dataByBin.txt"))
        {
            //加载游戏
            //反序列化 打开一个文件流
            BinaryFormatter bf = new BinaryFormatter();
            FileStream fileStream = File.Open(Application.dataPath + "/StreamingFile" + "/dataByBin.txt", FileMode.Open);
            SaveDate saveDate = (SaveDate)bf.Deserialize(fileStream);
            fileStream.Close();
            SetGame(saveDate);
            UIManager._instance.Showtext("");

        }
        else
        {
            UIManager._instance.Showtext("存档文件不存在");
        }

    }

9.Xml存档和读档

通过创建Xml文档,创建多个层级元素,将对象数据转化为字符串存入各个层级元素中,代码较前两种复杂

存档:

 private void SavebyXML()
    {
        SaveDate save=savedata();
        string filePath = Application.dataPath + "/StreamingFile" + "/dataByXml.txt";
        //创建XML文档
        XmlDocument xmlDoc = new XmlDocument();
        //创建根节点
        XmlElement root = xmlDoc.CreateElement("save");
        //设置根节点属性
        root.SetAttribute("name", "savefiale");
        XmlElement target;
        XmlElement targetPosition;
        XmlElement monsterType;
        //将数据转化为string写入到xml文档中的各个元素中
        for (int i=0;i<save.liveTargetPosion.Count;i++)
        {
            target = xmlDoc.CreateElement("target");
            targetPosition= xmlDoc.CreateElement("position");
            targetPosition.InnerText = save.liveTargetPosion[i].ToString();
            monsterType=xmlDoc.CreateElement("type");
            monsterType.InnerText = save.MosterTypes[i].ToString();
            //设置层级关系
            target.AppendChild(monsterType);
            target.AppendChild(targetPosition);
            root.AppendChild(target);
        }
        XmlElement shootnum=xmlDoc.CreateElement("shootnum");
        shootnum.InnerText=save.shootnum.ToString();
        root.AppendChild(shootnum);
        XmlElement score = xmlDoc.CreateElement("score");
        score.InnerText=save.score.ToString();
        root.AppendChild(score);
        xmlDoc.AppendChild(root);
        xmlDoc.Save(filePath);
        if(File.Exists(filePath))
        {
            UIManager._instance.Showtext("保存成功");
        }

    }

读档:

private void LoadByXML()
    {
        SaveDate save=new SaveDate();
        string filePath = Application.dataPath + "/StreamingFile" + "/dataByXml.txt";
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(filePath); 
        XmlNodeList targets=xmlDoc.GetElementsByTagName("target");
        if(File.Exists(filePath))
        {
            if (targets.Count != 0)
            {
                foreach (XmlNode target in targets)
                {
                    XmlNode targetPosition = target.ChildNodes[0];
                    int targetPositionIndex = int.Parse(target.InnerText);
                    save.liveTargetPosion.Add(targetPositionIndex);

                    XmlNode Moster = target.ChildNodes[1];
                    int MosterTypeIndex = int.Parse(Moster.InnerText);
                    save.MosterTypes.Add(MosterTypeIndex);
                }
            }
            XmlNodeList shootnum = xmlDoc.GetElementsByTagName("shootnum");
            int shouutnumCount = int.Parse(shootnum[0].InnerText);
            save.shootnum = shouutnumCount;
            XmlNodeList score = xmlDoc.GetElementsByTagName("score");
            int scoreCount = int.Parse(score[0].InnerText);
            save.score = scoreCount;
            SetGame(save);
            UIManager._instance.Showtext("");
        }
        else
        {
            UIManager._instance.Showtext("存档文件不存在");
        }
     
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值