U3D资源打包与动态加载各种事项与方案

来源:互联网 发布:linux stdin 编辑:程序博客网 时间:2024/05/01 06:46
1. fbx直接打包,没有连带资源与否
2. 可把fbx拖入场景存为预设,然后打包,打包分为依赖打包,和非依赖打包。
3. 打包资源的时候,不要存在名字有空格的资源,因为在动态加载的时候,名称有空,容易出现问题。
4. 相同的类型,但是资源内容除Transform外其他都不同,场景中都要区分使用不同名称,并存成不同资源

动态加载材质贴图问题
. 以材质球为资源单位进行加载,打包的时候直接打包材质球连带贴图一起打包给材质球
    细节:材质球制作两份(两份贴图):一份是精细材质球,里面是场景的正式资源,一份是粗略材质,粗略材质默认放在场景当中,当场景加载完毕后,然后根据粗略材质
             的信息,去加载精细材质完成贴图。
. 以贴图为资源单位进行加载,打包的时候也会直接通过打包材质球连带贴图一起打包
    细节:材质球只需要一份粗略材质球,但是需要两份贴图,在加载精细贴图的时候,是不需要加载材质球的,而是通过获取材质球的对象,然后去获取材质球下的贴图信息,
            并下载指定贴图,然后赋给材质球对象,完成贴图的替换工作。

加载资源协同与多线程:
1 .协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。
unity中StartCoroutine()就是协程,协程实际上是在一个线程中,只不过每个协程对CUP进行分时,StartCoroutine()可以访问和使用unity的所有方法和component
2 .Thread,多线程是阻塞式的,每个IO都必须开启一个新的线程,但是对于多CPU的系统应该使用thread,尤其是有大量数据运算的时刻,但是IO密集型就不适合;而且thread中不能操作unity的很多方法和component
3 .异步,其实就是从线程池中的一个线程来完成某个任务,适合于IO密集型的操作。
4 .协同程序(coroutine)与多线程情况下的线程比较类似:有自己的堆栈,自己的局部变量,有自己的指令指针(IP,instruction pointer),但与其它协同程序共享全局变量等很多信息。线程和协同程序的主要不同在于:在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起。
资源加载方案
散资源单独下载,单独加载
    每个散资源都是一个单独的assetbundle,但是下载完了后,就会获取mainAseetbundle,实例化到场景,然后继续下载下一个,如此下去直到全部下载完成。
整体资源下载,单独加载
    把场景的散资源一起打包成一个大的资源包,然后下载一个assetbundle,下载完后,利用loadAll获取到大资源包下单个资源包的序列,然后依次实例化到场景

Caching.CleanCache();
如果两个场景存在同一名称的资源对象,当前一个场景已经下载之后,如果在第二个场景还是下载同名的资源(资源本质不同),会产生,U3D默认以为是已经下载并缓存好了的资源,而直接会使用前一个场景的同名资源,而不是下载后一个场景新的资源,这样容易出错。
所以,每个场景资源不能同名。同一加_下划线区分。

如是本地加载方式,WWW加载方式换成Resources.LoadAysc().

