2013-04-19 17:10:45 iteye_20251 阅读数 221

一、创建Unity项目

       打开Unity游戏编辑器界面,在导航菜单栏中选择File --->  New Project菜单项,在弹出界面中选择Create new Project页面,将项目名命名为MobilityModel,然后再点击Create Project,完成项目的创建。

       然后点击保存(Ctrl+S)保存场景。

 

二、构建模型

       在Hierarchy视图中分别创建游戏对象Plane(面板)、Cube(立方体)、Sphere(球体)、Cylinder(圆柱体)、Capsule(胶囊体),然后鼠标拖动创建的游戏对象将他们摆放在合适的位置。

       接下来在游戏中添加一个光源,在Hierarchy视图中选择Create--->Directional light菜单项,光源是游戏中非常重要的一个属性,一定要在游戏场景中设置它,如果不设置光源对象,Game视图会非常暗,严重影响游戏的效果。

 

三、添加脚本

       在Project视图中点击Create--->JavaScript菜单项创建一个游戏脚本,将其命名为MobilityModelScript.js,在脚本上编写如下代码:

//模型移动速度
var TranslateSpeed = 10;
//模型旋转速度
var RotateSpeed = 1000;
//绘制UI界面
function OnGUI(){
	//设置GUI背景色
    GUI.backgroundColor = Color.red;
	if(GUI.Button(Rect(10,10,70,30),"向左旋转")){
		//向左旋转
		transform.Rotate(Vector3.up * Time.deltaTime * (-RotateSpeed));
	}
	if(GUI.Button(Rect(90,10,70,30),"向前移动")){
		//向前移动
		transform.Translate(Vector3.forward * Time.deltaTime * TranslateSpeed);
	}
	if(GUI.Button(Rect(170,10,70,30),"向右旋转")){
		//向右旋转
		transform.Rotate(Vector3.up * Time.deltaTime * RotateSpeed);
	}
	if(GUI.Button(Rect(90,50,70,30),"向后移动")){
		//向后移动
		transform.Translate(Vector3.forward * Time.deltaTime * (-TranslateSpeed));
	}
	if(GUI.Button(Rect(10,50,70,30),"向左移动")){
		//向左移动
		transform.Translate(Vector3.right * Time.deltaTime * (-TranslateSpeed));
	}
	if(GUI.Button(Rect(10,50,70,30),"向右移动")){
		//向右移动
		transform.Translate(Vector3.right * Time.deltaTime * TranslateSpeed);
	}
	
	//显示模型位置信息
	GUI.Label(Rect(250,10,200,30),"模型位置"+transform.position);
	//显示模型旋转信息
	GUI.Label(Rect(250,50,200,30),"模型旋转"+transform.rotation);
}

      上述代码中重要方法和属性如下:

      OnGUI()方法用来绘制GUI界面组件。

      GUI.Button():设置一个按钮,返回true时表示该按钮被按下。

      GUI.Label():设置一个文本框。

      transform:为当前绑定模型的变换对象。

      transform.Rotate():设置模型旋转。

      transform.Translate():设置模型平移。

      Time.deltaTime:该数值为一个只读属性,不可修改,表示完成最后一帧的事件,单位为秒。

      Vector3:标志一个模型移动或者旋转的方法。

      Rect:规定一个矩形区域,用于显示控件。

      将编写好的脚本对象,将其从Project视图拖拽到Hierarchy视图中的立方体(Cube)对象上,如果没有提示错误,表示脚本绑定成功,运行游戏后该游戏对象将执行该脚本中的内容。

 

       目前立方体对象与其他模型对象之间是不存在碰撞的,但是运行游戏后,可以控制立方体(Cube)直接穿越另一个模型对象。为了让模型对象之间具有物理的碰撞,需要给模型对象添加一个刚体(Rigidbody)属性,添加方式:首先在Hierarchy视图中选中立方体对象,在Uinty导航菜单栏中选择Component --> Physics 

-->Rigidbody菜单项即可。

 

四、测试运行

       点击运行按钮就能看到结果,可以点击显示的六个按钮对象,可以移动Cube(立方体)的位置和旋转。


 

