unity3d 本地配置文件_unity3d本地配置表更新上传到服务器 - CSDN
  • 本文大部分转载,作者做了关于配置文件生成工作,但是很遗憾,关于position和rotation信息目前尚未自动生成,运行本例的朋友,需要自己手动添加位置和角度信息,否则程序会报错。 标准的json数据: { ...
    本文大部分转载,作者做了关于配置文件生成工作,但是很遗憾,关于position和rotation信息目前尚未自动生成,运行本例的朋友,需要自己手动添加位置和角度信息,否则程序会报错。
    标准的json数据:
    1. {
    2.     "AssetList" : [{
    3.         "Name" : "Chair 1",
    4.         "Source" : "Prefabs/Chair001.unity3d",
    5.         "Position" : [2,0,-5],
    6.         "Rotation" : [0.0,60.0,0.0]
    7.     },
    8.     {
    9.         "Name" : "Chair 2",
    10.         "Source" : "Prefabs/Chair001.unity3d",
    11.         "Position" : [1,0,-5],
    12.         "Rotation" : [0.0,0.0,0.0]
    13.     },
    14.     {
    15.         "Name" : "Vanity",
    16.         "Source" : "Prefabs/vanity001.unity3d",
    17.         "Position" : [0,0,-4],
    18.         "Rotation" : [0.0,0.0,0.0]
    19.     }
    20.     }]
    21. }

          用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载。比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕。应该优先加载用户附近的场景资源,在游戏的过程中,不影响操作的情况下,后台加载剩余的资源,直到所有加载完毕。
           在讲述代码之前,先想象这样一个网络游戏的开发流程。首先美工制作场景资源的3D建模,游戏设计人员把3D建模导进Unity3D,托托拽拽编辑场景,完成后把每个gameobject导出成XXX.unity3d格式的资源文件(参看BuildPipeline),并且把整个场景的信息生成一个配置文件,xml或者Json格式(本文使用Json)。最后还要把资源文件和场景配置文件上传到服务器,最好使用CMS管理。客户端运行游戏时,先读取服务器的场景配置文件,再根据玩家的位置从服务器下载相应的资源文件并加载,然后开始游戏,注意这里并不是下载所有的场景资源。在游戏的过程中,后台继续加载资源直到所有加载完毕。
    json.txt:(注:当生成的json无法读取时,记得改一下编码格式 改成 ANSI)
    {"AssetList":[{"Name":"Sphere","Source":"Prefabs/Sphere.unity3d"},{"Name":"cube","Source":"Prefabs/cube.unity3d"},{"Name":"Sphere","Source":"Prefabs/Sphere.unity3d"},{"Name":"cube","Source":"Prefabs/cube.unity3d"}]}

    主程序:

    using UnityEngine;  using System.Collections;    public class MainMonoBehavior : MonoBehaviour {        public delegate void MainEventHandler(GameObject dispatcher);      public event MainEventHandler StartEvent;      public event MainEventHandler UpdateEvent;      public void Start()      {          ResourceManager.getInstance().LoadSence("Scenes/json.txt");//json配置文件          if(StartEvent != null)          {              StartEvent(this.gameObject);          }      }      public void Update()      {          if (UpdateEvent != null)          {              UpdateEvent(this.gameObject);          }      }  }

    
    

        这里面用到了C#的事件机制,大家可以看看我以前翻译过的国外一个牛人的文章。C# 事件和Unity3D在 start方法里调用ResourceManager,先加载配置文件。每一次调用update方法,MainMonoBehavior会把update 事件分发给ResourceManager,因为ResourceManager注册了MainMonoBehavior的update事件。

    ResourceManager.cs  using UnityEngine;  using System.Collections;  using System.Collections.Generic;  using LitJson;  using System.Net;  public class ResourceManager  {    // Use this for initialization          private MainMonoBehavior mainMonoBehavior;          private   string mResourcePath;          private Scene mScene;          private Asset mSceneAsset;          private static ResourceManager resourceManager=new ResourceManager();//如果没有new 会出现没有实例化的错误          private Dictionary<string ,WWW > wwwCacheMap=new Dictionary<string,WWW>();//这个新添加的原文代码中没有定义它 应该是个字典         public static  ResourceManager getInstance( )          {                  return resourceManager;//静态函数中不能使用非静态成员          }          public  ResourceManager()          {                  mainMonoBehavior = GameObject.Find("Main Camera").GetComponent<MainMonoBehavior>();                  mResourcePath ="file://"+Application.dataPath+"/..";          }                  public void LoadSence(string fileName)          {                  //Debug.Log(fileName);                  mSceneAsset = new Asset();                  mSceneAsset.Type = Asset.TYPE_JSON;//后面类型判断有用                  mSceneAsset.Source = fileName;                  mainMonoBehavior.UpdateEvent += OnUpdate;//添加监听函数          }                public void OnUpdate(GameObject dispatcher)//该函数是监听函数,每帧都会被调用(它的添加是在MainMonoBehavior的start函数中通过调用本地LoadSence函数)          {                  if (mSceneAsset != null)//表示已经通过了new操作分配类内存空间但是资源还没有加载完                  {                          LoadAsset(mSceneAsset);//这个函数里面会通过判断,使www的new操作只执行一次                          if (!mSceneAsset.isLoadFinished)//C#中 bool类型默认是false                          {                                 return;                          }                          mScene = null;                          mSceneAsset = null;                  }                  mainMonoBehavior.UpdateEvent -= OnUpdate;//当所有资源被加载后,删除监听函数。          }          //最核心的函数       private Asset LoadAsset(Asset asset)          {                  string fullFileName =mResourcePath+"/"+ asset.Source;// mResourcePath + "/" + asset.Source;                  Debug.Log("fullFileName=" + fullFileName);                  //if www resource is new, set into www cache                  if (!wwwCacheMap.ContainsKey(fullFileName))                  {//自定义字典 查看开头的定义                          if (asset.www == null)                          {//表示www还没有new操作                                  asset.www = new WWW(fullFileName);                                  return null;                          }                          if (!asset.www.isDone)                          {                                  return null;                          }                          wwwCacheMap.Add(fullFileName, asset.www); //该字典是作为缓存的作用,如果之前已经加载过同样的Unity3D格式文件,那么不需要在加载,直接拿来用就行了。                                    if (asset.Type == Asset.TYPE_JSON)                  { //Json 表示当txt文件被首次加载时的处理                          if (mScene == null)                          {                                     string jsonTxt = mSceneAsset.www.text;                              Debug.Log("jsonTxt=" + jsonTxt);                              mScene = JsonMapper.ToObject<Scene>(jsonTxt);//mScene是个Asset对象列表,也就是Json文件需要一个AssetList列表对象,注意名字的统一,列表中Asset对象中的成员名称要和txt                //文件中的相关名称统一 不然JsonMapper无法找到                           }                          //load scene                          foreach (Asset sceneAsset in mScene.AssetList)                          {                                  if (sceneAsset.isLoadFinished)                                  {                                          continue;                                  }                                  else                                  {                                          LoadAsset(sceneAsset);//这里的处理就是 下面 Asset.TYPE_GAMEOBJECT的处理方式,注意是递归函数的调用                                          if (!sceneAsset.isLoadFinished)                                          {                                              return null;                                           }                                   }                          }                  }                  else if (asset.Type == Asset.TYPE_GAMEOBJECT)//处理文件中具体信息,嵌套关系或者直接是一个GameObject对象,与上面的代码有联系,Asset创建时候的构造函数中设置成                  //TYPE_GAMEOBJECT类型                  { //Gameobject                          if (asset.gameObject == null)//如果不为null 表示已经通过wwwCacheMap加载了资源包中所包含的资源(fullFileName仅仅是一个文件,资源包中资源是分散的GameObject对象),不需要在重新加载                          {                                  wwwCacheMap[fullFileName].assetBundle.LoadAll();//已经通过new WWW操作完成了加载,该函数用来加载包含着资源包中的资源                                  GameObject go = (GameObject)GameObject.Instantiate(wwwCacheMap[fullFileName].assetBundle.mainAsset);                                  UpdateGameObject(go, asset);                                  asset.gameObject = go;                          }                          if (asset.AssetList != null)//有嵌套关系                          {                                  foreach (Asset assetChild in asset.AssetList)                                  {                                          if (assetChild.isLoadFinished)                                          {                                                  continue;                                          }                                          else                                          {                                                  Asset assetRet = LoadAsset(assetChild);                                                  if (assetRet != null)//这个if else 语句是为了防止你的配置文件中的GameObject对象路径不正确,导致访问空指针。                                                  {                                                          assetRet.gameObject.transform.parent = asset.gameObject.transform;                                                  }                                                  else                                                  {                                                          return null;                                                  }                                          }                                  }                          }                  }                  asset.isLoadFinished = true;                  return asset;          }          private void UpdateGameObject(GameObject go, Asset asset)          {                  //name                  go.name = asset.Name;                  //position                  Vector3 vector3 = new Vector3((float)asset.Position[0], (float)asset.Position[1], (float)asset.Position[2]);                  go.transform.position = vector3;                  //rotation                 vector3 = new Vector3((float)asset.Rotation[0], (float)asset.Rotation[1], (float)asset.Rotation[2]);                  go.transform.eulerAngles = vector3;          }  }

    View Code  Asset.cs类:  using UnityEngine;  using System.Collections.Generic;  public class Asset  {          public const byte TYPE_JSON = 1;          public const byte TYPE_GAMEOBJECT = 2;          public Asset()          {              //default type is gameobject for json load              Type = TYPE_GAMEOBJECT;          }          public byte Type          {              get;              set;          }          public string Name          {              get;              set;          }          public string Source          {              get;              set;          }          public double[] Bounds          {              get;              set;          }                  public double[] Position          {              get;              set;          }          public double[] Rotation          {              get;              set;          }          public List<Asset> AssetList          {              get;              set;          }          public bool isLoadFinished          {              get;              set;          }          public WWW www          {              get;              set;          }          public GameObject gameObject          {              get;              set;          }  }  Scene.cs类:  using System.Collections.Generic;    public class Scene  {          public List<Asset> AssetList          {              get;              set;          }  }

    生成.unity3d代码:

    View Code  using UnityEngine;  using UnityEditor;  using System.IO;  using System;  using System.Text;  using System.Collections.Generic;  using LitJson;  public class BuildAssetBundlesFromDirectory  {        static List<JsonResource> config=new List<JsonResource>();        static Dictionary<string, List<JsonResource>> assetList=new Dictionary<string, List<JsonResource>>();          [@MenuItem("Asset/Build AssetBundles From Directory of Files")]//这里不知道为什么用"@",添加菜单          static void ExportAssetBundles ()          {//该函数表示通过上面的点击响应的函数                     assetList.Clear();                     string path = AssetDatabase.GetAssetPath(Selection.activeObject);//Selection表示你鼠标选择激活的对象                    Debug.Log("Selected Folder: " + path);                                    if (path.Length != 0)                    {                             path = path.Replace("Assets/", "");//因为AssetDatabase.GetAssetPath得到的是型如Assets/文件夹名称,且看下面一句,所以才有这一句。                              Debug.Log("Selected Folder: " + path);                             string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);//因为Application.dataPath得到的是型如 "工程名称/Assets"                                                         string[] div_line = new string[] { "Assets/" };                             foreach(string fileName in fileEntries)                             {                                      j++;                                      Debug.Log("fileName="+fileName);                                      string[] sTemp = fileName.Split(div_line, StringSplitOptions.RemoveEmptyEntries);                                      string filePath = sTemp[1];                                       Debug.Log(filePath);                                      filePath = "Assets/" + filePath;                                      Debug.Log(filePath);                                      string localPath = filePath;                                      UnityEngine.Object t = AssetDatabase.LoadMainAssetAtPath(localPath);                                                                           //Debug.Log(t.name);                                      if (t != null)                                      {                                              Debug.Log(t.name);                                              JsonResource jr=new JsonResource();                                              jr.Name=t.name;                                              jr.Source=path+"/"+t.name+".unity3d";                                                Debug.Log( t.name);                                              config.Add(jr);//实例化json对象                                                string bundlePath = Application.dataPath+"/../"+path;                                                 if(!File.Exists(bundlePath))                                                  {                                                     Directory.CreateDirectory(bundlePath);//在Asset同级目录下相应文件夹                                                  }                                                bundlePath+="/"  + t.name + ".unity3d";                                               Debug.Log("Building bundle at: " + bundlePath);                                               BuildPipeline.BuildAssetBundle(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);//在对应的文件夹下生成.unity3d文件                                      }                             }                              assetList.Add("AssetList",config);                              for(int i=0;i<config.Count;i++)                              {                                      Debug.Log(config[i].Source);                              }                    }                  string data=JsonMapper.ToJson(assetList);//序列化数据                  Debug.Log(data);          string jsonInfoFold=Application.dataPath+"/../Scenes";          if(!Directory.Exists(jsonInfoFold))          {              Directory.CreateDirectory(jsonInfoFold);//创建Scenes文件夹          }                  string fileName1=jsonInfoFold+"/json.txt";                  if(File.Exists(fileName1))                  {                      Debug.Log(fileName1 +"already exists");                      return;                  }                  UnicodeEncoding uni=new UnicodeEncoding();                                     using FileStream  fs=File.Create(fileName1))//向创建的文件写入数据                  {                          fs.Write(uni.GetBytes(data),0,uni.GetByteCount(data));                          fs.Close();                  }        }  }

    展开全文
  • using UnityEngine;...using UnityEditor; using System.IO; using System; using System.Text; using System.Collections.Generic; using LitJson; public class BuildAssetBundlesFromDirectory { ...
    using UnityEngine;
    using UnityEditor;
    using System.IO;
    using System;
    using System.Text;
    using System.Collections.Generic;
    using LitJson;
    public class BuildAssetBundlesFromDirectory
    {
          static List<JsonResource> config=new List<JsonResource>();
          static Dictionary<string, List<JsonResource>> assetList=new Dictionary<string, List<JsonResource>>();
            [@MenuItem("Asset/Build AssetBundles From Directory of Files")]//这里不知道为什么用"@",添加菜单
            static void ExportAssetBundles ()
            {//该函数表示通过上面的点击响应的函数
                       assetList.Clear();
                       string path = AssetDatabase.GetAssetPath(Selection.activeObject);//Selection表示你鼠标选择激活的对象
                      Debug.Log("Selected Folder: " + path);
           
           
                      if (path.Length != 0)
                      {
                               path = path.Replace("Assets/", "");//因为AssetDatabase.GetAssetPath得到的是型如Assets/文件夹名称,且看下面一句,所以才有这一句。
                                Debug.Log("Selected Folder: " + path);
                               string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);//因为Application.dataPath得到的是型如 "工程名称/Assets"
                               
                               string[] div_line = new string[] { "Assets/" };
                               foreach(string fileName in fileEntries)
                               {
                                        j++;
                                        Debug.Log("fileName="+fileName);
                                        string[] sTemp = fileName.Split(div_line, StringSplitOptions.RemoveEmptyEntries);
                                        string filePath = sTemp[1];
                                         Debug.Log(filePath);
                                        filePath = "Assets/" + filePath;
                                        Debug.Log(filePath);
                                        string localPath = filePath;
                                        UnityEngine.Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
                                       
                                         //Debug.Log(t.name);
                                        if (t != null)
                                        {
                                                Debug.Log(t.name);
                                                JsonResource jr=new JsonResource();
                                                jr.Name=t.name;
                                                jr.Source=path+"/"+t.name+".unity3d";
                                                  Debug.Log( t.name);
                                                config.Add(jr);//实例化json对象
                                                  string bundlePath = Application.dataPath+"/../"+path;
                                                   if(!File.Exists(bundlePath))
                                                    {
                                                       Directory.CreateDirectory(bundlePath);//在Asset同级目录下相应文件夹
                                                    }
                                                  bundlePath+="/"  + t.name + ".unity3d";
                                                 Debug.Log("Building bundle at: " + bundlePath);
                                                 BuildPipeline.BuildAssetBundle(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);//在对应的文件夹下生成.unity3d文件
                                        } 
                               }
                                assetList.Add("AssetList",config);
                                for(int i=0;i<config.Count;i++)
                                {
                                        Debug.Log(config[i].Source);
                                }
                      }
                    string data=JsonMapper.ToJson(assetList);//序列化数据
                    Debug.Log(data);
            string jsonInfoFold=Application.dataPath+"/../Scenes";
            if(!Directory.Exists(jsonInfoFold))
            {
                Directory.CreateDirectory(jsonInfoFold);//创建Scenes文件夹
            }
                    string fileName1=jsonInfoFold+"/json.txt";
                    if(File.Exists(fileName1))
                    {
                        Debug.Log(fileName1 +"already exists");
                        return;
                    }
                    UnicodeEncoding uni=new UnicodeEncoding();
                      
                    using(  FileStream  fs=File.Create(fileName1))//向创建的文件写入数据
                    {
                            fs.Write(uni.GetBytes(data),0,uni.GetByteCount(data));
                            fs.Close();
                    }
          }
    }

     http://www.cnblogs.com/U-tansuo/archive/2012/07/11/2587173.html

    转载于:https://www.cnblogs.com/hisiqi/p/3202915.html

    展开全文
  • Unity3D游戏本地存储 Unity3D游戏本地存储玩家积分。Unity提供了一个类似配置文件的类,可以非常好的实现信息数据的存储,那就是PlayerPrefs。它可以存储:int、float和string类型。 // 存进去 PlayerPrefs....

    Unity3D游戏本地存储


    Unity3D游戏本地存储玩家积分。Unity提供了一个类似配置文件的类,可以非常好的实现信息数据的存储,那就是PlayerPrefs。它可以存储:int、float和string类型。

    // 存进去
    
    PlayerPrefs.SetInt("key1", 10);
    
    PlayerPrefs.SetString("key2", aaaaaa);
    
    PlayerPrefs.SetFloat("key3", 10.009);
    
    // 取出来
    
    int i = PlayerPrefs.GetInt("key1");


    unity3d保存文件到本地and加载本地文件
    001.using UnityEngine;
    002.using System.Collections;
    003.using System.IO;
    004.using System.Collections.Generic;
    005.using System;
    006.  
    007.public class Text : MonoBehaviour {
    008.    //文本中每行的内容
    009.    ArrayList infoall;
    010.    //皮肤资源,这里用于显示中文
    011.    public GUISkin skin;
    012.    void Start ()
    013.    {
    014.        print("当前文件路径:"+Application.persistentDataPath);
    015.        //删除文件
    016.        DeleteFile(Application.persistentDataPath,"FileName.txt");
    017.  
    018.        //创建文件,共写入3次数据
    019.        CreateFile(Application.persistentDataPath,"FileName.txt","dingxiaowei");
    020.        CreateFile(Application.persistentDataPath,"FileName.txt","丁小未");
    021.        //CreateFile(Application.persistentDataPath ,"Filename.assetbundle","丁小未");
    022.        //下载模型
    023.        StartCoroutine(loadasset("http://192.168.1.180/3DShowResource/Products/AssetBundles/HX_DY02.assetbundle"));
    024.        //得到文本中每一行的内容
    025.        infoall = LoadFile(Application.persistentDataPath,"FileName.txt");
    026. 
    027.         
    028.    }
    029.    //写入模型到本地
    030.    IEnumerator loadasset(string url)
    031.    {
    032.        WWW w = new WWW(url);
    033.        yield return w;
    034.        if (w.isDone)
    035.        {
    036.            byte[] model = w.bytes;
    037.            int length = model.Length;
    038.            //写入模型到本地
    039.            CreateModelFile(Application.persistentDataPath, "Model.assetbundle", model,length);
    040.        }
    041.    }
    042. 
    043.    void CreateModelFile(string path, string name, byte[] info, int length)
    044.    {
    045.        //文件流信息
    046.        //StreamWriter sw;
    047.        Stream sw;
    048.        FileInfo t = new FileInfo(path + "//" + name);
    049.        if (!t.Exists)
    050.        {
    051.            //如果此文件不存在则创建
    052.            sw = t.Create();
    053.        }
    054.        else
    055.        {
    056.            //如果此文件存在则打开
    057.            //sw = t.Append();
    058.            return;
    059.        }
    060.        //以行的形式写入信息
    061.        //sw.WriteLine(info);
    062.        sw.Write(info, 0, length);
    063.        //关闭流
    064.        sw.Close();
    065.        //销毁流
    066.        sw.Dispose();
    067.    }
    068.  
    069.   /**
    070.   * path:文件创建目录
    071.   * name:文件的名称
    072.   *  info:写入的内容
    073.   */
    074.   void CreateFile(string path,string name,string info)
    075.   {
    076.      //文件流信息
    077.      StreamWriter sw;
    078.      FileInfo t = new FileInfo(path+"//"+ name);
    079.      if(!t.Exists)
    080.      {
    081.        //如果此文件不存在则创建
    082.        sw = t.CreateText();
    083.      }
    084.      else
    085.      {
    086.        //如果此文件存在则打开
    087.        sw = t.AppendText();
    088.      }
    089.      //以行的形式写入信息
    090.      sw.WriteLine(info);
    091.      //关闭流
    092.      sw.Close();
    093.      //销毁流
    094.      sw.Dispose();
    095.   }
    096. 
    097.    
    098.  
    099.  /**
    100.   * 读取文本文件
    101.   * path:读取文件的路径
    102.   * name:读取文件的名称
    103.   */
    104.   ArrayList LoadFile(string path,string name)
    105.   {
    106.        //使用流的形式读取
    107.        StreamReader sr =null;
    108.        try{
    109.            sr = File.OpenText(path+"//"+ name);
    110.        }catch(Exception e)
    111.        {
    112.            //路径与名称未找到文件则直接返回空
    113.            return null;
    114.        }
    115.        string line;
    116.        ArrayList arrlist = new ArrayList();
    117.        while ((line = sr.ReadLine()) != null)
    118.        {
    119.            //一行一行的读取
    120.            //将每一行的内容存入数组链表容器中
    121.            arrlist.Add(line);
    122.        }
    123.        //关闭流
    124.        sr.Close();
    125.        //销毁流
    126.        sr.Dispose();
    127.        //将数组链表容器返回
    128.        return arrlist;
    129.   } 
    130. 
    131.    //读取模型文件
    132.   IEnumerator LoadModelFromLocal(string path, string name)
    133.   {
    134.       print("file:///" + path + "/" + name);
    135.       WWW w = new WWW("file:///"+path + "/" + name);
    136.       yield return w;
    137.       if (w.isDone)
    138.       {
    139.           Instantiate(w.assetBundle.mainAsset);
    140.       }
    141.   }
    142. 
    143.  
    144.  /**
    145.   * path:删除文件的路径
    146.   * name:删除文件的名称
    147.   */
    148.  
    149.   void DeleteFile(string path,string name)
    150.   {
    151.        File.Delete(path+"//"+ name);
    152.   }
    153.  
    154.   void OnGUI()
    155.   {
    156.        //用新的皮肤资源,显示中文
    157.        GUI.skin = skin;
    158.        //读取文件中的所有内容
    159.        foreach(string str in infoall)
    160.        {
    161.            //绘制在屏幕当中
    162.            GUILayout.Label(str);
    163.        }
    164.        if (GUILayout.Button("加载模型"))
    165.        {
    166.            StartCoroutine(LoadModelFromLocal(Application.persistentDataPath, "Model.assetbundle"));
    167.        }
    168.   }
    169.  
    170.}


    展开全文
  • 本文大部分转载,作者做了关于配置文件生成工作,但是很遗憾,关于position和rotation信息目前尚未自动生成,运行本例的朋友,需要自己手动添加位置和角度信息,否则程序会报错。标准的json数据: {  "...
    本文大部分转载,作者做了关于配置文件生成工作,但是很遗憾,关于position和rotation信息目前尚未自动生成,运行本例的朋友,需要自己手动添加位置和角度信息,否则程序会报错。
    标准的json数据:
    1. {
    2.     "AssetList" : [{
    3.         "Name" : "Chair 1",
    4.         "Source" : "Prefabs/Chair001.unity3d",
    5.         "Position" : [2,0,-5],
    6.         "Rotation" : [0.0,60.0,0.0]
    7.     },
    8.     {
    9.         "Name" : "Chair 2",
    10.         "Source" : "Prefabs/Chair001.unity3d",
    11.         "Position" : [1,0,-5],
    12.         "Rotation" : [0.0,0.0,0.0]
    13.     },
    14.     {
    15.         "Name" : "Vanity",
    16.         "Source" : "Prefabs/vanity001.unity3d",
    17.         "Position" : [0,0,-4],
    18.         "Rotation" : [0.0,0.0,0.0]
    19.     }
    20.     }]
    21. }

    用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载。比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕。应该优先加载用户附近的场景资源,在游戏的过程中,不影响操作的情况下,后台加载剩余的资源,直到所有加载完毕。

    在讲述代码之前,先想象这样一个网络游戏的开发流程。首先美工制作场景资源的3D建模,游戏设计人员把3D建模导进Unity3D,托托拽拽编辑场景,完成后把每个gameobject导出成XXX.unity3d格式的资源文件(参看BuildPipeline),并且把整个场景的信息生成一个配置文件,xml或者Json格式(本文使用Json)。最后还要把资源文件和场景配置文件上传到服务器,最好使用CMS管理。客户端运行游戏时,先读取服务器的场景配置文件,再根据玩家的位置从服务器下载相应的资源文件并加载,然后开始游戏,注意这里并不是下载所有的场景资源。在游戏的过程中,后台继续加载资源直到所有加载完毕。
    json.txt:(注:当生成的json无法读取时,记得改一下编码格式 改成 ANSI
    {"AssetList":[{"Name":"Sphere","Source":"Prefabs/Sphere.unity3d"},{"Name":"cube","Source":"Prefabs/cube.unity3d"},{"Name":"Sphere","Source":"Prefabs/Sphere.unity3d"},{"Name":"cube","Source":"Prefabs/cube.unity3d"}]}

    主程序:
    1 using UnityEngine;
     2 using System.Collections;
     3 
     4 public class MainMonoBehavior : MonoBehaviour {
     5 
     6     public delegate void MainEventHandler(GameObject dispatcher);
     7     public event MainEventHandler StartEvent;
     8     public event MainEventHandler UpdateEvent;
     9     public void Start()
    10     {
    11         ResourceManager.getInstance().LoadSence("Scenes/json.txt");//json配置文件
    12         if(StartEvent != null)
    13         {
    14             StartEvent(this.gameObject);
    15         }
    16     }
    17     public void Update()
    18     {
    19         if (UpdateEvent != null)
    20         {
    21             UpdateEvent(this.gameObject);
    22         }
    23     }
    24 }

     

    这里面用到了C#的事件机制,大家可以看看我以前翻译过的国外一个牛人的文章。C# 事件和Unity3D
    在 start方法里调用ResourceManager,先加载配置文件。每一次调用update方法,MainMonoBehavior会把update 事件分发给ResourceManager,因为ResourceManager注册了MainMonoBehavior的update事件。

    辅助类:
    ResourceManager.cs
      1 using UnityEngine;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using LitJson;
      5 using System.Net;
      6 public class ResourceManager
      7 {
      8 
      9 // Use this for initialization
     10         private MainMonoBehavior mainMonoBehavior;
     11         private   string mResourcePath;
     12         private Scene mScene;
     13         private Asset mSceneAsset;
     14         private static ResourceManager resourceManager=new ResourceManager();//如果没有new 会出现没有实例化的错误
     15         private Dictionary<string ,WWW > wwwCacheMap=new Dictionary<string,WWW>();//这个新添加的原文代码中没有定义它 应该是个字典
     16        public static  ResourceManager getInstance( )
     17         {
     18                 return resourceManager;//静态函数中不能使用非静态成员
     19         }
     20         public  ResourceManager()
     21         {
     22                 mainMonoBehavior = GameObject.Find("Main Camera").GetComponent<MainMonoBehavior>();
     23                 mResourcePath ="file://"+Application.dataPath+"/..";
     24         }
     25        
     26         public void LoadSence(string fileName)
     27         {
     28                 //Debug.Log(fileName);
     29                 mSceneAsset = new Asset();
     30                 mSceneAsset.Type = Asset.TYPE_JSON;//后面类型判断有用
     31                 mSceneAsset.Source = fileName;
     32                 mainMonoBehavior.UpdateEvent += OnUpdate;//添加监听函数
     33         }
     34 
     35 
     36 
     37         public void OnUpdate(GameObject dispatcher)//该函数是监听函数,每帧都会被调用(它的添加是在MainMonoBehavior的start函数中通过调用本地LoadSence函数)
     38         {
     39                 if (mSceneAsset != null)//表示已经通过了new操作分配类内存空间但是资源还没有加载完
     40                 {
     41                         LoadAsset(mSceneAsset);//这个函数里面会通过判断,使www的new操作只执行一次
     42                         if (!mSceneAsset.isLoadFinished)//C#中 bool类型默认是false
     43                         {
     44                                return;
     45                         }
     46                         mScene = null;
     47                         mSceneAsset = null;
     48                 }
     49                 mainMonoBehavior.UpdateEvent -= OnUpdate;//当所有资源被加载后,删除监听函数。
     50         }
     51         //最核心的函数
     52      private Asset LoadAsset(Asset asset)
     53         {
     54                 string fullFileName =mResourcePath+"/"+ asset.Source;// mResourcePath + "/" + asset.Source;
     55                 Debug.Log("fullFileName=" + fullFileName);
     56                 //if www resource is new, set into www cache
     57                 if (!wwwCacheMap.ContainsKey(fullFileName))
     58                 {//自定义字典 查看开头的定义
     59                         if (asset.www == null)
     60                         {//表示www还没有new操作
     61                                 asset.www = new WWW(fullFileName);
     62                                 return null;
     63                         }
     64                         if (!asset.www.isDone)
     65                         {
     66                                 return null;
     67                         }
     68                         wwwCacheMap.Add(fullFileName, asset.www); //该字典是作为缓存的作用,如果之前已经加载过同样的Unity3D格式文件,那么不需要在加载,直接拿来用就行了。  
     69                 }  
     70                 if (asset.Type == Asset.TYPE_JSON)
     71                 { //Json 表示当txt文件被首次加载时的处理
     72                         if (mScene == null)
     73                         {        
     74                             string jsonTxt = mSceneAsset.www.text;
     75                             Debug.Log("jsonTxt=" + jsonTxt);
     76                             mScene = JsonMapper.ToObject<Scene>(jsonTxt);//mScene是个Asset对象列表,也就是Json文件需要一个AssetList列表对象,注意名字的统一,列表中Asset对象中的成员名称要和txt                //文件中的相关名称统一 不然JsonMapper无法找到
     77                          }
     78                         //load scene
     79                         foreach (Asset sceneAsset in mScene.AssetList)
     80                         {
     81                                 if (sceneAsset.isLoadFinished)
     82                                 {
     83                                         continue;
     84                                 }
     85                                 else
     86                                 {
     87                                         LoadAsset(sceneAsset);//这里的处理就是 下面 Asset.TYPE_GAMEOBJECT的处理方式,注意是递归函数的调用
     88                                         if (!sceneAsset.isLoadFinished)
     89                                         {
     90                                             return null;
     91                                          }
     92                                  }
     93                         }
     94                 }
     95                 else if (asset.Type == Asset.TYPE_GAMEOBJECT)//处理文件中具体信息,嵌套关系或者直接是一个GameObject对象,与上面的代码有联系,Asset创建时候的构造函数中设置成
     96                 //TYPE_GAMEOBJECT类型
     97                 { //Gameobject
     98                         if (asset.gameObject == null)//如果不为null 表示已经通过wwwCacheMap加载了资源包中所包含的资源(fullFileName仅仅是一个文件,资源包中资源是分散的GameObject对象),不需要在重新加载
     99                         {
    100                                 wwwCacheMap[fullFileName].assetBundle.LoadAll();//已经通过new WWW操作完成了加载,该函数用来加载包含着资源包中的资源
    101                                 GameObject go = (GameObject)GameObject.Instantiate(wwwCacheMap[fullFileName].assetBundle.mainAsset);
    102                                 UpdateGameObject(go, asset);
    103                                 asset.gameObject = go;
    104                         }
    105                         if (asset.AssetList != null)//有嵌套关系
    106                         {
    107                                 foreach (Asset assetChild in asset.AssetList)
    108                                 {
    109                                         if (assetChild.isLoadFinished)
    110                                         {
    111                                                 continue;
    112                                         }
    113                                         else
    114                                         {
    115                                                 Asset assetRet = LoadAsset(assetChild);
    116                                                 if (assetRet != null)//这个if else 语句是为了防止你的配置文件中的GameObject对象路径不正确,导致访问空指针。
    117                                                 {
    118                                                         assetRet.gameObject.transform.parent = asset.gameObject.transform;
    119                                                 }
    120                                                 else
    121                                                 {
    122                                                         return null;
    123                                                 }
    124                                         }
    125                                 }
    126                         }
    127                 }
    128                 asset.isLoadFinished = true;
    129                 return asset;
    130         }
    131         private void UpdateGameObject(GameObject go, Asset asset)
    132         {
    133                 //name
    134                 go.name = asset.Name;
    135                 //position
    136                 Vector3 vector3 = new Vector3((float)asset.Position[0], (float)asset.Position[1], (float)asset.Position[2]);
    137                 go.transform.position = vector3;
    138                 //rotation
    139                vector3 = new Vector3((float)asset.Rotation[0], (float)asset.Rotation[1], (float)asset.Rotation[2]);
    140                 go.transform.eulerAngles = vector3;
    141         }
    142 }
    View Code
     1 Asset.cs类:
     2 using UnityEngine;
     3 using System.Collections.Generic;
     4 public class Asset
     5 {
     6         public const byte TYPE_JSON = 1;
     7         public const byte TYPE_GAMEOBJECT = 2;
     8         public Asset()
     9         {
    10             //default type is gameobject for json load
    11             Type = TYPE_GAMEOBJECT;
    12         }
    13         public byte Type
    14         {
    15             get;
    16             set;
    17         }
    18         public string Name
    19         {
    20             get;
    21             set;
    22         }
    23         public string Source
    24         {
    25             get;
    26             set;
    27         }
    28         public double[] Bounds
    29         {
    30             get;
    31             set;
    32         }
    33        
    34         public double[] Position
    35         {
    36             get;
    37             set;
    38         }
    39         public double[] Rotation
    40         {
    41             get;
    42             set;
    43         }
    44         public List<Asset> AssetList
    45         {
    46             get;
    47             set;
    48         }
    49         public bool isLoadFinished
    50         {
    51             get;
    52             set;
    53         }
    54         public WWW www
    55         {
    56             get;
    57             set;
    58         }
    59         public GameObject gameObject
    60         {
    61             get;
    62             set;
    63         }
    64 }
    65 Scene.cs类:
    66 using System.Collections.Generic;
    67 
    68 public class Scene
    69 {
    70         public List<Asset> AssetList
    71         {
    72             get;
    73             set;
    74         }
    75 }


    生成.unity3d代码:

    View Code
     1 using UnityEngine;
     2 using UnityEditor;
     3 using System.IO;
     4 using System;
     5 using System.Text;
     6 using System.Collections.Generic;
     7 using LitJson;
     8 public class BuildAssetBundlesFromDirectory
     9 {
    10       static List<JsonResource> config=new List<JsonResource>();
    11       static Dictionary<string, List<JsonResource>> assetList=new Dictionary<string, List<JsonResource>>();
    12         [@MenuItem("Asset/Build AssetBundles From Directory of Files")]//这里不知道为什么用"@",添加菜单
    13         static void ExportAssetBundles ()
    14         {//该函数表示通过上面的点击响应的函数
    15                    assetList.Clear();
    16                    string path = AssetDatabase.GetAssetPath(Selection.activeObject);//Selection表示你鼠标选择激活的对象
    17                   Debug.Log("Selected Folder: " + path);
    18        
    19        
    20                   if (path.Length != 0)
    21                   {
    22                            path = path.Replace("Assets/", "");//因为AssetDatabase.GetAssetPath得到的是型如Assets/文件夹名称,且看下面一句,所以才有这一句。
    23                             Debug.Log("Selected Folder: " + path);
    24                            string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);//因为Application.dataPath得到的是型如 "工程名称/Assets"
    25                            
    26                            string[] div_line = new string[] { "Assets/" };
    27                            foreach(string fileName in fileEntries)
    28                            {
    29                                     j++;
    30                                     Debug.Log("fileName="+fileName);
    31                                     string[] sTemp = fileName.Split(div_line, StringSplitOptions.RemoveEmptyEntries);
    32                                     string filePath = sTemp[1];
    33                                      Debug.Log(filePath);
    34                                     filePath = "Assets/" + filePath;
    35                                     Debug.Log(filePath);
    36                                     string localPath = filePath;
    37                                     UnityEngine.Object t = AssetDatabase.LoadMainAssetAtPath(localPath);
    38                                    
    39                                      //Debug.Log(t.name);
    40                                     if (t != null)
    41                                     {
    42                                             Debug.Log(t.name);
    43                                             JsonResource jr=new JsonResource();
    44                                             jr.Name=t.name;
    45                                             jr.Source=path+"/"+t.name+".unity3d";
    46                                               Debug.Log( t.name);
    47                                             config.Add(jr);//实例化json对象
    48                                               string bundlePath = Application.dataPath+"/../"+path;
    49                                                if(!File.Exists(bundlePath))
    50                                                 {
    51                                                    Directory.CreateDirectory(bundlePath);//在Asset同级目录下相应文件夹
    52                                                 }
    53                                               bundlePath+="/"  + t.name + ".unity3d";
    54                                              Debug.Log("Building bundle at: " + bundlePath);
    55                                              BuildPipeline.BuildAssetBundle(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);//在对应的文件夹下生成.unity3d文件
    56                                     } 
    57                            }
    58                             assetList.Add("AssetList",config);
    59                             for(int i=0;i<config.Count;i++)
    60                             {
    61                                     Debug.Log(config[i].Source);
    62                             }
    63                   }
    64                 string data=JsonMapper.ToJson(assetList);//序列化数据
    65                 Debug.Log(data);
    66         string jsonInfoFold=Application.dataPath+"/../Scenes";
    67         if(!Directory.Exists(jsonInfoFold))
    68         {
    69             Directory.CreateDirectory(jsonInfoFold);//创建Scenes文件夹
    70         }
    71                 string fileName1=jsonInfoFold+"/json.txt";
    72                 if(File.Exists(fileName1))
    73                 {
    74                     Debug.Log(fileName1 +"already exists");
    75                     return;
    76                 }
    77                 UnicodeEncoding uni=new UnicodeEncoding();
    78                   
    79                 using(  FileStream  fs=File.Create(fileName1))//向创建的文件写入数据
    80                 {
    81                         fs.Write(uni.GetBytes(data),0,uni.GetByteCount(data));
    82                         fs.Close();
    83                 }
    84       }
    85 }

     

    展开全文
  • unity3d可以把游戏发布在很多游戏平台下,但unity3d在不同的运行平台下,本地文件路径是不一样的,这样给我们用给应用配置本地文本文件的读取带来不小的麻烦,要要把不同的平台来写出不同的路径,特别是android ...
  • Unity3d 动态读取外部文件,1,加载封装好的内部文件。2,加载磁盘文件
  • Unity3D读取外部文件

    2020-03-30 17:01:18
    Unity3D读取外部文件xml、jsonC#读取XML文档C#读取Json文本 C#读取XML文档 Unity3D读取XML文档不需要另外导入程序集(dll),直接引用System.Xml就行。 C#读取XML文档的代码需要根据xml文档结构做出修改。 using ...
  • 欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦: ...导入导出Markdown文件 丰富的快捷键 快捷键 加粗 Ctrl + B 斜体 Ctrl + I 引用 Ctrl
  • 首先是获取到配置文件的文本路径,这里就不多做介绍了,不了解的可以查阅Unity3d实现打开窗口选择文件获取路径 获取到路径后 开始准备读写文件,读写文件的方法也有很多 可参考 C#读写文件的两种方式 我这里使用...
  • 我竟然最近两天才知道Unity中ScriptableObject的存在…… 看了下ScriptableObject的一些介绍,最大的优点感觉有三点: 把数据真正存储在了资源文件中,可以像其他资源那样管理它,例如退出运行也一样会保持修改 ...
  • Unity3D读取保存XML文件

    2020-07-21 10:00:02
    Unity3D中如何读取保存XML文件 说明+代码,想在unity项目中使用配置文件或者需要保存和读取数据但又不想使用数据库的可以看看
  • 这里以TXT文件为目标 不管使用什么读写时,记得先判断目标路径是否存在以防出现bug 常用路径
  • Unity游戏中加载配置文件系列文章,希望能帮助到大家。
  • Unity3d读取.csv文件

    2016-05-31 16:58:22
    (一)文件路径 需要把二进制文件放在StreamingAssets这个文件夹中,一定要放在这里。
  • 通常,在游戏的开发过程中,最终会建立起一些组件,通过某种形式的配置文件接收一些数据。这些可能是程序级别生成系统的一些参数,或许是手势识别系统的手势集,或任何其他东西。如果你是在Unity内部开发,很可能以...
  • unity3d可以把游戏发布在很多游戏平台下,但unity3d在不同的运行平台下,本地文件路径是不一样的,这样给我们用给应用配置本地文本文件的读取带来不小的麻烦,要要把不同的平台来写出不同的路径,特别是android ...
  • Unity3D 数据转换 本地数据存储、Excel表格数据读取与多语言本地
  • 1、修改host文件  在C:\Windows\System32\drivers\etc文件夹下找到hosts文件,因为涉及到管理权限,将该文件复制到桌面并用txt打开,里面什么都没有。  写下这段文字: 127.0.0.1 www.zhcskjtext.cn  127.0.0.1...
  • Unity3D研究院之Android NDK编译C/C++结合Unity实现本地数据共享 转载自: http://www.xuanyusong.com/archives/1129 作者: 雨松MOMO 2012年06月02日 于 雨松MOMO程序研究院 发表 开始本篇...
1 2 3 4 5 ... 20
收藏数 2,368
精华内容 947
关键字:

unity3d 本地配置文件