blender 和unity3D的一个问题

blender 和unity3D的一个问题,第1张

(引自别处,希望有用)
用Max导出Unity3D使用的FBX文件流程注解
从max导出FBX到Unity,以下环节需要特别注意。
1,单位设置
很多人在建模,动画的时候,默认的max system unit是设置的inch,建议修改成metres或者centimetres,否则导出的模型和动画可能比例不一致
2,导出物
在导出模型和动画时,建议选择的导出模式,是根据你要导出模型或者动画,使用export selected模式导出,即,只导出选中的对象。
3,动画中必须有模型
在使用export selected导出动画时,要全选你要导出的全部骨骼,包括Bipe,和Bone,以及他们的Nub。然后选中任何1个模型,一起导出;FBX不允许没有模型的动画单独存在;
4,可能丢失蒙皮信息的原因1
在使用export selected导出模型时,要选中你要导出的模型,以及全选所有的骨骼,才会有蒙皮信息。查看导出的FBX有没有蒙皮信息,可以把FBX文件拖到Unity里,看Mesh上面有没有一个参数叫做skined mesh material,如果没有,则是你没有选中骨骼就导出了,因此没有蒙皮信息。
5,可能丢失蒙皮信息的原因2
在导出有蒙皮信息的模型文件成FBX时,一定要给每一个模型或者sub mesh指定他们的材质,且给每个材质正确的命名,且其Diffusemap不能为空。 否则也不会有skined mesh mat,也就是蒙皮信息也无法导出。
6,ResetXForm
记得在skin或者physique之前,一定要严格的进行ResetXForm,否则导出的FBX,模型会有严重的偏移; 以下是自用的FBX自动导出脚本说明书
FBX_AniExporterms
当模型/动画的unit和system的unit一致时(建议都是 centimetres),使用这个脚本进行FBX动画文件的批量导出,需要修改里面的导入文件夹和导出文件夹路径,脚本会对导出FBX自动命名;脚本会自动全选场景中所有的$Bip和$Bone,以及1个模型进行导出;
FBX_AllMeshExporterms
批量导出场景中的所有模型/子物体为一个个单独的FBX 模型文件(含模型,UV,蒙皮信息,不含动画信息);脚本在导出时自动使用以下规则:模型1+全部$Bip+全部$Bone,模型2+全部$bip+全部$Bone,模型3+全部$bip+全部$Bone;
FBX_MeshExporterms
旧版的FBX_AllMeshExporter,可以不管; ANI_1by1ms 当模型/动画的unit和system的unit设置不一致时,将system unit设定正确,然后逐个打开要导出的max文件,使用这个脚本一个个导出; InitMatFilems 给场景中所有模型/子物体设置独立的材质球,给材质球自动命名为模型的名字并且填充Diffuse Map,需要指定其中的map路径,且map路径里的TGA贴图张数不能小于场景里的模型数量,脚本才能正确运行;
Select2Export
故名思意,导出选中的模型和骨骼。
unity3d模型导入技巧
Unity3d导入3dMax模型会产生若干问题,按照官方的说明,将max模型导成fbx文件导入untiy似乎也不能解决
1、x轴向偏转
3dmax模型导入后自动有一个x轴270度的偏转,巧合的是,在unity中旋转模型的时候,你会发现y轴参照方向永远朝上,而x和z轴则以模型本身的局部坐标为准,这样当模型沿x轴旋转270度之后,z轴正好与y轴重合,这样你试图用程序控制方向的时候就会发现旋转y和旋转z效果相同,这显然不是你期望的结果。解决这个问题的方法是,将max文件导出为3ds文件再导入untiy,而不是官方说的导成fbx
2、材质问题
模型在3dmax里赋予材质之后,不管通过何种方式导入到unity中,都是没有材质的,好在untiy自动生成了这些材质的材质球,我们需要做的是将贴图再重新设置一遍,如果你的材质还有其他效果,比如lightmap,则需要选择正确的shader之后再设置贴图。 另外一个是多重材质,多重材质暂时还不知道如何在unity中显示,所以在制作模型的之后,应该先确定哪些部件应该合在一起,而哪些需要独立,比如,对于一架直升飞机来说,身体和螺旋桨就可以分为两个部件,而不应该把螺旋桨与发动机合并成一个部件,这样程序就无法旋转螺旋桨了。
3、缩放因子问题
模型导入到untiy中,如果你之前在3dmax中没有关心过“单位”问题,则它在场景里的大小一定会出呼你的意料。
unity中的1单位是fbx文件中的1单位的100倍 所以,如果我们想unity中使用1单位=1米的话,那在max和maya中
制作的时候,单位就设置成1厘米 如果我们想unity中1单位=100M,那单位就设置为1M 如果我们想unity中1单
位=1厘米的话,那单位就设置为01毫米,或者在单位为1厘米的情况下把比例因子改为1 在max中,单设置应
该像这样 1Unit = 1厘米,这样在unity中1格就等3dmax中的1M了
针对经常出现的问题,将需要注意的点罗列如下:
1、物体的头要朝下
2、所有游戏中的车辆飞机大致都可以分成两个部分,一个是身体,一个是炮台或螺旋桨,那么身体要有一个统一的名称,都叫做Body,螺旋桨叫做Airscrew,炮台叫做 Barbette ,这样我就可以找到所有的身体,并把爆炸效果的火焰和身体连接起来
3、模型尺寸比例问题,参考前文所说的设置,另外不管是飞机,还是坦克,尺寸都在10米左右(以这个尺寸为基准),也就是3dmax里的10格大小
4、模型要在场景中居中,否则导入物体质心位置不对
5、起名字可以起这个武器的实际名称,如果不知道的话,也可以叫做Tank1,Tank2这样,但最重要的是贴图名字和模型名字要相同,否则很乱。