2014-05-29 11:36:21 u011212411 阅读数 1928

Unity3D模型制作规范

一.单位,比例统一

在建模型前先设置好单位,在同一场景中会用到的模型的单位设置必须一样,模型与模型之间的比例要正确,和程序的导入单位一致,即便到程序需要缩放也可以统一调整缩放比例。统一单位为米。

二.模型规范

⒈所有角色模型最好站立在原点。没有特定要求下,必须以物体对象中心为轴心。

⒉面数的控制。移动设备每个网格模型控制在300-1500个多边形将会达到比较好的效果。   而对于桌面平台,理论范围1500-4000。如果游戏中任意时刻内屏幕上出现了大量的角色,那么就应该降低每个角色的面数。比如,半条命2对于每个角色使用2500-5000个三角面。

正常单个物体控制在1000个面以下,整个屏幕应控制在7500个面以下。所有物体不超过20000个三角面。

⒊整理模型文件,仔细检查模型文件,尽量做到最大优化,看不到的地方不需要的面要删除,合并断开的顶点,移除孤立的顶点,注意模型的命名规范。模型给绑定之前必须做一次重置变换。

⒋可以复制的物体尽量复制。如果一个1000面的物体,烘焙好之后复制出去100个,那么他所消耗的资源基本和一个物体消耗的资源一样多。

三.材质贴图规范

⒈我们目前使用的Unity3D软件作为仿真开发平台,该软件对模型的材质有一些特殊的要求,在我们使用的3dsMax中不是所有材质都被Unity3D软件所支持,只有standard(标准材质)和Multi/Sub-Objiect(多维/子物体材质)被Unity3D软件所支持。注:Multi/Sub-Objiect(多维/子物体材质)要注意里面的子材质必须为standard(标准材质)才能被支持。

⒉Unity3D目前只支持Bitmap贴图类型,其它所有贴图类型均不支持。只支持DiffuseColor(漫反射)同self-Illumination(自发光,用来导出lightmap)贴图通道。 Self-Illumination(不透明)贴图通道在烘焙lightmap后,需要将此贴图通道channel设置为烘焙后的新channel,同时将生成的lightmap指向到self-Illumination。

四.贴图文件格式和尺寸

原始贴图不带通道的jpg,带通道的为32位tga或者 png,尺寸最大别超过2048,贴图文件尺寸须为2的N次方 (8、16、32、64、128、256、512、1024)最大贴图尺寸不能超过1024x1024,特殊情况下尺寸可在这些范围内做调整。

五.贴图材质应用规则

⒈贴图不能为中文命名,不能有重名;

⒉材质球命名与物体名称一致,材质球的父子层级的命名必须一致;

⒊同种贴图必须使用一个材质球;

⒋除需要用双面材质表现的物体之外,其他物体不能使用双面材质;

⒌材质的ID和物体的ID号必须一致;

⒍若使用completemap烘焙,烘焙完毕后会自动产生一个shell材质,必须将shell材质变为standard标准材质,并且通道要一致,否则不能正确导出贴图;

⒎带Alpha通道的贴图存储为tga或者png格式,在命名是必须加_al以区分。

⒏模型需要通过通道处理时需要制作带有通道的纹理,在制作树的通道纹理是,最好将透明部分改为树的主色,这样在渲染是可以使有效边缘部分的颜色正确,通道纹理在程序渲染时占用的资源币同尺寸的普通纹理要多.通道纹理命名时应以_al结尾。

六.模型烘焙及导出

⒈模型的烘焙方式有两种:一种是LightMap烘焙贴方式,这种烘焙贴图渲染出来的贴图只带有阴影信息,不包含基本纹理。具体应用于制作纹理较清晰的模型文件(如地形),原理是将模型的基本纹理贴图和LightMap阴影贴图两者进行叠加。优点是最终模型纹理比较楚,而且可以使用重复纹理贴图,节约纹理资源;烘焙后的模型可以直接导出FBX文件,不用修改贴图通道。缺点是LightingMap贴图不带有高光信息;

