Unity游戏存档之Xml存档

发表于2018-04-09
评论0 1.4k浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594
很多公司的游戏都用的这个XML存档,对于XML的优势这里就和大家介绍了,本篇文章就通过一个Demo讲解如何使用以下脚本对游戏进行存档。

一个管理类 用来管理 存档 读档
#region 快门:存取总控制  
   public void SaveSnap(string filename)  
   {  
       var xmlDoc = new XmlDocument();  
       try  
       {  
           var xmlRoot = xmlDoc.CreateElement("Snaps");  
           xmlDoc.AppendChild(xmlRoot);  
           var xmlModel = xmlDoc.CreateElement("Models");  
           xmlRoot.AppendChild(xmlModel);  
           ModelManager.Instance.SaveSnap(xmlDoc, xmlModel);  
           var xmlRole = xmlDoc.CreateElement("Roles");  
           xmlRoot.AppendChild(xmlRole);  
           RoleManager.Instance.SaveSnap(xmlDoc, xmlRole);  
           var xmlTool = xmlDoc.CreateElement("Tools");  
           xmlRoot.AppendChild(xmlTool);  
           ToolManager.Instance.SaveSnap(xmlDoc, xmlTool);  
           xmlDoc.Save(filename);  
           Debug.Log("XML 存档成功~!!!!!");  
       }  
       catch  
       {  
           throw new ArgumentOutOfRangeException();  
           Debug.Log("Save Error");  
       }  
       xmlDoc = null;  
   }  
   public void LoadSnap(string filename)  
   {  
       if (File.Exists(filename))  
       {  
           var xmlDoc = new XmlDocument();  
           try  
           {  
               xmlDoc.Load(filename);  
               var xmlRoot = xmlDoc.DocumentElement;  
               var xmlModel = xmlRoot.SelectSingleNode("Models") as XmlElement;  
               if (xmlModel != null)  
                   ModelManager.Instance.LoadSnap(xmlModel);  
               var xmlRole = xmlRoot.SelectSingleNode("Roles") as XmlElement;  
               if (xmlRole != null)  
                   RoleManager.Instance.LoadSnap(xmlRole);  
               Debug.Log("222");  
               var xmlTool = xmlRoot.SelectSingleNode("Tools") as XmlElement;  
               if (xmlTool != null)  
                   ToolManager.Instance.LoadSnap(xmlTool);  
               if (Warmtips.Instance.OnHideMessage != null)  
               {  
                   Warmtips.Instance.OnHideMessage();  
               }  
               OperationMessage.Instance.AddTipMessage("读档成功");  
               Debug.Log("XML 读档~!!!!!");  
           }  
           catch  
           {  
               throw new ArgumentOutOfRangeException();  
               Debug.LogError("读档有问题!!!!");  
           }  
           xmlDoc = null;  
       }  
   }  

