Unity3D常用知识点总结

最近找了个U3D实习,把之前的笔记发上来

Unity3D

可以通过将游戏中的物体拖入新键文件夹来重复使用(往往包括该物体用到的模型,动画,贴图,脚本等等)

右上可以调整Debug还是Normal模式

物体

unity3d下

常用物体

  1. cube
  2. cylinder
  3. sphere
  4. plane
  5. quad

prefabs

可以将全部资源整合完后的gameobject打包成prefabs供重复使用,实例和场景中的游戏物体是可以相互apply的。

特殊物体

Terrain(地形)

常用操作:

  1. paint terrain

  2. paint details(刷草)

    在Details页面上可以选择我需要的details(add details mesh是添加3d模型,add … texture是添加2d模型),还可以用这个添加其他地形细节(比如花,瓷砖等等)

  3. terrain setting

  4. 地形刷

    处理地形等等

    其中包含了地形纹理刷,Paint Texture,通过create layer来添加新的纹理(图片网上找即可),通过normal map来将纹理平滑(原理是再贴一层贴图通过光线反射角度处理),对原texture生成成normal map,再将其加入到layer当中。可以通过修改地形layer贴图的张大小来缓解明显一张张的感觉

    注意如果想要设置低海拔,那么需要抬高地形,通过地形刷中的setHeight,设定地形高度后flatten(将地形整平),设置完后,之前刷的地形会被重置,所以先抬地形再刷地形

    可以通过给地形添加layers来选择需要的笔刷(texture+normal map)

  5. 种树(Paint Tree)

    在edit tree中选择对应模型添加即可

保存场景,每一幕都是一个scene,(保存完后需要添加到Building Settings当中)

地形纹理

地形常用属性

wind settings for grass:草所受到的风力大小

Detail Resolution Per:地形每一帧处理的detail,降低这个数据来减少gpu压力

风区

会让地形上的树等物体晃动,常用属性:main(主风力) turbalance(影响程度)

贴图/材质

地形贴图如上所述

快捷创建材质,直接创建一个cube把图片丢到cube上直接生成material,然后再将normal map添加到材质上

默认材质

新建的默认材质可以通过设置颜色,金属质地,光滑,normal map等等

贴图不等于材质!!!贴图是在材质之上的 材质用于表现物体质感,贴图用于处理纹理细节

材质的一些属性说明

Rendering Mode:

物理

可以在project settings当中设置物理属性包括重力系数等等

Rigidbody

U3D中主要通过刚体对游戏物体赋予物理效果,当物体被赋予刚体时,就最好不要使用Transform去改变物体的位置等信息,而是给物体施加力去使之移动。如果物体要受重力支配就必须有刚体

常用属性

is Kinematic true则物理系统失效,由脚本控制运动,否则由物理系统控制运动,可以根据需要在脚本中选择是否开启运动学
Drag/Angular Drag表示移动以及旋转时的空气阻力
Mass质量 (kg)
Constraints各方向力是否开启

刚体往往与碰撞体联合使用,对一个移动中的物体进行触发器控制必须要有刚体组件

碰撞体(Collisions)

在碰撞体(Collider)中需要设置is_trigger才能开启触发器功能,开启触发器功能后就会丧失阻挡能力

对于由各个组件组成的复杂物体,可以给每个组件添加一个碰撞体,此时只在根object上添加刚体

静态碰撞体

只含碰撞体但是不含由刚体,这样的物体可以被碰撞但是不会受力移动。往往用于不动的物体。尽量不改变静态碰撞体的位置等信息,避免性能下降。别的物体碰撞时是不会由摩擦力的(因为没刚体)

物理碰撞体

刚体+碰撞体,用于实现物理效果

运动学刚体+碰撞体,与静态碰撞体类似,差异在于被碰撞的对象会受到物理效果

基本碰撞体

Box,Capsule,Sphere

Mesh Collider

用于复杂物体,根据其mask来设置阻挡,但是仍然优先使用复合碰撞体

碰撞触发规则

两个物体仅仅有碰撞体是不会触发碰撞的,必须其中一个含有刚体

碰撞体触发器规则

除了静态碰撞体,只要设置了触发器,就能够使用trigger相关函数。对于静态碰撞体,如果设置了触发器,除了静态相关的之外,也都能使用trigger。

角色控制器

Character Controller,对于游戏中的角色来说,其物理未必需要那么真实,其有一套自行的移动接口。其不需要刚体也不会从terrain掉下去,自带一个圆锥形的碰撞体,但是他不能闯过静态碰撞体。可以推动其他刚体,但不会因撞击而加速。

RayCast