⒉另一种是CompleteMap烘焙方式,这种烘焙贴图方式的优点是渲染出来的贴图本身就带有基本纹理和光影信息,但缺点是没有细节纹理,且在近处时纹理比较模糊。

⒊烘焙贴图设置。

在进行completemap烘焙方式设置时应注意:贴图通道和物体uv坐标通道必须为1通道,烘焙贴图文件存储为tga格式,背景要改为与贴图近似的颜色;

lightingmap烘焙设置时,和completemap设置有些不同,贴图通道和物体uv坐标通道必须为3通道,烘焙时灯光的阴影方式为adv.raytraced 高级光线跟踪阴影,背景色要改为白色,可以避免黑边的情况。主要物件的贴图uv必须手动展开。

七. 模型绑定及动画

1.骨骼必须为IK、CAT、BIP三类,unity不认虚拟体动画,单个物体骨骼数量不超过60个。

2.动画帧率、帧数的控制,一般情况下为每秒10帧,一个动画尽量控制在1秒内完成。

3.角色蒙皮、动作调节规范详见---(动画规范流程表)。

4.导出动画,分开2个文件,导出没有动作的模型、骨骼,模型需要带有蒙皮信息。之后调节好做动画后导出的就是只有骨骼的fbx文件。

八.模型导出

1.将烘焙材质改为标准材质球,通道为1,自发光100%;

2.所以物体名、材质球名、贴图名保持一致;

3.合并顶点,清除场景,删除没有用的一切物件;

4.清材质球,删除多余的材质球(不重要的贴图要缩小);

5.按要求导出fbx(检查看是否要打组导出),导出fbx后,再重新导入max中查看一遍fbx的动画是否正确;

6.根据验收表格对照文件是否正确;

九.文件备份提交标准

⒈ 最终确认后的max文件分 角色模型、场景模型、道具模型带贴图存放到服务器相应的" 项目名/model/char" "项目名/model/scene"  "项目名/model/prop"文件夹里面。动画文件对应的存放至anim 文件夹中。

⒉ 导出给程序obj、fbx等格式文件统一存放至export文件夹下的子文件夹anim、model、prop

十.项目命名要求

⒈项目进入策划时,各部门统一为项目命好名称,服务器建立项目名称文件夹,制作人员本机制作时建立对应名称的项目文件夹。

⒉角色模型命名:项目名_角色名字,max文件中模型对象如果需要分开各部位时,应在此命名的基础上_部位,如角色头部命名为:项目名_角色名_head ,以此类推。对应的材质球、贴图都将命名一致。

⒊场景、道具命名:项目名_场景名称,max文件中对应的物体为项目名_场景名物体名,同类的比较多的情况下,命名为:项目名_场景名_物体名_01-----02……同类型的物体以数字类推方式命名。材质球、贴图对应物体名字。同类物体只需要给同一个材质球,同一贴图即可。

⒋带通道的贴图:要加_al后缀

⒌特效贴图以特效名称命名,贴图加入_vfx后缀。

2019-12-26 11:44:40 qq_43292530 阅读数 36

本文介绍Unity Asset Store中迷你卡通风格的优质3D模型素材。整个Unity Asset Store中最符合该风格的开发商应该属于:SURIYUN

一:人物篇

以下的人物素材可以轻松运行在手机上。

1:MEGA SD RPG Pack

MEGA SD RPG PACK包含17个角色:骑士、法师、国王、弓箭手、海盗、盒子男、青蛙人、不死族、护士等还有若干怪兽。另外包含完整的环境素材。

2:SD RPG Pack1

SD RPG Pack1包含8个人物角色:黑骑士、警察、古罗马人、萨满、盗贼和3个怪兽。还包含完整的环境素材。

3:SD RPG Pack2

SD RPG Pack2包含若干人物角色:骑士、泥石人、精灵、兽人和若干怪兽。包含完整的环境素材。

4:SD RPG Pack4

SD PRG Pack4包含若干人物角色:圣诞老人、驯鹿、雪怪、冰雪公主、假面骑士和一只怪兽。包含完整的环境素材。