RoleManager
#region 快门:使用xmlNode存取数据  
  public void SaveSnap(XmlDocument xmlDoc, XmlElement xmlNode)  
  {  
      foreach (var role in Roles)  
      {  
          var xmlRoleInfo = xmlDoc.CreateElement("RoleInfo");  
          xmlRoleInfo.SetAttribute("ID", role.OwnId.ToString());  
          xmlRoleInfo.SetAttribute("HP", role.HP.ToString());  
          xmlRoleInfo.SetAttribute("Active", role.gameObject.activeSelf.ToString());  
          xmlRoleInfo.SetAttribute("IsHurt", role.IsHurt.ToString());  
          xmlRoleInfo.SetAttribute("Position", TxtUtility.Vtr3ToStr(role.gameObject.transform.position));  
          xmlRoleInfo.SetAttribute("Rotation", TxtUtility.Vtr3ToStr(role.gameObject.transform.eulerAngles));  
          xmlRoleInfo.SetAttribute("RoleHXJ", role.transform.Find(AppDefine.AirResName).gameObject.activeSelf.ToString());  
          if (role.ToolList.Count != 0)  
          {  
              string toolName = null;  
              for (int j = 0; j < role.ToolList.Count; j++)  
              {  
                  toolName += "," + role.ToolList[j].MainObject.name;  
              }  
              xmlRoleInfo.SetAttribute("ToolList", toolName.TrimStart(','));  
          }  
          else  
          {  
              xmlRoleInfo.SetAttribute("ToolList", "");  
          }  
          xmlNode.AppendChild(xmlRoleInfo);  
      }  
  }  
  public void LoadSnap(XmlElement xmlNode)  
  {  
      XmlNodeList nodeList = xmlNode.ChildNodes;  
      foreach (XmlElement itemElement in nodeList)  
      {  
          var role = GetRoleById(itemElement.GetAttribute("ID").ToInt());  
          Debug.Log(role.OwnId);  
          if (role != null)  
          {  
              role.gameObject.SetActive(Convert.ToBoolean(itemElement.GetAttribute("Active")));  
              role.HP = itemElement.GetAttribute("HP").ToFloat();  
              switch (AppSetting.Platform)  
              {  
                  case EPlatform.PC:  
                      role.gameObject.transform.position = TxtUtility.StrToVtr3(itemElement.GetAttribute("Position"));  
                      role.gameObject.transform.eulerAngles = TxtUtility.StrToVtr3(itemElement.GetAttribute("Rotation"));  
                      break;  
                  case EPlatform.HTC:  
                      if (RoleManager.instance.CurrentRoleData.OwnId == role.OwnId)  
                      {  
                          //Player.instance.gameObject.transform.position = TxtUtility.StrToVtr3(itemElement.GetAttribute("Position"));  
                          TelePortManager.Instance.SampleTeleport(  
                              TxtUtility.StrToVtr3(itemElement.GetAttribute("Position")), true);  
                      }  
                      else  
                      {  
                          role.gameObject.transform.position = TxtUtility.StrToVtr3(itemElement.GetAttribute("Position"));  
                          role.gameObject.transform.eulerAngles = TxtUtility.StrToVtr3(itemElement.GetAttribute("Rotation"));  
                      }  
                      break;  
                  case EPlatform.OCULUS:  
                      //Debug.LogError(RoleManager.instance.CurrentRoleData.OwnId + "CurrentRole");  
                      //Debug.LogError(role.OwnId + "role");  
                      if (RoleManager.instance.CurrentRoleData.OwnId == role.OwnId)  
                      {  
                          Debug.LogError(TxtUtility.StrToVtr3(itemElement.GetAttribute("Position")));  
                          RayManager.Get().SetPos(TxtUtility.StrToVtr3(itemElement.GetAttribute("Position")));  
                      }  
                      else  
                      {  
                          role.gameObject.transform.position = TxtUtility.StrToVtr3(itemElement.GetAttribute("Position"));  
                          role.gameObject.transform.eulerAngles = TxtUtility.StrToVtr3(itemElement.GetAttribute("Rotation"));  
                      }  
                      break;  
              }  
              role.transform.Find(AppDefine.AirResName).gameObject.SetActive(Convert.ToBoolean(itemElement.GetAttribute("RoleHXJ")));  
              if (Convert.ToBoolean(itemElement.GetAttribute("IsHurt")))  
              {  
                  role.Animator.SetBool("hurt", true);  
              }  
              else  
              {  
                  role.ClearSitDown();  
                  role.Animator.SetBool("hurt", false);  
                  //role.animator.Play("Idle", -1, 0);  
              }  
              //如果不等于"" 说明人物有拿起东西  
              if (itemElement.GetAttribute("ToolList") != "")  
              {  
                  role.ToolList.Clear();  
                  ToolBase tool = null;  
                  string[] toolName = itemElement.GetAttribute("ToolList").Split(',');  
                  for (int j = 0; j < toolName.Length; j++)  
                  {  
                      tool = ToolManager.Instance.GetToolBase(toolName[j]);  
                      role.ToolList.Add(tool);  
                  }  
              }  
              else  
              {  
                  //如果没有东西则清空  
                  role.ToolList.Clear();  
              }  
          }  
      }  
  }  