可以从origin出发射以direction为方向,设定最大距离和碰撞过滤器的激光,可以通过RayCastHit去接受碰撞后信息,将测量得到的距离返回给全局变量使用。注意,激光穿透的物体中必须含有Collider,可以设置LayerMask使RayCast与指定的Layer中的物体发生碰撞。

除此之外还可以通过Ray来生成射线碰撞探测,常用于手游触摸操作测距当中。

可以通过RayCashHit对象,来得到碰撞对象的collider信息,从而得到对方的tag等信息

空间表示

红轴为X 黄轴为Y 蓝轴为Z(左手法则,食指y轴,大拇指x轴,剩下四各z轴)

Vector3 u3d中所有内容都是通过该向量作距离表示,通过magnitude得到模长(两点间距离)

World Space将世界空间中的(0,0,0)作为原点

Local Space将物体自身作为世界空间的原点

旋转

U3D中一共有两种旋转形式,第一种是欧拉角(x,y,z)分别表示绕三个坐标轴旋转多少度,用Vector3即可赋值。第二种是四元组,有以下五种:

  1. LocalEulerAngles,所有的物体会沿着物体本身(或者其父物体)的三个转轴进行旋转
  2. EulerAngles,沿着世界坐标的三个轴旋转
  3. Rotation,用四元组表示的旋转角,以世界坐标为表示

对于欧拉角

不能直接设置欧拉角中单独绕一个轴旋转,会发生失效。也不能设置超过360的旋转,也会失效。此时使用四元组的旋转。

旋转通法

获取方向

U3D中所有物体的Z轴所在方向为面朝方向forward

  1. 向量减法后,通过Vector3.RotateTowards()得到旋转后的中间方向向量
  2. 将向量使用Vector3.Angle()得到欧拉角或者通过Quaternion.LookRotaion()得到四元组
  3. 可以通过对应物体的up,forward,down得到对应物体的坐标方向

使用欧拉角进行旋转

  1. 根据得到的旋转角度生成一个新的Vector3
  2. 选定是根据父亲旋转还是世界坐标旋转
  3. 对应赋值或者使用Rotate(使用后者的时候可以选的按照那个轴进行旋转eg,Rotate())

代码如下

transform.RotateAround(transform.up,angle)

使用四元组进行旋转

​ 差别仅在赋值时使用父或者世界的rotation

代码如下

transform.rotation=Quaternion.LookRotation(当中是Vector3.RotateTowards返回的量)

上述两种方法的差异

欧拉角的旋转遵循左手法则(顺时针),所以当进行逆时针顺转时,会发生旋转角变成一个>180的角,出现问题。而四元组则没有这个问题。所以人物角色进行旋转时优先使用四元组进行旋转

完整旋转过程的例子


动画系统

基础

可以直接在Animation的状态栏下设置需要的动画并调整帧数(ctrl+滑轮调整时间轴)

Animator(控制一组动画)

Animation(控制一个动画)

每一个组件可以绑定一个动画状态控制

关键帧

Animation Clip

U3D可以直接通过Animation窗口去创建动画clip(通过录制的方式)

对于没有添加Animation的物体,使用timeline创建动画,会自动添加一个animatior组件,此时无法通过Animation脚本来控制动画,哪怕之后删除animator直接添加animation。想要用animation来控制动画就必须使用animation添加给物体。(常用于UI动画制作)

通过对物体在Timeline创建各关键帧来录制动画,对于一列物体(包含子物体的物体),可以在修改物体本身在动画中属性变化的同时去修改其子物体的变化。(关键帧上每个结点表示修改的物体属性)

TimeIine:可以通过点击时间刻度来选择时间,其视图有表格和曲线两种视图

表格:每个结点时是对应一个关键帧上的物体属性

曲线:表示每一个属性的变化趋势,注意这种方式下由于每个属性度量不同,可以调整坐标观察

当每新创建一个animation clip时会自动生成一个animation controller

两种方式添加关键帧(record(自动),preview(手动))

record模式下:每改变一个可动画属性,就可以在必要位置生成关键帧。可以拖动关键帧到不同位置,直接修改对应关键帧上数值即可

preview模式下(时间条为蓝色):修改物体属性后,右键add Key来添加关键帧,修改关键帧时需要修改完后add key才能完成,也可以通过拖动关键帧来改变位置

曲线模式下的使用

对于一个动画clip来说,任何可以动画的属性(必须是选择状态下的)都可以显示成一个动画曲线(往往以周期函数形式呈现),在preview模式下双击曲线上任意点都可以形成一个key。在record模式下可以右键添加key

Animator Controllers

主页面左侧的是状态机参数,可以用于动画状态机的输入(float,int,bool,trigger)

通过Animator来控制一连串的Animation并进行状态转换(视作一个状态机)