5:SD RPG Pack5

SD RPG Pack5包含若干人物角色:小恶魔、科学怪人、木乃伊、南瓜人和两只怪兽。包含完整的环境素材。

6:POLYGON MINI - Fantasy Character Pack

这是一组Low Poly迷你卡通风格的人物素材,包含60组不同的迷你人物模型,非常推荐。

7:POLYGON MINI - City Character Pack

包含37个Q版城镇人物素材。

8:Mini Skeleton Swarm Pack

该资源包包含5个暗黑风格的迷你骷髅人模型。

9:Minions Series - Goblin

该模型包含哥布林种族模型:勇士、剑手、魔法师、弓箭手和士兵。模型带有完整动画。该开发商还开发了其他几个种族的迷你版模型:Downrain DC开发的其他迷你模型

10:Mini Legion Human HP

该资源包含8个人类种族的迷你模型,该开发商还有其他种族的迷你版模型:Dungeon Mason开发的其他迷你模型

二:环境篇

1:POLYGON MINI - Fantasy Pack

POLYGON MINI - Fantasy Pack包含了306个不同的Low Poly风格的迷你环境资源,为幻想风格。而且为6边型风格模型,适合作为策略游戏或者战棋游戏的场景资源。

2:POLYGON MINI - City Pack

POLYGON MINI - City Pack同样包含了306个不同的Low Poly风格的迷你环境素材,为城镇风格。而且为6边型风格模型,适合作为策略游戏或者战棋游戏的场景资源。

3:Mini Towers Pack

该资源包的迷你环境素材非常适合制作制作塔防游戏。

4:Minicar Race Creator

该素材包含制作一款赛车游戏的所有材料。

三:动物篇

1:Cute 3D Voxel Animals

Cute 3D Voxel Animals包含40个迷你版的动物模型,适合制作Cross Street风格的休闲游戏。

2:KUBIKOS - 22 Animated Cube Mini Animals

该资源包含22个带有动画的Low Poly迷你版动物模型。

3:Yippy Kawaii

该资源包含猫咪、兔子和小熊,每种素材都有多种材质可以替换,而且带有超多动画。

4:Cute Pet

Cute Pet包含了20多种可爱的小动物,每种小动物都包含6组动画。

5:Cute Zoo

Cute Zoo包含了11个动物模型,每种小动物都包含6组动画。

6:MEGA Monsters Pack

MEGA Monsters Pack包含几十种小动物的模型资源。

7:Funny Bear

Funny Bear包含小熊模型,而且有非常多的素材可以替换。模型带有完整的动画。

 

2013-07-18 12:49:48 u010743716 阅读数 1332

导入模型,发现人物漫游时直接穿过工厂模型,解决办法

在project视图中选中该模型,在Inspector视图中更改该模型的属性,将Generate Colliders选中,

apply一下

即可设置模型的碰撞

2013-10-14 19:49:57 u011838628 阅读数 9032

      最近在看Unity3D的人物模型和动画。所以今天先说下人物的换装吧。相信大家都玩过网游吧,没有玩过的也相信见过,就是网游或者单机游戏里的人物会有更换服装,更换武器的功能。如果外形(mesh)是一样的,那么把贴图换下就好,但是如果外形不一样甚至骨骼都变了的话,就需要我们今天讨论的技术了。

  一.Unity3D里的3D模型

Unity3D里的基础模型是从3D工具中导出来的fbx文件。把fbx放在Assets目录下会自动生成一个Materials文件夹,里面会生成一个材质球。在Unity3D项目里的显示是这样

注意:Textrue需要另外添加进去。

         模型的主要文件就是那个蓝色的方块,前面两个(WGKS_wugang,WGKS_yaodai)这两个文件是模型的Mesh信息,一个是人物本身的,一个是腰带的,因为比较简单的模型,所以只有两个。下面的一坨是动作信息,动作是可以自己设置的,这个以后文章会讲。而紧接着的

