黄祖祥的文章《关于Unity3D中的Update、LateUpdate、FiexdUpdate》:
http://bbs.9ria.com/thread-417976-1-1.html
当然黄同学也是参考了,博客园的赵青青的两篇文章总结的
http://www.cnblogs.com/zhaoqingqing/p/3454091.html
http://www.cnblogs.com/zhaoqingqing/p/3296086.html
这两位同学的文章已经详尽讲解了三个update的区别用法。
如果非要让DC老湿概括简略的讲呢,就是:
Update()是每帧执行的函数,更新频率和设备的性能有关。
一般你要不停地计算不停地执行着什么的话,是写在Update里的。
FixedUpate()是固定时间间隔执行函数(可人为调整间隔时间),不受游戏帧率影响。
但如果你写的算法是要不断的处理Rigidbody(俗称刚体)以及物理运算神马的,那就最好写在FixedUpate,
LateUpdate()是在所有Update()函数执行完之后,执行。
正因为LateUpdate慢于update所以可以避免在update中因频繁的计算物体的位置方向选装导致的抖动问题。
2,Unity中的1单位是FBX文件中的1单位的几倍?
Unity中的1单位是fbx文件中的1单位的100倍,所以我们想Unity中使用1单位=1米的话,那在Max和Maya中制作的时候,单位就设置成1厘米,如果我们想Unity中1单位=100M,那单位就设置为1M,如果我们想Unity中1单位=1厘米的话,那单位就设置为0.1毫米,或者在单位为1厘米的情况下把比例因子改为1,1Unit = 1厘米,这样在Unity中1格就等3Dmax中的1M了。
由于移动端性能的限制,所以不能用自带的DirectionalLight来设置实时阴影,SO如下:
1,贴图的方式,如果不需要很真实的阴影可以脚下绑定个半透贴图脚本控制来模拟阴影效果,对于材质写一个简单的Shader就行了。
Shader "iPhone/SimpleShadow"
{ Properties
{
_MainTex ("MainTex", 2D) = "" {}
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{ Blend SrcAlpha OneMinusSrcAlpha
Color [_clrBase]
Cull Off
Lighting Off
SetTexture [_MainTex] { combine texture, one - texture }
}
}
}
2,利用相机投射,在游戏主角身上绑定个专门投射的正交相机每帧实时绘制,用Render Texture来接收,也是脚下绑定个面片Plane Quad之类的,这个方式可以有更真实的实时阴影,因为身上会有一个特效之类的透明材质所以要在Shader中来进行处理,使用这个方法的一些注意事项,多人重叠时阴影会多次渲染,所以简单的方法就是给阴影分层处理,单独的投影。还有一点就是跳跃问题因为是脚下绑的面片所以用代码的方式控制跳跃就会出现阴影跟人一起跳跃的状态,所以要注意这一点人物的跳跃可以用动画的方式来实现。这一点在上一种方式也是一样的,还有就是这两种方式都不适合与复杂凹凸的地形阴影会出现奇葩效果。
由于这里代码太多就不贴出来了,大概就是绘制阴影的Shader,相机投射的脚本,跟相机跟随的脚本。详情也可以去泰课的格斗之王60,61,62课去看看。(通过摄像机的RenderRexture绘制显示:http://www.2cto.com/kf/201510/446632.html)
3,使用Unity内置的Projecter投影器。(关于Projecter投影器:http://www.xuanyusong.com/archives/2132
http://blog.sina.com.cn/s/blog_799860f90102vkp2.html)
4,一张图片的像素格式为512*512,若每个像素占4位,存储这张图片的大小为多少KB/MB?
512*512*4=262144*4=1048576(byte)=1024(Kb)=1(M),属于常用纹理 A8R8G8B8像素格式。
5,Unity5.X版本中,如何添加GUI Text组件?是否有其他更好的方法代替它?(新手常见问题)
在Unity5.X以后UI系统已经更新成了UGUI,添加UI-Text代替老版本的GUI Text。
有两种方法添加GUI Text组件
1、选中要添加组件的载体——>Component——>Rendering——>GUI Text
2、选中要添加组件的载体——>在其Inspector面板下点击Add Component——>GUI Text
什么?你问我有否其他更好的方法代替它~Absolutely!当然有~
可以用内置ugui以及NGUI都可以
6,项目导入一张图集后,如何在Unity中使用?(变成一张一张的小图)
导入图集后在project面板中选中它,并在Inspector面板中设置如下参数,并Apply
选中对应的纹理,打开Sprite Editror面板。再点其工具栏的左上角的“Slice”按钮,打开根据个人需要选择切割方式
Automatic方式要智能一点,能自动识别出纹理中的小
Grid方式是根据你的设置行列数,直接把整个纹理划成几等份
也可以手动鼠标划区域,不管以哪种方式,划分的区域,一个区域就是一个精灵了。
用鼠标选中一个区域,你就可以再次张编辑这个精灵了,可以通过左下角的Sprite面板来编辑,也直接用鼠标点击相应的元素以拖动的方式来编辑它,你可移动它,设置它的名字,边框大小,轴点位置。
NGUI和DFGUI,是要先把这整张图集切成一张张的小图,里有其各自的MakeAtlas做成一个Atlas图集预设,然后再其各自的Sprite(NGUI是UISprite,DFGUI是dfSprite里面去,Sprite.SpriteName得到你想要的单张小图)
而UGUI的做法,跟据宣雨松(雨松momo)的说法是,UGUI的原理是让开发者彻底模糊图集的概念,让开发者不要去关心自己的图集。做界面的时候用小图,而在最终打包的时候,unity才会把你的小图合并在一张大图集里面。这一切的一切都是自己动完成的,开发者不用过分在意。
详细的做法和操作步骤在这个链接里。
UGUI图集的理解: http://www.xuanyusong.com/archives/3304
7,当一个物体在视野内被其它物体遮挡,不希望对该物体进行渲染,可以通过哪一个模块实现?
Occlusion Culling遮挡剔除,这个板块在专业版中,选择Window->Occlusion Culling。
Occlusion Culling 也是一个特性,让不可见的物体不被渲染,但这个不是自动发生,这个和摄像头的平截头体的剔除是不一样的,摄像头的平截头体只是不渲染不在可视范围内的物体,但是它不会禁止一些不可见物体的重画。
遮挡剔除和平截头体剔除不相互矛盾。遮挡剔除会在场景中使用一个虚拟摄像头去组织可见物体的层次,这样unity可以根据这个信息确定哪些物体需要被渲染,大大减少draw call的次数,提高性能。具体参数百度一堆就不画蛇添足了。
8,值类型和引用类型的区别?
1,C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型。
C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。
2,值类型在内存管理方面具有更好的效率,并且不支持多态,适合用作存储数据的载体;引用类型支持多态,适合用于定义应用程序的行为。
3,值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。
4,栈的内存分配是自动释放;而堆在.NET中会有GC来释放
5,值类型存取速度快,引用类型存取速度慢。
6,值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。
7,值类型继承自System.ValueType,引用类型继承自System.Object
其实你可以这么理解,更加形象,
“你手里有份报纸很有趣,你朋友很想看,你复印了一份,给你朋友”这个就叫值类型的操作。
“你发现一个网址很有趣,你朋友很想看,你把这个网址,告诉你朋友”这个就叫引用类型的操作。
肿么样,生动不生动~
9,什么是泛型?请举一个通俗易懂的例子
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性。泛型为.NET框架引入了类型参数(type parameters)的概念。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。用一个通用的数据类型T来作为一个占位符,等待在实例化时用一个实际的类型来代替。泛型广泛用于容器(collections)和对容器操作的方法中。.NET框架2.0的类库提供一个新的命名空间System.Collections.Generic,其中包含了一些新的基于泛型的容器类。要查找新的泛型容器类(collection classes)的示例代码,请参见基础类库中的泛型。
泛型中关键字where用以实现约束,类型参数的约束,增加了可调用的操作和方法的数量。这些操作和方法受约束类型及其派生层次中的类型的支持。因此,设计泛型类或方法时,如果对泛型成员执行任何赋值以外的操作,或者是调用System.Object中所没有的方法,就需要在类型参数上使用约束。
举个例子在实际项目中也许会类似功能不通参数类型重复定义使用又或者编程中不确定参数类型
MyList<MyClass> list1 = new MyList<MyClass>();
MyList<float> list2 = new MyList<float>();
MyList<SomeStruct> list3 = new MyList<SomeStruct>();
等等操作的类型方式,完全可以用泛型来定义
MyList<T> list1 = new MyList<T>();
泛型可以适用于类,方法,接口,委托,列表等。
List<int> ls = new List<int>(new int[] { 1, 2, 3, 4, 5 });
foreach (int item in ls)
{
Console.WriteLine(item * item);
ls.Remove(item);
}
还可以用for来遍历如下,List每remove掉一个元素以后,后面的元素都会向前移动,此时如果执行i=i+1,则刚刚移过来的元素没有被读取,每移除一个元素以后再把i移回来就可以了。还可以倒过来遍历代码简单就不都贴了。
List<int> ls = new List<int>(new int[] { 1, 2, 3, 4, 5 });
for(i=0;i<Is.Count;i++)
{
Console.WriteLine(item * item);
ls.Remove(item);
i=i-1;
}
那么学编程的人都知道foreach
和for
不一样,遍历的时候,是不能对集合内的成员随意删改的,这也是二者最大的区别之一。
要问如何避免,乖乖的用for
就好咯~
但又会有同学问:老湿,如果在上述代码里,我一定要装腔(bi
)用foreach
呢,咋整?
我会说:没问题,foreach
里面ls.Remove(item);
这句话肯定是要去掉了,你可以在foreach
遍历完之后,用List
的Clear()
或者RemoveAll()
等方法都可以。
再不济,还可以在最后一行写上ls = new List<int>();
办法有的是,条条大路通罗马咯~
另外贴上博客园Terry的一篇文章《深入foreach和for循环的区别》里面讲到了迭代器以及游标规则,相当深刻的剖析了二者的区别。推荐给大家。
http://www.cnblogs.com/Terry-greener/archive/2011/10/27/2226179.html