ModelManager
#region 快门:使用xmlNode存取数据  
 public void SaveSnap(XmlDocument xmlDoc, XmlElement xmlNode)  
 {  
     //消防车  
     for (int i = 0; i < AccidentPosList.Count; i++)  
     {  
         for (int j = 0; j < AccidentPosList[i].XFCList.Count; j++)  
         {  
             if (AccidentPosList[i].XFCList[j].activeSelf)  
             {  
                 var _xmlModelFire = xmlDoc.CreateElement("ModelFire");  
                 _xmlModelFire.SetAttribute("Name", AccidentPosList[i].XFCList[j].name);  
                 _xmlModelFire.SetAttribute("Active", AccidentPosList[i].XFCList[j].activeSelf.ToString());  
                 //是否有人引导  
                 _xmlModelFire.SetAttribute("IsCall", AccidentPosList[i].XFCList[j].GetComponent<Fireengine>().Called.ToString());  
                 xmlNode.AppendChild(_xmlModelFire);  
             }  
         }  
     }  
     var ambulance = Ambulance.GetComponent<Ambulance>();  
     var _xmlModelInfoAmb = xmlDoc.CreateElement("ModelAmbulance");  
     //救护车 如果打电话应该出现 有人引导开始移动  
     if (Ambulance.gameObject.activeSelf)  
     {  
         _xmlModelInfoAmb.SetAttribute("Rotation", TxtUtility.Vtr3ToStr(Ambulance.transform.eulerAngles));  
         _xmlModelInfoAmb.SetAttribute("IsCall", ambulance.Called.ToString());  
         _xmlModelInfoAmb.SetAttribute("Guided", ambulance.Guided.ToString());  
         _xmlModelInfoAmb.SetAttribute("Active", Ambulance.gameObject.activeSelf.ToString());  
         xmlNode.AppendChild(_xmlModelInfoAmb);  
     }  
     else  
     {  
         _xmlModelInfoAmb.SetAttribute("Active", Ambulance.gameObject.activeSelf.ToString());  
         xmlNode.AppendChild(_xmlModelInfoAmb);  
     }  
     Transform fireCGroup;  
     if (MainEnv.transform.Find("FireControllerGroup"))  
         fireCGroup = MainEnv.transform.Find("FireControllerGroup");  
     else  
         fireCGroup = MainEnv.transform.Find("FireControlGP");  
     //消防炮 isActive 消防炮喷水  
     if (fireCGroup != null && fireCGroup.childCount != 0)  
     {  
         for (int i = 0; i < fireCGroup.childCount; i++)  
         {  
             var _xmlModelFireControl = xmlDoc.CreateElement("xmlModelFireControl");  
             _xmlModelFireControl.SetAttribute("Name", fireCGroup.GetChild(i).gameObject.name);  
             _xmlModelFireControl.SetAttribute("Rotation", TxtUtility.Vtr3ToStr(fireCGroup.GetChild(i).GetChild(2).eulerAngles));  
             if (fireCGroup.GetChild(i).GetComponent<Firemonitor>().particleWater == null)  
                 _xmlModelFireControl.SetAttribute("IsActive", false.ToString());  
             else  
                 _xmlModelFireControl.SetAttribute("IsActive", fireCGroup.GetChild(i).GetComponent<Firemonitor>().particleWater.activeSelf.ToString());  
             xmlNode.AppendChild(_xmlModelFireControl);  
         }  
     }  
 }  
 public void LoadSnap(XmlElement xmlNode)  
 {  
     XmlNodeList nodeList = xmlNode.ChildNodes;  
     foreach (XmlElement itemElement in nodeList)  
     {  
         switch (itemElement.Name)  
         {  
             case "ModelFire":  
                 for (int i = 0; i < AccidentPosList.Count; i++)  
                 {  
                     for (int j = 0; j < AccidentPosList[i].XFCList.Count; j++)  
                     {  
                         if (itemElement.GetAttribute("Name").Equals(AccidentPosList[i].XFCList[j].name))  
                         {  
                             var fireengine = AccidentPosList[i].XFCList[j].GetComponent<Fireengine>();  
                             //AccidentPosList[i].XFCList[j].GetComponent<Fireengine>().FireengineWater.SetActive(false);  
                             //如果消防车激活 并且引导 就到指定位置喷水 如果没有 则在原地 如果没有显示 则隐藏  
                             if (Convert.ToBoolean(itemElement.GetAttribute("Active")))  
                             {  
                                 if (Convert.ToBoolean(itemElement.GetAttribute("IsCall")))  
                                 {  
                                     AccidentPosList[i].XFCList[j].transform.position = fireengine.EndPosition + new Vector3(0f, -1.3f, 0f);  
                                     AccidentPosList[i].XFCList[j].transform.rotation = Quaternion.LookRotation(fireengine.EndDirection, Vector3.up);  
                                     fireengine.OpenFireengineWater(true);  
                                 }  
                                 else  
                                 {  
                                     AccidentPosList[i].XFCList[j].transform.rotation = Quaternion.LookRotation(Vector3.Normalize(NodePathList[3].point.transform.position - NodePathList[2].point.transform.position), Vector3.up);  
                                     AccidentPosList[i].XFCList[j].transform.position = NodePathList[3].point.transform.position;  
                                     fireengine.OpenFireengineWater(false);  
                                     fireengine.Called = false;  
                                     fireengine.IsRealy = false;  
                                     AccidentPosList[i].XFCList[j].SetActive(true);  
                                 }  
                             }  
                             else  
                             {  
                                 if (AccidentPosList[i].XFCList[j].activeSelf)  
                                 {  
                                     AccidentPosList[i].XFCList[j].transform.rotation = Quaternion.LookRotation(Vector3.Normalize(NodePathList[3].point.transform.position - NodePathList[2].point.transform.position), Vector3.up);  
                                     AccidentPosList[i].XFCList[j].transform.position = NodePathList[3].point.transform.position;  
                                     fireengine.OpenFireengineWater(false);  
                                     fireengine.Called = false;  
                                     fireengine.IsRealy = false;  
                                     AccidentPosList[i].XFCList[j].SetActive(false);  
                                 }  
                             }  
                         }  
                     }  
                 }  
                 break;  
             case "ModelAmbulance":  
                 var ambulance = Ambulance.GetComponent<Ambulance>();  
                 if (Convert.ToBoolean(itemElement.GetAttribute("Active")))  
                 {  
                     if (Convert.ToBoolean(itemElement.GetAttribute("IsCall")))  
                     {  
                         if (Convert.ToBoolean(itemElement.GetAttribute("Guided")))  
                         {  
                             ambulance._initNavPathed = false;  
                             ambulance._isGotoGoal = false;  
                             Ambulance.transform.position = ambulance.StartPosition;  
                             Ambulance.transform.rotation = Quaternion.identity;  
                             ambulance.GoToGoal(new ParamMessage());  
                         }  
                         else  
                         {  
                             Ambulance.gameObject.SetActive(true);  
                             Ambulance.transform.position = ambulance.StartPosition;  
                             Ambulance.transform.rotation = Quaternion.identity;  
                             ambulance.Guided = false;  
                             ambulance._initNavPathed = false;  
                             ambulance._isGotoGoal = false;  
                         }  
                     }  
                 }  
                 else  
                 {  
                     if (Ambulance.gameObject.activeSelf)  
                     {  
                         Ambulance.transform.position = ambulance.StartPosition;  
                         Ambulance.transform.rotation = Quaternion.identity;  
                         ambulance.Called = false;  
                         ambulance.Guided = false;  
                         ambulance._initNavPathed = false;  
                         ambulance._isGotoGoal = false;  
                         Ambulance.gameObject.SetActive(false);  
                     }  
                 }  
                 break;  
             case "xmlModelFireControl":  
                 Transform fireCGroup;  
                 if (MainEnv.transform.Find("FireControllerGroup"))  
                     fireCGroup = MainEnv.transform.Find("FireControllerGroup");  
                 else  
                     fireCGroup = MainEnv.transform.Find("FireControlGP");  
                 for (int i = 0; i < fireCGroup.childCount; i++)  
                 {  
                     if (itemElement.GetAttribute("Name").Equals(fireCGroup.GetChild(i).name))  
                     {  
                         if (Convert.ToBoolean(itemElement.GetAttribute("IsActive")))  
                         {  
                             fireCGroup.GetChild(i).GetChild(2).eulerAngles = TxtUtility.StrToVtr3(itemElement.GetAttribute("Rotation"));  
                             fireCGroup.GetChild(i).GetComponent<Firemonitor>().particleWater.SetActive(true);  
                         }  
                         else  
                         {  
                             fireCGroup.GetChild(i).GetChild(2).eulerAngles = TxtUtility.StrToVtr3(FireControllerDict[fireCGroup.GetChild(i).name]);  
                             if (fireCGroup.GetChild(i).GetComponent<Firemonitor>().particleWater != null)  
                                 fireCGroup.GetChild(i).GetComponent<Firemonitor>().particleWater.SetActive(false);  
                         }  
                     }  
                 }  
                 break;  
         }  
     }  
 }  