“Bip001”这个是模型的骨骼信息,你拖到Scene里就能层层打开看到了。而WGKS_yaodai则是蒙皮信息的一些玩意。选择到它会在Inspector属性栏里看到SkinnedMeshRenderer组件,这里会看到它牵扯到的mesh,material,bone信息。

  

  二.换装方案1组合模型的显示和隐藏

  这个题目可能说的不合适,但是想不到更合适的了。我们的第一种换装的方法很简单,就是让模型或者Mesh进行显示和隐藏。就比如让人物穿两套衣服,显示第一套的时候隐藏第二套,显示第二套的时候显示第一套。

         例如这个模型:

         

这里有TBJ_SR_01和TBJ_SR_03两个SkinnedMeshRenderer.那么我们可以分别设置Active来设置是否可见。代码如下:

public GameObject clothA = null;
public GameObject clothB = null;

if (GUI.Button(new Rect(5, 5, 100, 50), "ClothA"))
{
    clothA.SetActive(true);
    clothB.SetActive(false);
}

if (GUI.Button(new Rect(5, 60, 100, 50), "ClothB"))
{
    clothA.SetActive(false);
    clothB.SetActive(true);
}


运行起来的效果如下:

ClothA

ClothB

      如果角色是换武器而不是换装备的话,原理是一样的,只不过我们要找到附属的武器GameObject然后设置让它显示和隐藏就可以了。

  三.换装方案2 替换Skin信息

      方案1的方法用起来比较简单,比较适合简单的模型替换,比如一个模型来来回回就两把武器的话,就可以用。但是如果一个模型有十来套衣服或者十几件装备的话,这么做会比较悲剧的,因为太占资源了,创建一个模型,牵扯的不用的东西也整进内存了,暴殄天物。

      所以我想能不能游戏运行的时候替换模型的Skin信息达到我们的目的。一开始我觉得,其实我们只需要把sharedmesh,material替换掉就行了。实验证明不行的。大家可以自己尝试下,Unity3D会报错,即使不报错模型也会变形的。模型中还有一块是骨骼没有动,所以我想尝试下如果把骨骼去掉能不能拿到mesh信息等,然后再替换。结果是从3DMAX里去掉骨骼导出的话,蒙皮信息也没有了。所以我确定了一点是,被换装的模型必须有骨架,而源Mesh信息中必须包含骨架信息,按照我的理解就是Mesh中保存着这个点依附的是哪个骨头,权重是多少等。

 

  这里我准备了两个模型:

            

带有完整的信息(骨头,动作,蒙皮信息等,只不过模型只有一个mesh而已)。

放在Scene的样子:

            

  我的目的是想让左边的那个模型读取右边模型的SkinnedMeshRenderer信息,然后赋值给自己。首先我把右边的模型除了骨架的所以资源赋值给一个prefab,然后加载prefab,读取信息给左边的模型。

  代码如下:

// 声明两个SkinnedMeshRenderer
public SkinnedMeshRenderer MyskinMeshRender = null;
public SkinnedMeshRenderer SrcSkinMeshRender = null;

//加载资源
Object Src = Resources.Load("Res/Materials2");
objSrc = Instantiate(Src) as GameObject;

//找到目标模型的SkinnedMeshRenderer
MyskinMeshRender = GameObject.Find("TBJ_SR_01").GetComponent<SkinnedMeshRenderer>();
//获取加载的SkinnedMeshRenderer
SrcSkinMeshRender = objSrc.GetComponent<SkinnedMeshRenderer>();
//获取目标模型的骨骼
Transform[] bonesMy = gameObject.GetComponentsInChildren<Transform>();
Debug.Log(bonesMy.Length);
//Transform[] bonesSrc = GameObject.Find("TBJ_SR_03").GetComponentsInChildren<Transform>();
//获得源SkinMesh中依附的骨骼信息
Transform[] bonesSrc = SrcSkinMeshRender.bones;
Debug.Log(bonesSrc.Length);