Animator三个默认状态Entry,Exit,Any State,通过各动画间的连线表示状态转换

Animation State Machines转换

动画间的各个状态是由状态机表示的,可以通过状态参数去控制各个状态机之间的迁移,状态机上的Solo表示如果该迁移执行,那么其他迁移均失效。Mute表示关闭迁移。Mute高优先级。

状态机脚本

在状态机上添加专门用于控制状态机触发效果等等用处的脚本

状态机迁移流程

  1. 得到对应动画机的StateInfo
  2. 根据动画状态的Hash来判断现在处于哪个动画状态
  3. 进入动画状态后,重置状态转换参数
  4. 进一步根据需求进入其他动画状态

注意点

  1. 可以使用计时器对动画的播放进行控制
  2. 注意使用Hash选择进入动画状态时要排除过度状态

子状态机

一个角色动画动作肯能包含多个状态,可以将多个状态包括在一个蓝色框的状态机中,而其中含有多个子状态机,在总状态机中有一个Up Base Layer使得其中子状态机选择与外部那个状态机进行迁移。

Animation Layers

动画层次,用来处理同一时刻同一物体不同部分的动画承现(弓箭边射箭,边移动),通过设置动画物体的Mask。同样可以通过Blending来设置是否其他Layer对当前层次的影响

Sync表示同步动画,表示在不同状态下对某些动画效果的同步复用,需要设置一个动画源,在其上的设置会修改动画源的状态机

反向动力动画(IK)

在已知骨骼位置的情况下给出动画,(关联前向动力动画)可以运用在有明确人形骨骼的任何动画上,往往用来处理角色与物体的触摸与抓取。通过一个脚本作为IKControl来管理动力目标,从而生成动画,绑定在人物上。动力目标往往会设置一个子孩子用来处理抓取目标(Hand Object),其父亲作为面朝目标(Look Object)

Root Transform(根变换)

关联Body Transform(角色重心),身体朝向(由人物T型模型下上身和下身朝向的平均值)

所谓根变化可以理解为角色重心的投影,用来带动GameObject移动(由人物动画来带动人物移动),可以在人形动画的Animation clips当中设置动画对物体位置的影响。

混合树

用于一系列相似动画的转换,但是与状态机迁移不同。用于迁移一系列相似的动画(比如走路与跑步)

可以在Animation Controller页面创建混合树,并在树中添加一系列动画clip

1D混合树是指可以通过一个参数来控制动画,选择左侧的参数来作为动画控制参数,Compute Positions会根据动画的特点选项来调整动画变化的门槛

2D混合树是指可以根据两个参数来控制动画

  1. 2D简单方向适合运动表示不同方向时的动画
  2. 2D任意方向,与上述相比还可适用于同一方向上的不同动画
  3. 2D笛卡尔方向

其2D混合图上点的位置对应1D图上的阈值,X轴位置表示第一个参数值,Y轴位置表示第二个参数值。2D混合图的蓝色表示各动画对面上门槛点的影响力,圆形大小表示混合位置对应各个动画的影响力强度。

人物动画的重定向

可以把一个人形动画绑定到另一个有骨架的物体上

操作步骤如下:

  1. 通过Select选中对应模型,将其的Animation Type设置为人形动画,并且创建骨架,这样之后这个骨架就能使用人形动画了(人形动画与骨架相关,与模型关系不大)
  2. 得到动画,将其类型设置为人形动画,从需要绑定的组件上设置人形骨架
  3. 随后就能够将不同的绑定了骨架的动画添加给该人形模型了

配合Animator组件使用

Animator上选择对应的骨架,并在状态机中添加对应骨架的动画

粒子系统

往往添加到3d object上面

基本属性

duration:发射粒子的持续时间,looping,

prewarm:只能在looping下使用,会预发射粒子 startlifetime:每个粒子的生命周期,这个参数是可以设置成随机数的(曲线表示在x秒发射的粒子生命周期有y秒)

startspeed,startsize,startrotation 这四个start参数都可以有四个类型的设置值

startcolor:开始颜色,可以设置成渐变,常量颜色,以及两者之间(gradient,设置这个模式时,上部分是透明度,下部分是颜色游标)

gravity modifier:重力系数

simulation space:local(发射粒子与发射器对应),world(发射粒子与世界坐标对应)

max particles:一个duration内最多发射粒子数

Emission

rate:每秒发射多少粒子

bursts:表示在duration的时间内每个时间点会发射多少粒子数(注意不能超过总数)

Shape