ToolManager
#region 快门:使用xmlNode存取数据  
  public void SaveSnap(XmlDocument xmlDoc, XmlElement xmlNode)  
  {  
      //一种未点击警戒绳 一种是点击警戒绳  
      if (ModelManager.Instance.jjsRoot.transform.childCount != 0)  
      {  
          //如果有警戒绳  
          for (int i = 0; i < ModelManager.Instance.jjsRoot.transform.childCount; i++)  
          {  
              jjrParent.Add(ModelManager.Instance.jjsRoot.transform.GetChild(i).gameObject);  
              for (int j = 0; j < ModelManager.Instance.jjsRoot.transform.GetChild(i).childCount; j++)  
              {  
                  var _xmlToolJJS = xmlDoc.CreateElement("ToolsJJS");  
                  _xmlToolJJS.SetAttribute("ID", i + "." + j);  
                  _xmlToolJJS.SetAttribute("Position", TxtUtility.Vtr3ToStr(ModelManager.Instance.jjsRoot.transform.GetChild(i).GetChild(j).position));  
                  _xmlToolJJS.SetAttribute("Rotation", TxtUtility.Vtr3ToStr(ModelManager.Instance.jjsRoot.transform.GetChild(i).GetChild(j).eulerAngles));  
                  _xmlToolJJS.SetAttribute("Scale", TxtUtility.Vtr3ToStr(ModelManager.Instance.jjsRoot.transform.GetChild(i).GetChild(j).localScale));  
                  _xmlToolJJS.SetAttribute("Count", i.ToString() + "." + ModelManager.Instance.jjsRoot.transform.GetChild(i).childCount.ToString());  
                  xmlNode.AppendChild(_xmlToolJJS);  
              }  
          }  
      }  
      else  
      {  
          var _xmlToolJJS = xmlDoc.CreateElement("ToolsJJS");  
          _xmlToolJJS.SetAttribute("Count", 0.ToString());  
          xmlNode.AppendChild(_xmlToolJJS);  
      }  
      for (int i = 0; i < toolAllList.Count; i++)  
      {  
          var _xmlToolInfo = xmlDoc.CreateElement("ToolsInfo");  
          //当前人物ID  
          _xmlToolInfo.SetAttribute("RoleID", RoleManager.Instance.CurrentRoleData.OwnId.ToString());  
          //_xmlToolInfo.SetAttribute("RoleHXJ", RoleManager.Instance.CurrentRoleData.transform.Find(AppDefine.AirResName).gameObject.activeSelf.ToString());  
          _xmlToolInfo.SetAttribute("Active", toolAllList[i].activeSelf.ToString());  
          _xmlToolInfo.SetAttribute("Name", toolAllList[i].name);  
          _xmlToolInfo.SetAttribute("Position", TxtUtility.Vtr3ToStr(toolAllList[i].transform.position));  
          _xmlToolInfo.SetAttribute("Rotation", TxtUtility.Vtr3ToStr(toolAllList[i].transform.eulerAngles));  
          if (toolAllList[i].gameObject.tag.CompareTo(GlobalTags.Extinguisher.ToString()) == 0)  
          {  
              _xmlToolInfo.SetAttribute("State", RoleManager.Instance.CurrentRoleData.nWithExtinguisherState.ToString());  
          }  
          //如果没有父物体 则回到toolRoot  
          if (toolAllList[i].transform.parent == null)  
          {  
              _xmlToolInfo.SetAttribute("Parent", "");  
          }  
          else  
          {  
              _xmlToolInfo.SetAttribute("Parent", toolAllList[i].transform.parent.name.ToString());  
          }  
          xmlNode.AppendChild(_xmlToolInfo);  
      }  
      //ToolList 状态  
  }  
  public void LoadSnap(XmlElement xmlNode)  
  {  
      XmlNodeList nodeList = xmlNode.ChildNodes;  
      foreach (XmlElement itemElement in nodeList)  
      {  
          if (itemElement.Name == "ToolsInfo")  
          {  
              for (int i = 0; i < toolAllList.Count; i++)  
              {  
                  if (itemElement.GetAttribute("Name").Equals(toolAllList[i].gameObject.name))  
                  {  
                      //RoleManager.Instance.RoleDicts[Convert.ToInt32(itemElement.GetAttribute("RoleID"))].transform.Find(AppDefine.AirResName).gameObject.SetActive(Convert.ToBoolean(itemElement.GetAttribute("RoleHXJ")));  
                      toolAllList[i].gameObject.SetActive(Convert.ToBoolean(itemElement.GetAttribute("Active")));  
                      var role = RoleManager.Instance.GetRoleById(itemElement.GetAttribute("RoleID").ToInt());  
                      if (itemElement.GetAttribute("Parent") == "Bip01 R Hand")  
                      {  
                          toolAllList[i].gameObject.transform.SetParent(role.RightHand.transform);  
                      }  
                      else  
                      {  
                          toolAllList[i].gameObject.transform.SetParent(ToolRoot.transform);  
                      }  
                      toolAllList[i].gameObject.transform.position = TxtUtility.StrToVtr3(itemElement.GetAttribute("Position"));  
                      toolAllList[i].gameObject.transform.eulerAngles = TxtUtility.StrToVtr3(itemElement.GetAttribute("Rotation"));  
                      //如果是灭火器  
                      if (toolAllList[i].gameObject.tag.CompareTo(GlobalTags.Extinguisher.ToString()) == 0)  
                      {  
                          //拿着灭火器的状态,0为没拿,1为拿着,2为喷着  
                          switch (Convert.ToInt32(itemElement.GetAttribute("State")))  
                          {  
                              case 0:  
                                  PutDownExtinguisherState();  
                                  break;  
                              case 1:  
                                  PutDownExtinguisherState();  
                                  role.GetExtinguisher(toolAllList[i]);  
                                  break;  
                              case 2:  
                                  role.GetExtinguisher(toolAllList[i]);  
                                  role.RpcUseExtinguisher(Vector3.zero);  
                                  break;  
                          }  
                      }  
                  }  
              }  
          }  
          if (itemElement.Name == "ToolsJJS")  
          {  
              //如果有警戒绳  如果没有则删除多余的警戒绳  
              if (ModelManager.Instance.jjsRoot.transform.childCount != 0)  
              {  
                  for (int i = 0; i < ModelManager.Instance.jjsRoot.transform.childCount; i++)  
                  {  
                      //如果存档没有JJS 则清空JJS  
                      if (Convert.ToInt32(itemElement.GetAttribute("Count")) == 0)  
                      {  
                          RoleManager.Instance.CurrentRoleData.DestoryTools(ModelManager.Instance.jjsRoot.transform.GetChild(i).gameObject);  
                      }  
                      else  
                      {  
                          string[] strJJSCount = itemElement.GetAttribute("Count").Split('.');  
                          if (!strJJSCount[1].Equals(ModelManager.Instance.jjsRoot.transform.GetChild(i).childCount))  
                          {  
                              //删除多余的JJS  
                              for (int j = Convert.ToInt32(strJJSCount[1]); j < ModelManager.Instance.jjsRoot.transform.GetChild(i).childCount; j++)  
                              {  
                                  RoleManager.Instance.CurrentRoleData.DestoryTools(ModelManager.Instance.jjsRoot.transform.GetChild(i).GetChild(j).gameObject);  
                              }  
                          }  
                      }  
                  }  
              }  
          }  
      }  
  }  
以上就是xml存档的全部内容了,如果大家有更好的方案和代码也可以分享出来。

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台