WWW下载模型并且下载不同类型资源添加给模型
using UnityEngine;
using System.Collections;
public class DownloadAssets : MonoBehaviour { 
public RuntimeAnimatorController animator; 
private string path = "http://127.0.0.1/res/role/npc_nanzhanglao/fbx/" + "npc_nanzhanglao.assetbundle"; 
private string animpath = "http://127.0.0.1/res/role/npc_nanzhanglao/animator/" + "npc_nanzhanglao.assetbundle";
// Use this for initialization
void Start () 
{
Caching.CleanCache();
StartCoroutine(load());
}
IEnumerator load() 
{
WWW www = WWW.LoadFromCacheOrDownload(path, 1);
yield return www;
if (www.isDone)
{
AssetBundle asset = www.assetBundle;
GameObject go = (GameObject)asset.mainAsset;
asset.Unload(false);
Caching.CleanCache();
StartCoroutine(loadAnimator(go));
}
}

IEnumerator loadAnimator(GameObject go) 

WWW www = WWW.LoadFromCacheOrDownload(animpath, 1);
yield return www;
if (www.isDone)
{
//下载模型的动画资源,因为动画无法连带资源一起打包到模型上,所以动画需要单独打包(暂时只是Animator),但是动画单独打包的时候也需要连带资源打包,要不然动画没有作用。
//所以分开打包,另外,验证的时候,注意清除缓存(Caching.CleanCache(); )
//在资源添加模型之后实例化,要不然没有作用(对材质没有动画的貌似可以先实例化)
//该语法,也针对其他资源的格式转化。
RuntimeAnimatorController run = www.assetBundle.Load("npc_nanzhanglao", typeof(RuntimeAnimatorController)) as RuntimeAnimatorController;
Debug.Log("资源2:" + run.name);
go.GetComponent<Animator>().runtimeAnimatorController = run;
Instantiate(go);
www.assetBundle.Unload(false);
}
}
}
给对象添加材质:
//为已下载的资源对象贴材质资源 
IEnumerator LoadAssetBundlesWithMaterial(string url, string materName, GameObject go) 


WWW www = WWW.LoadFromCacheOrDownload(url, version);
yield return www;
if (www.isDone)
{
//这里可以先实例化,然后再添加材质资源
Debug.Log("开始把贴图资源贴载并且实例化到场景的游戏对象");
Material mater = www.assetBundle.Load(materName, typeof(Material)) as Material;
go.renderer.sharedMaterial = mater;
www.assetBundle.Unload(false);
}
}

C#炸鸡:
C#数据类型:在栈上分配内存的值类型,在堆上分配内存的引用类型。(扩展)
内存分配方式有三种:
  (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。  
  (2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。  
  (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。 构造函数的调用 构造函数的调用顺序是先调用System.Object,再按照层次结构由上向下进行,直到到达编译器要实例化的类为止。还要注意在这个过程中,每个构造函数都初始化它自己的类中的字段。这是它的一般工作方式,在开始添加自己的构造函数时,也应尽可能遵循这个规则。
注意构造函数的执行顺序。基类的构造函数总是最先调用。也就是说,派生类的构造函数可以在执行过程中调用它可以访问的基类方法、属性和其他成员,因为基类已经构造出来了,其字段也初始化了。如果派生类不喜欢初始化基类的方式,但要访问数据,就可以改变数据的初始值,但是,好的编程方式应尽可能避免这种情况,让基类构造函数来处理其字段。

结构
结构遵循其他数据类型都遵循的规则:在使用前所有的元素都必须进行初始化。在结构上调用new运算符,或者给所有的字段分别赋值,结构就完全初始化了。当然,如果结构定义为类的成员字段,在初始化包含对象时,该结构会自动初始化为0。
结构是值类型,所以会影响性能,但根据使用结构的方式,这种影响可能是正面的,也可能是负面的。正面的影响是为结构分配内存时,速度非常快,因为它们将内联或者保存在堆栈中。
在结构超出了作用域被删除时,速度也很快。另一方面,只要把结构作为参数来传递或者把一个结构赋给另一个结构(例如A=B,其中A和B是结构),结构的所有内容就被复制,而对于类,则只复制引用。这样,就会有性能损失,根据结构的大小,性能损失也不同。注意,结构主要用于小的数据结构。但当把结构作为参数传递给方法时,就应把它作为ref参数传递,以避免性能损失--此时只传递了结构在内存中的地址,这样传递速度就与在类中的传递速度一样快了。另一方面,如果这样做,就必须注意被调用的方法可以改变结构的值。




转载请注明出处。

作者: 大帅纷纭

微博:http://weibo.com/2357191704/profile?topnav=1&wvr=6

博客:http://blog.csdn.net/dashuaifenyun1991

邮箱:bandit_empire@163.com






0 0
原创粉丝点击