常用的发射形状:

  1. Sphere: 有两个个巧妙属性:随机方向,随机起始地点
  2. Hemisphere:半球体,属性同上
  3. Cube(锥体):Angle表示斜面与垂直角度, Length表示底面之间的间距,Emit from发射起点
  4. Mesh 由网格来发射粒子,其下的三个选择分别是在Vertex,Edge,Triangle(面)上发射粒子

Velocity over life time

表示生命周期内粒子的速度x,y,z上的分量

同样下面的属性Limit velocity over lifetime表示限制粒子速度

Force over life time

粒子生命周期中的受力情况(三分量)。这里的Space表示坐标相对于世界坐标还是物体本地

Color over lifetime & Color by Speed

都是通过Gradient来设置的,注意Color by speed的速度范围是颜色游标的两个端点

剩下两组Size与Rotation和Color类似

Noise

设置让粒子不规则运动

strength,frequency

粒子的Position,Rotation,Size属性在噪点设置下的随机变化

Collision

type:与粒子碰撞的其他碰撞体类型 plane表示只能与平面发生碰撞,world则表示可以与世界内任何碰撞体发生碰撞

scale plane:碰撞器缩放大小(只有plane下才有),dampen:摩擦力,bounce:弹力,

lifetime loss:生命损失,

Collision直接根据设置即可

Triggers

Sub Emitters

可以在birth,death,collision,trigger等情况下发射子粒子,注意子例子系统必须在当前粒子系统之下

Light

可以给每个小的粒子赋予灯光效果,需要给属性赋予绑在其下的一个Light组件

Ratio:每周期有光效的粒子个数 Range,Intensity的累乘器 Max light最多光源个数

Trails

粒子轨迹效果

Texture Sheet Animation

需要设置Render中的材质球,将材质球上的贴图切片后设置播放顺序来作为粒子效果

Tiles x,y轴切片数

Animation:whole sheet表示经过切割后的所有图片,single row每次一行行播放

frame over time:第几帧中播放第几章图片

Render

Render Mode渲染模式:billboard渲染出来的粒子永远朝向摄像机

​ stretchboard没有正面朝向摄像机的粒子渲染

图形学与渲染

天空盒(skybox)

环境光调整

环境光往往来自于directional light(也可以不要这个)并且受制于skybox

window->rendering->light setting 可以设置环境光

常用属性

Lighting

Reflection

Directional light

光照类型:spot,directional,point,area光源形式

图层(Layers)

类似ps图层,表示3d各物体在画面上渲染的层次,可以通过摄像机调整,越往前的图层,其图层的摄像机渲染优先级越高

后期处理

post_processing(可以直接通过Package Manager下载),相当于给主视角加滤镜

在使用之前要先在project setting中的quality关闭 AA,并关闭游戏中主视角摄像机的MSAA并且defer掉其rendering path,在游戏主视角摄像机下创建一个含有post processing volume的gameobject,并在主视角摄像机上绑定post processing layer。并将后者设置在Post Processing Layer上(注意此时会将子孩子全部都设置到同一层级,可以把要单独列出来的层级再重设置,比如摄像机追踪剑的图层)。

通过给post processing volume添加效果来生成各种后期效果(注意要勾选is globals)

常见设置效果

Depth of Field景深效果

Bloom 泛光

摄像机

可以通过GameObject中的Align view to Selected来使得选中的摄像机指向当前视角位置

多摄像机重叠显示时,只有主摄像机会显示天空盒,其他均设置会depth only才会重叠显示

eg. 3Dui摄像机与主摄像机重叠时

U3D视图窗口中的属性

ClearFlags 决定屏幕留白部分的处理

​ skybox 空白显示背景颜色

​ depth only显示深度

​ dont clear 不清除

Culling Mask 选择要照射的LayerMask,对于一个场景中存在多个摄像机时使用该属性来选择摄像机的分配,并且配合depth使用

Projection 投射方式

​ perspective 透视

​ orthographic 正交 不显示透视效果,往往用于小地图

Size:摄像机视图口大小

Field of view 视野方式,开始渲染到结束渲染的距离

​ Near,Far

Viewport Rect 视口矩形表示摄像机的视图在屏幕上绘制的坐标

LayerMask

用来给物体分层,常用于PostProcessing与RayCast,可以给每一层标数字来识别

多媒体

音频

音频资源导入后需要变成gameobject才能给其他东西使用,必须同时有一个音频和对应的gameobject

UI

UnityEngine.UI

基础

(这里用的是ugui)

这里通过创建一个Canvas来进行ui布局,并在上面添加ui组件。UI Canvas会显示在游戏中的主视角摄像机前。将脚本中需要涉及到的UI组件作为gameobject传递给脚本并根据操作修改。

UI空间坐标

左下角为(0,0)作为Rect的坐标原点

UI层级

越下层的UI组件会越优先渲染

Canvas