1、首先启动Unity,单机菜单栏中的Assets->Create来添加脚本。

2、启动Unity后,单击Project视图中的Create按钮创建脚本。

3、启动Unity应用程序,在Project视图中的assets文件夹内通过右击d出的列表框创建脚本。

4、添加完脚本后就可以在Project视图中看到。

5、双击脚本文件就可以将其打开进行编辑。

首先,我已经建好了我的u3d工程,包括模型,模型的移动、旋转等函数。。
然后,我导出一个xcode工程(版本:unity421、xcode5)。。。
如图:
这是unity导出来的xcode工程的目录结构。
接下来:
第一步:选择UnityAppControllermm这个文件打开。
并在int OpenEAGL_UnityCallback(UIWindow window, int screenWidth, int screenHeight, int openglesVersion)
这个方法里面的
return true;之前加入
//创建一个全屏幕的window
CGRect rect=CGRectMake(0, 0, screenWidth, screenHeight);
window=[[UIWindow alloc] initWithFrame:rect];
[window makeKeyAndVisible];

GLView view=[[GLView alloc] initWithFrame:rect];
[window addSubview:view];
[view release];

MyViewController myView=[[MyViewController alloc] init];
[window addSubview:myViewview];
[myView release];
其中:MyViewController是导出工程后,手动新建的类,目的是,在这个ViewController种控制u3d模型的旋转、移动等动作。
第二步:创建MyViewController并添加按钮,启动u3d
- (void)viewDidLoad {
[super viewDidLoad];
//创建label视图
UILabel label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
//设置显示内容
labeltext = @"雨松MOMO的程序世界";
//设置背景颜色
labelbackgroundColor = [UIColor blueColor];
//设置文字颜色
labeltextColor = [UIColor whiteColor];
//设置显示位置居中
labeltextAlignment = UITextAlignmentCenter;
//设置字体大小
labelfont = [UIFont fontWithName:[[UIFont familyNames] objectAtIndex:10] size:20];

//创建按钮
UIButton button0 = [UIButton buttonWithType:1];
//设置按钮范围
button0frame = CGRectMake(0, 40, 100, 30);
//设置按钮显示内容
[button0 setTitle:@"矩形左旋转" forState:UIControlStateNormal];
//设置按钮改变后 绑定响应方法
[button0 addTarget:self action:@selector(LeftButtonPressed) forControlEvents:UIControlEventTouchUpInside];

//创建按钮
UIButton button1 = [UIButton buttonWithType:1];
//设置按钮范围
button1frame = CGRectMake(0, 100, 100, 30);
//设置按钮显示内容
[button1 setTitle:@"矩形右旋转" forState:UIControlStateNormal];
//设置按钮改变后 绑定响应方法
[button1 addTarget:self action:@selector(RightButtonPressed) forControlEvents:UIControlEventTouchUpInside];

//创建按钮
UIButton button2 = [UIButton buttonWithType:1];
//设置按钮范围
button2frame = CGRectMake(0, 160, 100, 30);
//设置按钮显示内容
[button2 setTitle:@"矩形上旋转" forState:UIControlStateNormal];
//设置按钮改变后 绑定响应方法
[button2 addTarget:self action:@selector(UpButtonPressed) forControlEvents:UIControlEventTouchUpInside];

//创建按钮
UIButton button3 = [UIButton buttonWithType:1];
//设置按钮范围
button3frame = CGRectMake(0, 220, 100, 30);
//设置按钮显示内容
[button3 setTitle:@"矩形下旋转" forState:UIControlStateNormal];
//设置按钮改变后 绑定响应方法
[button3 addTarget:self action:@selector(DownButtonPressed) forControlEvents:UIControlEventTouchUpInside];
//向view添加
[selfview addSubview:label];
[selfview addSubview:button0];
[selfview addSubview:button1];
[selfview addSubview:button2];
[selfview addSubview:button3];
}
//向左按钮
-(void)LeftButtonPressed{

UnitySendMessage("Cube","MoveLeft","");
}
//向右按钮
-(void)RightButtonPressed{
UnitySendMessage("Cube","MoveRight","");
}
//向上按钮
-(void)UpButtonPressed{
UnitySendMessage("Cube","MoveUp","");
}
//向下按钮
-(void)DownButtonPressed{
UnitySendMessage("Cube","MoveDown","");
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
第三步:修改Bundle Identifier,进行真机测试
到此,代码部分全部搞定。接下来是真机,等待运行
艰难的运行中,大约两分钟
u3d的开机画面出来了,刷一下,进入到了你添加的界面,里面有几个按钮,分别是控制模型旋转的。
此时,看上去一切都很顺路,轻轻的,点一下,其中一个按钮。。。。问题出了。。崩溃。。。
悲剧的崩溃。。。
控制台输出了一大堆错误。
错误如下:
2014-01-09 11:50:55863 ProductName[3340:907] -> registered mono modules 0xfd4610
-> applicationDidFinishLaunching()
-> applicationDidBecomeActive()
Mono path[0] = '/var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed'
Mono config path = '/var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed'
2014-01-09 11:50:57289 ProductName[3340:907] 2
Renderer: PowerVR SGX 535
Vendor: Imagination Technologies
Version: OpenGL ES 20 IMGSGX535-73161
GL_OES_depth_texture GL_OES_depth24 GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_texture_float GL_OES_texture_half_float GL_OES_vertex_array_object GL_EXT_blend_minmax GL_EXT_debug_label GL_EXT_debug_marker GL_EXT_discard_framebuffer GL_EXT_map_buffer_range GL_EXT_read_format_bgra GL_EXT_separate_shader_objects GL_EXT_shader_framebuffer_fetch GL_EXT_shader_texture_lod GL_EXT_texture_filter_anisotropic GL_EXT_texture_storage GL_APPLE_copy_texture_levels GL_APPLE_framebuffer_multisample GL_APPLE_rgb_422 GL_APPLE_sync GL_APPLE_texture_format_BGRA8888 GL_APPLE_texture_max_level GL_IMG_read_format GL_IMG_texture_compression_pvrtc
Creating OpenGLES20 graphics device
Initialize engine version: 421f4 (4d30acc925c2)
Begin MonoManager ReloadAssembly
Platform assembly: /var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/UnityEnginedll (this message is harmless)
Loading /var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/UnityEnginedll into Unity Child Domain
Non platform assembly: /private/var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/MonoSecuritydll (this message is harmless)
Non platform assembly: /private/var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/Systemdll (this message is harmless)
Platform assembly: /var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/Assembly-UnityScriptdll (this message is harmless)
Loading /var/mobile/Applications/AA64800A-19C5-4CC9-8CF9-B00ACD24A100/ProductNameapp/Data/Managed/Assembly-UnityScriptdll into Unity Child Domain
- Completed reload, in 0182 seconds
The referenced script on this Behaviour is missing!

(Filename: Line: 1657)
The referenced script on this Behaviour is missing!

(Filename: Line: 1657)

1、首先在安装盘:\Program Files\Unity\Editor\Data下新建一个文件夹Localization。

2、然后百度下载unity50汉化文件。

3、然后将其放到Localization中。

4、然后打开我们桌面上的unity3D的软件,进入系统。

5、然后在系统中首先我们找到Edit编辑按钮,点击可以看到新d窗。

6、在新d窗中我们找到首选项Preferences。点击这个按钮。

7、然后我们在新d窗中看到Language语言选项按钮,点击语言选项。

8、然后我们可以在里面看到Editor Language选项,点开可以看到chinese。

9、最后我们可以看到我们的UNITY已经完美汉化了。

任何游戏对象在创建的时候都会附带Transform组件,用于储存并 *** 控物体的位置、旋转和缩放。

并且该组件是无法删除的。

Transform面板一共包含3个属性:

Position:位置

Rotation:旋转

Scale:(缩放)

可修改对象的位置、旋转方式、缩放数值

position;世界坐标系位置

localPosition;本地坐标系位置

缩放

localScale;自身缩放

lossyScale;全局缩放

旋转

transformrotation;世界坐标系旋转

transformlocalRotation;本地坐标系旋转

transformeulerAngles;世界坐标系旋转

transformlocalEulerAngles;本地坐标系旋转

欧拉角

构件在三维空间中的有限转动,可依次用三个相对转角表示这三个转角统称为欧拉角。

unity中的欧拉角有两种方式可以解释:

1,当认为顺序是yxz时(其实就是heading - pitch - bank),是传统的欧拉角变换,也就是以物体自己的坐标系为轴的。

2,当认为顺序是zxy时(roll - pitch - yaw),也是官方文档的顺序时,是以惯性坐标系为轴的。后者比较直观一些,但其实两者的实际效果是一样的,只是理解不一样。

欧拉角有两种:

静态:即绕世界坐标系三个轴的旋转,由于物体旋转过程中坐标轴保持静止,所以称为静态。

动态:即绕物体坐标系三个轴的旋转,由于物体旋转过程中坐标轴随着物体做相同的转动,所以称为动态。

使用动态欧拉角会出现万向锁现象;静态欧拉角不存在万向锁的问题

正常状态:三个独立的旋转轴

万向锁:一旦选择±90°作为pitch角,就会导致第一次旋转和第三次旋转等价,整个旋转表示系统被限制在只能绕竖直轴旋转,丢失了一个表示维度。

万向节死锁会导致位置上连续变化,在数值表示上确是非连续的。给定的两个关键帧之间无法平滑过渡。解决方法:可以使用四元数球面线性插值

四元数

爱尔兰数学家William hamilton一直致力于寻找一种方法将复数2D扩展到3D他认为,新的复数应该有一个实部和两个虚部。但是一直没有成功。1843年,他在前往爱尔兰学院演讲的路上,突然意识到应该有三个虚部而不是两个。他把这种新复数类型性质刻在了桥上,这就是四元数。

四元数使用四个数来表达方位,因此命名为四元数用三个数来表达3D方位,一定会导致万向锁的问题。一个四元数包含一个标量分量和一个3D向量分量。通常标量分量为w,向量分量为v或者分开的x,y,z

记法:[w,v][w,(x,y,z)]四元数与复数:复数定义: a+bi, i是所谓的虚数,满足 i的平方等于-1;a是实部,b是虚部。

四元数扩展了复数系统,使用了三个虚部i,j,k一个四元数[w,(x,y,z)]定义了复数 w+xi+yj+zk很多标准复数的性质都能应用到四元数上。更重要的是,和复数来旋转2D中的向量类似,四元数也能用来旋转3D中的向量。

四元数是非常重要的工具类之一。在Unity中所有用到模型旋转的,其底层都是由四元数实现的,它可以精确的计算模型旋转的角度。Quaternion基于复数的表示并不容易被直观地理解,因此没有必要访问或修改单个Quaternion组件(x,y,z,w)只需通过Transform的rotation来实现旋转,或者构造新的旋转,如在两个旋转间平滑地插值

eulerAngles属性返回表示旋转的欧拉角度。表示旋转的角度,顺序依次绕z轴旋转eulerz度,绕x轴旋转eulerx度,绕y轴旋转eulery度范例:创建一个旋转,绕y轴,指定一个30度旋转角

在unity3d中,用四元数来表示旋转,四元数英文名叫quaternion 比如 transformrotation 就是一个四元数,其由四个部分组成

Quaternion = (xi + yj + zk + w ) = (x,y,z,w)

quaternion 中 (x,y,z) 跟旋转轴有关, w 与绕旋转轴旋转的角度有关,因为它们都要经过代数运算才能得出旋转轴和旋转角度  
Unity3D 中 用quaternion 来对一个坐标点进行旋转,我进行的是第2种 *** 作,即对一个向量进行旋转;

首先 ,Quaternion 的基本数学方程为 :

Q = cos (a/2) + i (x sin(a/2)) + j (y sin(a/2)) + k(z sin(a/2))    (a 为旋转角度)
Qw = cos (angle / 2) 

Qx = axisx sin (angle / 2) 

Qy = axisy sin (angle / 2)  

Qz = axisz sin (angle / 2)
我们只要有角度就可以给出四元数的四个部分值,例如我想要让点M=Vector3(o,p,q) 绕x轴顺时针旋转90度;那么对应的quaternion数值就应该为:

Q : Quaternion;

Qx = 1 sin(90度/2) = sin(45度) = 07071

Qy = 0;

Qz = 0;

Qw = cos(90度/2) = cos (45度) = 07071

Q = (07071, 0 , 0 , 07071);

m = Q m;(将点m 绕 x轴(1,0,0) 顺时针旋转了90度)

示例:

using UnityEngine;

using SystemCollections;

class EulerAnglesTest: MonoBehaviour 

{

  public Quaternion rotation = Quaternionidentity;

  public void Awake() {   

     rotationeulerAngles = new Vector3(0, 30, 0); 

    transformrotation = rotation;

 }

}

Translate

移动transform在translation的方向和距离。

SpaceSelf和SpaceWorld

注意,vectorforward和tranformforward区别

DebugLog("");

DebugLog(Vector3forward);

DebugLog(Vector3right);

DebugLog(Vector3up);

DebugLog("");

DebugLog(transformforward);

DebugLog(transformright);

DebugLog(transformup);

Rotate

TransformRotate 旋转

TransformRotateAround 围绕旋转

LookAt

盯着看

transformLookAt(Transform target);

transformLookAt(Vector3 worldPosition);

扩展

transformLookAt(Transform target,Vector3 worldUp);

z轴指向目标后,y轴旋转变换指向由worldUp向量暗示的方向。 如果省略worldUp参数,该函数将使用世界y轴。 worldUp只是一个提示矢量。

Find:通过名字查找子物体并返回它。如果没有查找到子物体名字,将返回null。如果名字包含“/”字符它将向路径一样穿越层次。

GetChild():根据子节点的序列查找子物体。

Transform维护父子关系

Transformroot 根

Transformparent 父级

TransformchildCount 子物体数

TransformSetParent();设置父节点

TransformDetachChildren 分离子物体

坐标系变换

TransformPoint:变换位置从物体坐标到世界坐标

InverseTransformPoint:变换位置从世界坐标到自身坐标

TransformDirection:将一个方向从局部坐标变换到世界坐标方向。

InverseTransformDirection:将一个方向从世界坐标变换到局部坐标方向。

(扩展)矩阵(Matrix)

一个标准的4x4变换矩阵。

一个变换矩阵可以执行任意的线形3D变换(例如,平移,旋转,缩放,切变等等)

并且透视变换使用齐次坐标。脚本中很少使用矩阵:最常用Vector3,Quaternion,而且Transform类的功能更简单。

单纯的矩阵用于特殊情况,如设置非标准相机投影在Unity中,Matrix4x4被Transform,Camera,Material和GL几个函数使用。

worldToLocalMatrix:矩阵变换的点从世界坐标转为自身坐标(只读)。

localToWorldMatrix:矩阵变换的点从自身坐标转为世界坐标(只读)。
DebugLog(tran

sformposition);

DebugLog(transformlocalPosition);

Vector4 vec = new Vector4(transformlocalPositionx,transformlocalPositiony,transformlocalPositionz,1);

DebugLog((transformparentlocalToWorldMatrixvec));

Vector4 vec2=new Vector4(transformpositionx,transformpositiony,transformpositionz,1); 

DebugLog(transformparentworldToLocalMatrixvec2);


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13377401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-24
下一篇 2023-07-24

发表评论

登录后才能评论

评论列表(0条)

保存