//根据源SkinMesh依附的骨骼信息重新排列目标骨骼
List<Transform> bones = new List<Transform>();
foreach (Transform boneS in bonesSrc)
{
    foreach (Transform boneM in bonesMy)
    {
        if (boneS != null && boneM != null)
        {
            if (boneS.name != boneM.name)
            {
                continue;
            }
            bones.Add(boneM);
        }
    }
}
MyskinMeshRender.bones = bones.ToArray();
MyskinMeshRender.sharedMesh = SrcSkinMeshRender.sharedMesh;
MyskinMeshRender.sharedMaterials =SrcSkinMeshRender.sharedMaterials;     


运行之后发现皮肤换了,而且动画信息没有丢失掉,也就是说还能动,但是有个奇葩的现象,人物是倒着的,如图:

  这个我分析后觉得是因为骨骼的问题。两个模型的骨骼有点不一样。因为我是读取了右边的模型的蒙皮信息对应的骨骼信息而重组了左边的骨骼,但是左边的动画信息还是按照原来的。虽然不是很清楚动画数据里面数据结构,但是我觉得就是记录的骨骼或者mesh或者当前模型的世界坐标的某个点对应的Mesh或者骨骼移动到哪个位置。

 

  接着我换了一个思路,用一个人物模型,一套骨骼,一套动作,不过蒙皮信息有两个,导出fbx。

如图:

 

  然后在3DMax里面导出一个没有蒙皮信息只有骨骼和动作的fbx,如图:

  然后添加脚本,代码如下: 

//声明两个SkinMeshRender 声明为public是为了方便观察 真正需要private
public SkinnedMeshRenderer MyskinMeshRender = null;
public SkinnedMeshRenderer SrcSkinMeshRender = null;

//添加SkinnedMeshRenderer组件
MyskinMeshRender = gameObject.AddComponent<SkinnedMeshRenderer>();
	
if (Input.GetKeyDown(KeyCode.Z))
{
    GameObject obj = GameObject.Find("TBJ_SR_01") as GameObject;
    SrcSkinMeshRender = GameObject.Find("TBJ_SR_01").GetComponent<SkinnedMeshRenderer>();

    Transform[] bonesMy = gameObject.GetComponentsInChildren<Transform>();
    Transform[] bonesSrc = SrcSkinMeshRender.bones;

    List<Transform> bones = new List<Transform>();
    foreach (Transform boneM in bonesSrc)
    {
        foreach (Transform boneS in bonesMy)
        {
            if (boneM != null && boneS != null)
            {
                if (boneM.name != boneS.name)
                {
                    continue;
                }
                bones.Add(boneS);
            }
        }
    }
    MyskinMeshRender.bones = bones.ToArray();
    MyskinMeshRender.sharedMesh = SrcSkinMeshRender.sharedMesh;
    MyskinMeshRender.sharedMaterials = SrcSkinMeshRender.sharedMaterials;
}


 

  运行,结果没有问题了。如图:

  

  按下Z之后:

  而且动作保留。

 

  总结:

  虽然这个例子不是很经典,也存在些许问题,希望大家指出问题,共同进步。在添加skinnedMeshRenderer组件的时候有个问题,如果模型选择Generic的时候,Unity3D会挂掉。

这个例子可以运用到骨骼和动作基本一样,但是外形不同的模型中,减少游戏中的资源重复占用。网上还有个更经典的例子,运用的是Character Customization 包,运用的原理是一样的,这里给大家看下运行结果:

  

      

  这个模型是由各个部分的mesh组成,而我的例子是用的一个mesh。在复杂的模型中,我们可以查找子组件的SkinnedMeshRenderer,然后进行操作就可以了。想换哪里就替换哪里的SkinnedMeshRenderer的信息,更新对应的骨骼列表和组合一下网格就行了。

List<CombineInstance> combineInstances = new List<CombineInstance>();
CombineInstance ci = new CombineInstance();
ci.mesh = SrcSkinMeshRender.sharedMesh;
combineInstances.Add(ci);


         还有一个想法是这样的,源资源中是否需要骨头。我发现重组骨头结构的时候其实只是读取了骨头的列表信息,所以我觉得可以写成一个配置信息,直接读取配置信息来重组。这个想法还没有得到验证,等有时间的吧。

 

 

Unity3D 模型分块

阅读数 1595

没有更多推荐了,返回首页