所有的UI组件都设置在Canvas上

常用属性:

Canvas Scaler

​ UI Scale Mode: Constant固定,Scale With Screen Size(UI分辨率缩放)

Render Mode

​ Screen Space OverLay 使得UI永远显示在游戏主页面前,无需UI摄像机

​ Screen Space Camera 需要指定专门的UI摄像机

​ World Space 需要指定专门的UI摄像机 可以显示出透视效果

RawImage

UI中的组件图片元素

Anchors:两种模式:位置,stretch(可以用来做遮罩),stretch模式下UI会根据分别率大小自动缩放

在位置模式下可以调整image的大小为相对于原点的位置,在stretch模式下可以调整Image到四边的距离(left,right,top,buttom指的是距离锚点的四边距离)

Image

image和rawimage的区别

image: 使用sprite作为源

rawimage:使用texture作为源

sprite切割技巧

将图片拖入Unity3D后,将图判设置为Sprite,将Sprite Mode改成Mulit,通过Sprite Editor对其进行修改,通过对应窗口中的Slice与Apply来修建图片

Slider

滚动条,由背景,填充,滑块组成。往往可以用来做血条,进度条等。

Button

由Button,Image,以及其子孩子Text组成,可以通过自定义脚本绑定按钮事件。将按钮需要的函数绑定到一个脚本上(返回为空)。然后将脚本拖拽至游戏物体后绑定到按钮下。

normal/highlighted/pressed/selected color

UI动画

UI中也可以设置动画,将动画绑定到UI组件上即可(比如渐入渐出的动画),并通过脚本控制

EventSystem

需要EventSystems Events两个空间

专门用来处理输入事件,游戏对象选中事件以及raycast的管理控制器 核心组件 InputModule和Raycaster

EventTrigger用来接受来自EventSystem的事件,并且为每一个事件添加对应的回调函数,每一帧EventSystem都会检查这些事件。绑定了EventTrigger中的物体会响应所有的事件(与之相关的),哪怕事件不是发在它。所以可以专门开一个Manager对象用来存储这类事件处理

具体的使用方法如下:

  1. 给一物体添加EventTrigger, gameobject.AddComponent()

  2. 创建EventTrigger.Entry表示事件触发器进入,并绑定对应的触发器事件(eventID,也就是触发事件)

    可以直接通过trigger.onEvent(){}去处理回调,比如onPointerClick(){}

    也可通过设置triggers=new List()来创建一个事件列表,使得其响应多个事件

  3. 创建对应的回调函数,并且通过UnityAction把创建的事件赋值给它

    可以使用匿名方法。对于设置了触发器列表的触发器,可以通过Add的方式,设置多种对应方式

  4. 将回调函数绑定给事件

一个使用的例子

//创建一个事件
UnityAction action=new UnityAction(delegate(BaseEventData data){})
EventTrigger.Entry entry=new EventTrigger.Entry();
entry.eventID=Event=EventTriggerType.PointerDown;
entry.callback.AddListener(action);

EventTrigger trigger=AddComponent();
trigger.triggers=new List()
trigger.triggers.Add(entry)

脚本

主要的基类

MonoScript 所有绑定到游戏物体上的脚本必须要继承自MonoScript

ScriptObject 所有仅仅用于数据处理的对象可以使用ScriptObject

基础

常用名称空间

UnityEngine

​ UI

​ AI

新建脚本后默认的两个函数

以下函数根据执行顺序依次排列

void Awake(){}

void onEnabled(){} 每次游戏对象被激活时调用一次

void Start(){} Start和Awake只会在整个生命周期中被调用一次

void FixedUpdate(){}//固定帧更新,往往用于执行物理脚本

void Update(){} //每一帧都会执行该方法,往往用于更新实时数据

void onDisable(){} 每次游戏对象被反激活时调用一次

在脚本中设置public变量可以在u3d中设置对应的属性,当使用static修饰时相当于变成了一个全局变量,其他脚本也可以使用(不过不会再u3d中显示了),往往用于脚本中相互传递值

脚本绑定原则:可以通过创建一个空的gameobject来绑定给中脚本,作为功能总控

实例化问题

两种方法:

1. 直接public GameObject然后把游戏场景中的物体拖到u3d上
  1. 使用prefabs拖到GameObject,或者用资源加载的方式加载模型后使之实例化(不用new,使用Instantiate(obj,pos,rotation,parent.transform),该函数可以指定物体初始化位置transform包括位置和四元组的旋转值),使用Destroy可以删除实例(会引起垃圾回收

如果使用new去实例化gameobject是自带transform的。有一种方法是可以new空的gameobject后一一赋予组件AddComponent。

MonoBehavior

所有继承了这个类的脚本都有如下的属性和方法

gameObject属性可以得到该脚本绑定的游戏对象

U3D中继承

u3d中使用继承,子类的回调函数会覆盖父类的回调函数,除非使用base.function(),C#是单一继承

某些类是另一些类的父类,其中的一些公共函数最好还是设置为virtual(方便组件复用),属性为protected

Application

APP组件

用于游戏程序控制包括退出

常用api

Application.Quit()
Application.targetFrameRate可以用来设置游戏目标帧数

GameObject

自带Transform组件

name游戏组件的名称,往往用于子组件搜索(不用于全局搜索,因为太卡了)

SetActive是否激活物体 而对于组件来说是通过enabled选择是否开启

ToString()返回GameObject的名称

Type GetComponent() 会得到绑定了脚本的游戏物体对应类型的组件,如果游戏物体上绑定了脚本,那可以直接通过该方法得到对应的游戏脚本

Type GetComponentInChildern() 得到物体的子组件中第一个满足对应类型的组件

Type GetComponentsInChildern()如果使用这个函数,可以用foreach循环遍历需要的子组件中复数个需要的组件,这里的遍历类型可以是Transform

Type GetComponentInParent()

上述方法可以有this关键字调用

可以使用new关键字来创建一个空的GameObject

Destroy(gameobject) 销毁游戏对象

可以通过给特定的游戏对象绑定一个tag,并使用,如果想要动态地添加tag给物体,必须现在U3D中设置

GameObject.Find(“str”) 可以通过名称或者路径查找游戏对象,如果路径中的任何一个节点将设置成false,那么会找不到,无法查找隐藏对象

transform.Find(“str”) 与之相比的区别在于 如果隐藏对象的根节点是可见的,那么就能够找到(路径当中存在false对象也可以查找到

FindGameObjectWithTag(“tag”)//这是一个GameObject类的静态函数,返回一个gameobject

FindGameObjectsWtihTag(“tag”)//返回一个gameobject []

可以通过一个gameobject对象来动态添加Component

比如 t.gameObject.AddComponent() 会返回添加了的组件

使用u3d中gameobject中内容时注意判空

Compoment

enabled属性表示是否启用该组件

gameobject可以得到该组件对应的游戏物体,可以再设置SetActive

Transform与Vector3

在脚本中往往用transform去遍历,搜索需要的类,并且可以用这个类作为从游戏场景中拖入物体的类型

常用的一些Transform带的搜索函数

Find("name")//返回名为name的子孩子,注意返回类型是Transform
Translate(vector3)//相当于当前位向量+vector3所指向的方向向量,用于物体移动
transform.tag可以得到对应物体的tag

unity3d中向量

Vector3 Vector2

常用属性和方法

//Vector3相关
Distance(pos1,pos2)返回float表示两点距离
Magnitutde(vector3)返回模长

//移动相关
Vector3.MoveTowards(current,target,speed)//current至target方向在速度speed下移动的距离

//旋转相关
//得到旋转量
Vector3.RotateTowards(forward,target,speed,0.0f)//从forward旋转到target,在speed速度下旋转得到的方向向量,需要用下一个函数转换成旋转角
Vector3.Angle(forward,target)//返回旋转所需欧拉角
Quaternion.LookRotation(target)//返回旋转所需四元组
    
//旋转
rotation=Quaternion.Euler(new vector3(x,y,z))//四元组表示旋转角
Rotate(x,y,z)//以默认世界坐标为参考,旋转到分别旋转x,y,z旋转,也可以直接指定向量,也可以直接设置绕某个轴旋转多少度
localEulerAngles//本地欧拉角
eulerAngles//世界坐标欧拉角

Quaternion.LookRotation(Angles)//将旋转角度转化成四元组

//坐标旋转相关 , 存疑
transform.TransformPoint(x,y,z) 可以将物体(子物体)的相对坐标变成世界坐标
transform.TransformDirection(x,y,z)自身相对于本地向量方向转换成世界方向向量

Time

时间控制脚本

常用属性和方法

Time.deltaTime 每帧固定时间,可以用该属性去监控帧数,所有动画效果都要乘上这个参数(比如移动效果,每一帧移动距离=该参数*速度),这样设置的动画会平滑很多.用法往往是每帧时间相加得到的一个数值作为频率参数值,还可以用于计时器
Time.time 游戏进行实际时间从0开始,往往可以用来生成随机数

Camera

Camera.main.ScreenPointToRay(vector)可以根据摄像机顶点位置与指定位置得到一个射线,往往用在手游中测距得到位移与RayCast联用。

CharacterController

角色控制器自带了一套用于控制角色移动的属性和方法,如下

Move(vector3)//使用这个函数时需要先把角色面朝的方向向量转换成世界向量

多媒体

音频

AudioClip表示多媒体音频资源

AudioSource表示多媒体音频控制器,通过设置AudioClip来进行播放

触发器相关

常用方法

onTriggerEnter(Collider other) onTriggerExit(Collider other)

当打开 IsTrigger时会启动触发器,other表示的是与所绑定对象碰撞的对象的碰撞器

onBecomeInvisible()//当物体离开渲染可视范围后会触发

输入相关

可以通过edit中project setting的input去添加需要的按键

鼠标

常用方法

OnMouse Down Drag Enter Exit Over Up UpAsButton

鼠标如果在绑了该脚本的Object上做出对应操作的话会触发上述函数

如果要按下鼠标后操作的话,同样使用

Input.GetKeyDown(KeyCode.MouseX) X表示了具体是鼠标那个按键

Input.GetKeyUp()

Input.GetButtonDown() 其中的参数表示了Input管理器中的内容

Input.mousePosition得到鼠标位置,手机下则是触摸位置

键盘

Input.GetKeyDown(KeyCode.X) X表示键盘上的按键

动画相关

协程

StartCoroutine(函数名称),往往会传递一个返回IEnumerator的迭代器,该迭代器实现一系列动作,可以通过返回**yield return new WaitForSeconds()**在完成一套动作后返回原函数进行操作后再进行动作(比如执行一套连招等的一系列动作)。需要注意使用这个对象进行协程跳出后,会接着StartCoroutine之后的代码继续运行

当使用yield返回后,协程会返回调用它的位置之后的代码,等待时间过后再返回协程运行。

void Start()
{
    StartCoroutine(function()) //括号不能省去,调用的是迭代器方法而不是迭代器名称
}
IEnumerator function(){
    ...;
    yield return new WaitForSeconds();//有点js中回调函数的意思
    ...
}

可以通过标志位(比如时间的记录)控制协程中交互过程的流畅性,对应有StopCoroutine(函数名称)用于停止协程

往往使用协程来作时间控制,比如等待sql数据加载完毕后再运行,使用标志控制自旋来控制阻塞协程运行

IEnumerator Loading()
{
    while(manager.instance.is_connected==false)
        yield return new WaitForSecond(1);//必须等待1s执行,不能直接无限循环,否则会超出内存限制
    //after do something
}

除了自旋之外,还可以递归协程起到连续调用

Mecanim系统脚本控制

状态迁移

通过StateInfo来得到动画机的当前状态,并根据需要在Update函数中对每一个状态机设置进入条件,相关联的方法如下:

AnimatorStateInfo//动画状态机状态类 这个类要在update里面获取才有效
GetCurrentAnimatiorStateInfo(num)//num表示layer的编号,这个函数需要在Update里面调用
stateinfo.fullPathHash//某一状态机在layer层级的路径
stateinfo.normalizedTime//该属性>1表示动画播放结束
Animator.StringToHash("Layer.State")//可以把状态机转换为对应的hashcode
IsInTransition(num)//表示是否在第num层的过度状态中

UI

需要UnityEngine.UI空间

对于UI组件其空间大小变化使用的是RectTransform

Slider

value属性表示当前Slider数值,可以设置Slider数值的大小

Text

Text是可以使用富文本的,可以通过标签来给文本修饰

常用标签

 str color>
<b>strb>
<i>stri>

Button

通过得到Canvas中的Button组件,也可以进行事件添加(往往使用无返回值的匿名函数)

btn.onClick.AddListner(delegate(){
	//sth
});

EventSystem

using UnityEngine.Events
using UnityEngine.EventSystems

常用接口

UnityAction action=new UnityAction(func)//用于绑定Event处理函数的事件,这个泛型往往用BaseEventData表示基础数据类,func为回调函数
EventTrigger.Entry entry=new EventTrigger.Entry()//事件触发器
entry.eventID=EventTrigggerType.type//绑定事件
entry.callback.AddListener(action)//绑定回调函数

消息传递机制

可以从一个脚本中调用另一个脚本中的函数

SendMessage(method,parm,SendMessageOptions)

可以给同一游戏物体下的所有MonoBehavior类下的method方法传递一个参数并且调用该函数,往往用于跨脚本方法调用(如果组件的setActive为false那么就无法调用了)

场景

在building中可以对场景进行编号,使得方便进行场景切换

using UnityEngine.SceneManagement

SceneManager.LoadScene()可以用于加载场景

SceneManager.GetActiveScene().name得到当前激活场景的名称,可用于加载场景

U3D内置常用修饰器(c#特性)

[RequireComponent(typeof(CLASS))]

//表示使用该脚本的Object必须包含CLASS类对象,没有就自行添加一个
[SerializeField] 用于序列化字段使得脚本中的private变量也可以在视窗中显示醋回来,序列化的字段会在系统中被二进制存储
[System.Serializable]修饰类时,可以序列化类中的公共字段使得在主脚本类中声明该类变量时可以在U3D中显示其字段
[AddComponmentMenu("xxx")]可以把脚本添加到Componment中
[ContextMeun("item")]可以在脚本右上的设置栏里面手动运行该方法
void funtion(){}
[Range(a,b)]用于修饰字段来限制字段范围

游戏AI初步

Navagation

window->ai->Navagation可以在窗口中选择导航栏,进行参数bake显示出能够自动寻路的地区(蓝色地区),这是一个U3D自己提供的寻路功能

给对应的物体添加Nav Mesh Agent,表示寻路管理器。

常用属性:

Radius

Height

Base offset

speed

angular speed

acceleration

stopping distance 停止距离

auto braking :自动减速,减轻惯性影响

脚本相关

需要UnityEngine.AI组件,通过NavMeshAgent去管理自动寻路,得到该对象后通过api来寻路,常用方法如下

SetDestination(Vector3 pos)
Stop()
ResetPath()重置路线,用于停止寻路
Resume()重新开始移动
Wrap(Vector3 pos)瞬间移动
destination 目标点
nextPosition 下一个位置(这个属性会使物体瞬移)nextDestination 这个属性会使物体移动过去
remainingDistance 与目标点的距离

资源调用

standard assets(注意有些接口与之前的内容有不同需要修改)

tree

food steps

动态方法使用资源

以下两种都是IO方法

IO函数

Resources.Load(“name”) 通过该函数加载Resources文件下的资源但是需要通过Instantiate实例化,

上述两种方法的一种结合用法,动态加载资源来生成模型达到解耦目的

GameObject obj=Resources.Load("url");//使用Resources下的相对路径
model=(GameObject)Instantiate(obj,pos,angle)//不管是什么资源加载完后都要Instantiate

数据包方法

Asset Bundle

Unity开发辅助

UnityEditor

可以通过该包中的相关API简化U3D的使用,比如自动对导入模型生成prefabs等等

ScriptObject 无法附加到对象上,使数据独立于游戏对象上的一种脚本格式。这种往往用于编写Editor脚本

常用的特性与类

[MenuItem("url")] //可以把静态函数变成某一个页面上的功能,添加了这个后可以在U3d顶部看到添加的功能
static void CreatePathNode(){} //该函数是没有参数的

Selection //专门用于指向当前选择的物体,常用的静态变量:
activeGameObject
activeTransform
activeObject
GetTransforms(SelectionMode)

SelectionMode


所有修改与附加Editor的脚本需要添加到一个指定的Editor文件夹下

Gizmos

这个方法可以让游戏中的EmptyObject可视化显示在Scene中,通过设置一张图片,流程如下:

  1. 在根目录下新建一个Gizmos的文件夹(必须是这个名称),其中放入需要的图片

  2. 在对应得object脚本上添加

    void onDrawGizmos(){
        Gizmos.color=Color.xxx;//设置绘图颜色
    	Gizmos.DrawIcon(vector3,"png/jpg...",true);
        Gizmos.DrawLine(vector3,vector3);//第一个坐标与第二个坐标的连线
    }
    
    

自定义编辑器模块

可以把自定义的编辑器脚本放在Editor文件夹中,从而实现一个自定义的界面效果

安卓相关

鼠标点击相当于触摸

优化问题

u3d中使用Instaniate及Destroy进行对象的实例化与销毁。但是对象的销毁是由C#的GC自行完成的,频繁的开辟空间与销毁对象会导致性能的下降。解决方法

  1. 每隔一段时间手动使用System.GC.Collect()进行内存回收,或者在游戏加载,删除时进行内存回收。
  2. 使用对象池,预先加载一些游戏对象,使用时先去对象池中取对象。如果不够再进行原生的开内存方法。对象池插件由poolboss,poolmanager等等,也可以自己实现。

调试

Debug.Log("")控制台输出

u3d内嵌Sqlite

需要在Asset下新建Plugins文件夹其中放置三个文件

两个u3d系统文件Mono.Data.Sqlite.dll,System.Data.dll,一个sqlite.dll

sqlite配合sqlite

SQLite .db文件路径所在位置必须是StreamingAssets

版本控制相关

使用SourceTree软件可视化使用gitflow工作流,Unity3D中只需要把Assets与ProjectSettings两个文件夹与其.gitignore文件上传到github即可。clone下来后直接用unity打开项目就能运行了。

你可能感兴趣的:(Unity3D)