Unity入门教程

Unity入门

Unity脚本基础

Unity脚本基本规则

Unity脚本生命周期函数

Inspector窗口可编辑的变量

Mono中的重要内容

Unity重要组件和API

最小的单位GameObject

时间相关Time

1、时间缩放比例 Time.timeScale

// 时间暂停
Time.timeScale = 0;
// 时间恢复
Time.timeScale = 1;
// 2倍速
Time.timeScale = 2;
// 0.1倍速
Time.timeScale = 0.1;

2、帧间隔时间

帧间隔时间表示最近的一帧花费的时间,单位:秒

  • 受到时间缩放(Time.timeScale)影响的帧间隔时间 deltaTime
Time.deltaTime
  • 不受时间缩放(Time.timeScale)影响的帧间隔时间 unscaledDeltaTime
Time.unscaledDeltaTime

帧间隔时间主要用于计算位移,需要根据需求选择使用受时间缩放影响的帧间隔时间还是不受时间缩放影响的帧间隔时间。比如,如果在时间暂停(即Time.timeScale = 0)的情况下,游戏暂停不动就选择受时间缩放影响的帧间隔时间(deltaTime),如果游戏正常运行,就选择不受时间缩放影响的帧间隔时间(unscaleDeltaTime)
本质上:

Time.deltaTime= Time.unscaledDeltaTime * Time.deltaTime;

3、游戏开始到现在的时间

主要用来单机游戏的计时

  • 受到时间缩放(Time.timeScale)影响的游戏开始到现在的时间 time
Time.time
  • 不受时间缩放(Time.timeScale)影响的游戏开始到现在的时间 unscaledTime
Time.unscaledTime;

4、物理帧间隔(FixedUpdate)时间

  • 受到时间缩放(Time.timeScale)影响的物理帧间隔时间 fixedDeltaTime
Time.fixedDeltaTime
  • 不受时间缩放(Time.timeScale)影响的物理帧间隔时间 fixedUnscaledDeltaTime
Time.fixedUnscaledDeltaTime

5、帧数 frameCount

表示从开始到现在跑了多少帧

Time.frameCount

必不可少的Transform

1、位置和位移

2、角度和旋转

角度相关
相对世界坐标系的角度 eulerAngles
Vector3 angle = this.transform.eulerAngles;
相对父对象坐标系的角度 localEulerAngles
Vector3 angle = this.transform.localEulerAngles;
设置角度

设置角度和设置位置一样,不能单独设置其x、y、z的值,需要整体改变。
如果希望改变的角度是Inspector面板上显示的内容,便是改变相对父对象坐标系的角度值

this.transform.localEulerAngles = new Vector3(0, 10, 0);
旋转相关
自转
  • 每个轴具体旋转多少度
public void Rotate(Vector3 eulers, [DefaultValue("Space.Self")] Space relativeTo);

第一个参数表示旋转的角度,第二个参数默认是相对于自身坐标系,如果是相对于世界坐标系需要传入Space.World

// 每秒沿自身坐标系的y轴旋转10度
this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime);
// 每秒沿世界坐标系的y轴旋转10度
this.transform.Rotate(new Vector3(0, 10, 0) * Time.deltaTime, Space.World);
  • 相对于某个轴旋转多少度
public void Rotate(Vector3 axis, float angle, [DefaultValue("Space.Self")] Space relativeTo);

第一个参数表示沿哪个轴旋转,第二个参数表示沿该轴旋转的角度值,第二个参数默认是相对于自身坐标系,如果是相对于世界坐标系需要传入Space.World

// 沿自身坐标系的y轴每秒旋转10度
this.transform.Rotate(Vector3.Up, 10 * Time.deltaTime);
// 沿世界坐标系的y轴每秒旋转10度
this.transform.Rotate(Vector3.Up, 10 * Time.delaTime, Space.World);
公转
public void RotateAround(Vector3 point, Vector3 axis, float angle);

第一个参数表示绕哪个点公转,第二个参数表示绕该点的哪个轴公转,第三个参数表示公转的角度值

// 沿世界坐标系下的原点的y轴每秒旋转10度
this.transform.RotateAround(new Vector3(0, 0, 0), Vector3.Up, 10 * Time.DeltaTime);

缩放和看向

父子关系

1、获取和设置父对象
  • 获取父对象
this.transform.parent
  • 设置父对象
this.transform.parent = 父对象;
// 或者
this.transform.SetParent(父对象);
// 将父对象这是为null时,该对象与其父对象脱离父子关系,被放在根节点下
this.transform.parent = null;
// 第一个参数为父对象
// 第二个参数为是否保持其世界坐标的信息(位置、旋转、缩放)
// 设置为true,会保持世界坐标系下的信息,会和父对象进行计算,得到本地坐标系的信息
// 设置为false,不会保持世界坐标系下的信息,会直接将世界坐标系下的信息赋值到本地坐标系下
public void SetParent(Transform parent, bool worldPositionStays);
2、断绝和自己所有子节点的父子关系

当与自己所有子节点断绝父子关系后,所有的子节点被放在根节点下,子节点和孙节点之间的父子关系保持不变

this.transform.DetachChildren();
3、获取子对象

通过transform获取子对象是可以找到失活的子对象的。但是通过GameObject的获取是获取不到失活的对象。

按层级路径查找子对象
this.transform.Find("层级路径")

在这里插入图片描述

// 查找son1
this.transform.Find("son1");
// 查找son1_1
this.transform.Find("son1/son1_1");
遍历所有子对象

(1)获取所有子对象的个数 childCount
childCount只将儿子计算进去,孙子及以下辈不计入
(2)获取对应层级的子对象 GetChild(层级)
层级从0开始,按照Hierarchy窗口由上到下依次增大
如果传入的层级大于等于childCount时,会报错

for(int i = 0; i < this.transform.childCount; i ++)
{
	Transform child = this.transform.GetChild(i);
	Debug.Log(child.name);
}
4、子对象的操作
判断自己的爸爸是谁
this.transform.IsChildOf(判断对象);
获取自己的序号
this.transform.GetSiblingIndex();
把自己设置为第一个儿子
this.transform.SetAsFirstSibling();
把自己设置为最后一个儿子
this.transform.SetAsLastSibling();
把自己设置为指定序号的儿子

如果传入的序号不在范围内,不会报错,会直接设置成最后一个序号(例如传入-1或者很大的数,该对象会被设置为最后一个序号)

this.transform.SetSiblingIndex(序号);

坐标转换

Input和Screen

输入相关Input

输入相关的内容肯定是写在Update生命周期函数中

鼠标在屏幕上的位置 Input.mousePosition

屏幕坐标系的原点是在屏幕的左下角,往右是x轴的正方向,往上是y轴的正方向

public static Vector3 mousePosition { get; }
检测鼠标输入 GetMouse

0代表左键,1代表右键,2代表滚轮

鼠标按下一瞬间 GetMouseButtonDown
public static bool GetMouseButtonDown(int button);
鼠标抬起一瞬间 GetMouseButtonUp
public static bool GetMouseButtonUp(int button);
鼠标长按 GetMouseButton

长按时一直执行

public static bool GetMouseButton(int button);
检测键盘输入 GetKey

一般使用KeyCode来表示键盘的按键,也可以传入按键的名字,但是不能传入大写字母,比如键盘的A键,只能传入"a",传入"A"会报错。

键盘按下一瞬间
public static bool GetKeyDown(KeyCode key);
键盘松开一瞬间
public static bool GetKeyUp(KeyCode key);
键盘一直按下

长按时一直执行

public static bool GetKey(KeyCode key);
检测默认轴的输入 GetAxis

Edit–>Project Settings–>Input Manager
在这里插入图片描述

键盘A、D按下时,返回-1到1之间的数值

按下A键后,从0一直变到-1,松开恢复成0
按下D键后,从0一直变到1,松开恢复成0

float value = Input.GetAxis("Horizontal");
键盘S、W按下时,返回-1到1之间的数值

按下S键后,从0一直变到-1,松开恢复成0
按下W键后,从0一直变到1,松开恢复成0

float value = Input.GetAxis("Vertical");
鼠标横向移动时,返回-1到1(从左到右)

注意:鼠标不需要按下

float value = Input.GetAxis("Mouse X");
鼠标竖向移动时,返回-1到1(从下到上)

注意:鼠标不需要按下

float value = Input.GetAxis("Mouse Y");
GetAxisRaw方法

GetAxisRaw方法使用方式跟GetAxis一样,区别是其返回值只会返回-1、0、1三个值,不会出现中间值。

其他
是否有任意键或者鼠标长按 Input.anyKey
public static bool anyKey { get; }
是否有任意键或者鼠标按下 Input.anyKeyDown
public static bool anyKeyDown { get; }
这一帧的键盘输入 Input.inputString
public static string inputString { get; }
手柄输入相关
得到连接的手柄的所有按钮的名字 Input.GetJoystickNames
public static string[] GetJoystickNames();
检测某一个手柄按键按下 Input.GetButtonDown
public static bool GetButtonDown(string buttonName);
检测某一个手柄按键松开 Input.GetButtonUp
public static bool GetButtonUp(string buttonName);
检测某一个手柄按键长按 Input.GetButton
public static bool GetButton(string buttonName);
移动设备触摸相关
获取触摸信息 Input.touchCount 、Input.touches
// 触摸手指的数量
if(Input.touchCount > 0)
{
	// 获取第一个触摸对象
	Touch t1 = Input.touches[0];
	// 触摸点的位置
	print(t1.position);
	// 相对于上一帧触摸位置的变化
	print(t1.deltaPosition);
}
是否启用多点触控 Input.multiTouchEnabled
public static bool multiTouchEnabled { get; set; }
陀螺仪(重力感应) Input.gyro
是否开启陀螺仪 Input.gyro.enabled

必须开启陀螺仪才能正常使用

Input.gyro.enabled = true;
重力加速度向量 Input.gyro.gravity
旋转速度 Input.gyro.rotationRate
陀螺仪当前旋转的四元数 Input.gyro.attitude

可以用这个角度信息来控制场景上一个3D物体在受到重力音响时,跟随手机的旋转而运动。

屏幕相关Screen

静态属性
常用
当前屏幕分辨率 Screen.currentResolution

在这里插入图片描述
width:显示器(设备)分辨率宽度
hgith:显示器(设备)分辨率高度
refreshRate:显示器刷新频率

  • 屏幕窗口当前宽高 Screen.width Screen.height
    Screen.width:窗口分辨率宽度
    Screen.height:窗口分辨率高度
    在UnityEditor中,Screen.width和Screen.height可能跟Resolution.width和Resolution.height不一致(在Editor中,Resolution.width和Resolution.height表示显示器的分辨率,而Screen.width和Screen.height则是Game窗口的分辨率大小)。但是如果是在真机上的全屏游戏,这两个的值是一致的。
屏幕休眠模式 Screen.sleepTimeout

在这里插入图片描述

不常用
运行时是否全屏 Screen.fullScreen
全屏模式 Screen.fullScreenMode
ExclusiveFullScreen:独占全屏
FullScreenWindow:全屏窗口
MaximizedWindow:最大化窗口
Windowed:窗口模式
移动设备屏幕转向相关

(1)允许自动旋转为左横向,Home键在左

Screen.autorotateToLandscapeLeft = true;

(2)允许自动旋转为右横向,Home键在右

Screen.autorotateToLandscapeRight = true;

(3)允许自动旋转到竖向,Home键在下

Screen.autorotateToPortrait = true;

(4)允许自动旋转到反竖向,Home键在上

Screen.autorotateToPortraitUpsideDown = true;

(5)指定屏幕显示方向 Screen.orientation
ScreenOrientation.AutoRotation:可以自动旋转
ScreenOrientation.Landscape:只能横向旋转
ScreenOrientation.LandscapeLeft:只能水平向左(Home键在左)
ScreenOrientation.LandscapeRight:只能水平向右(Home键在右)
ScreenOrientation.Portrait:只能竖向旋转
ScreenOrientation.PortraitUpsideDown:只能反竖向(Home键在上)
在这里插入图片描述

静态方法

设置分辨率 Screen.SetResolution(宽度, 高度, 是否全屏)
一般在移动设备上不使用这个方法,在PC是可以使用。

必不可少的Camera

Camera可编辑参数

1、Clear Flags 如何清除背景
  • skybox 渲染天空盒 一般用于3D游戏
  • Solid Color 使用颜色填充空白区域 一般用于2D游戏
  • Depth Only 多个摄像机渲染时 只画Culling Mask指定层级的物体,空白内容的部分使用透明替代
  • Don’t Clear 不移除,覆盖渲染 一般不选
2、Culling Mask 选择性渲染部分层级
3、Projection 摄像机透视方式
  • Perspective 透视模式(默认) 正常眼睛看到的效果 近大远小 主要用于3D游戏
    (1)FOV Axis:视场角的轴
    (2)Field of View:视口大小,默认值为60度
    (3)Physical Camera:物理摄像机 勾选后可以模拟真实世界中的摄像机,焦距、传感器尺寸 透视移位等
    1)Focal Length:焦距
    2)Sensor Type:传感器类型
    3)Sensor Size:传感器尺寸
    4)Lens Shift:透镜移位
    5)Gate Fit:闸门配合
  • orthographic 正交摄像机 没有透视效果,主要用于2D游戏
    1)size:摄制范围
4、Clipping Planes 裁剪平面距离

超出近平面和远平面之间的物体才能被摄像机渲染

5、Viewport Rect 视口范围

屏幕上将绘制该摄像机视图的位置,主要用于双摄像机游戏,0-1相当于宽高百分比

6、Depth 渲染优先级

值越小越先渲染 在场景中有多个摄像机的情况下生效

7、Rendering path 渲染路径
8、Target Texture 渲染纹理

可以把摄像机画面渲染到一张图上,主要用来制作小地图

9、Occlusion Culling 是否启用剔除遮挡

被挡住的模型不被渲染

10、Allow HDR 是否允许高动态范围渲染
11、Allow MSAA 是否允许抗锯齿
12、Allow Dynamic Resolution 是否允许动态分辨率呈现
13、Targe Display 显示在哪个显示器

Camera代码相关

重要的静态成员
获取摄像机
  • 获取主摄像机

在这里插入图片描述

// 使用这种方式获取主摄像机,需要保证场景中有个tag为MainCamera的摄像机,如果场景中没有tag为MainCamera的摄像机,该静态成员获取的值为null
Camera.main
  • 获取摄像机的数量
Camera.allCamerasCount
  • 获取所有的摄像机
Camera[] allCamera = Camera.allCameras;
渲染相关委托
  • 当摄像机剔除前的委托
Camera.onPreCull += (camera) => {
};
  • 摄像机渲染前处理的委托
Camera.onPreRender += (camera) => {
};
  • 摄像机渲染后的委托
Camera.onPostRender += (camera) => {
};
重要的成员
  • Camera组件在Inspector界面中能看到的参数都可以通过Camera中获取到
    例如:
// 获取主摄像机的深度值
int depth = Camera.main.depth;
  • 世界坐标转屏幕坐标
Vector screenPos = Camera.main.WorldToScreenPoint(世界坐标);

screenPos.x代表屏幕上的x坐标,screenPos.y代表屏幕上的y坐标,screenPos.z代表在3D空间中,该位置距离摄像机的z方向的距离

  • 屏幕坐标转世界坐标

Vector3 v = Input.mousePosition;
// !!!!!!注意:这里之所有要改变z轴的值,是因为,屏幕坐标的z值表示该位置距离摄像机的z方向的距离,如果不改的话,z的值默认为0,转换过去的得到的世界坐标系的点,永远是一个点,可以理解为视口相交的点,如果改变了z值,那么转换过去的世界坐标的点就相当于摄像机前方多少单位的横截面上的世界坐标点
v.z = 5;
Vector3 worldPos = Camera.main.ScreenToWorldPoint(v);

Unity核心系统

光源系统

光源组件

Type 光源类型
Spot 【实时光源】聚光灯
Range 发光距离
Spot Angle 光锥角度
Directional 【实时光源】方向光
Point 【实时光源】点光源
Area 【烘焙光源】范围光
Color 光源颜色
Mode 光源模式
Realtime 实时光源

每帧实时计算,效果好,性能消耗大

Baked 烘焙光源

事先计算好,无法动态变化

Mixed 混合光源

预先计算+实时计算

Intensity 光源亮度
Indirect Multiplier 改变间接光的强度

低于1,每次反弹会使光变暗
大于1,每次反弹会使光更亮

Shadow Type 阴影类型
NoShadows 关闭阴影
HardShadows 生硬阴影(效果较差 但是性能消耗较少)
SoftShadows 柔和阴影(效果最好的阴影)
RealtimeShadows
Strength 阴影强度:阴影暗度0-1之间,越大越黑
Resolution 阴影贴图渲染分辨率:越高越逼真,性能消耗越高
Bias 阴影离光源的距离
Normal Bias 引用投射面沿法线收缩距离
Near Panel 渲染阴影的近裁剪面
Cookie 投影遮罩

主要用于聚光灯 用贴图实现各种不同效果的聚光灯

Cookie Size

方向光,投影遮罩的大小,因为方向光一般不会使用投影找找,所以该参数一般不用

Draw Halo 球形光环开关 类似光晕效果
Flare 耀斑 一般用于方向光

耀斑资源创建 Create–>Lens Flare
默认在Game窗口中不会显示效果,Scene窗口可以显示,如果要在Game窗口中也显示耀斑效果,需要在光源组件上添加Flare Layer脚本

Render Mode 光源渲染模式
Auto:运行时确定
Important:逐像素光源
Not Important:逐顶点光源
Culling Mask 剔除遮罩层

决定那些层的对象接受该光源的影响

Lighting Setting面板

Window–>Rendering–>Lighting Settings

Environment
Skybox Material 天空盒材质

创建天空盒材质:Create–>Material 选择Skybox Shader

Sun Source 太阳来源

不设置会默认使用场景中最亮的方向光代表太阳

Environment Lighting 环境光设置
Source 环境光光源颜色

1)Skybox 天空盒材质作为环境光颜色
2)Gradient 可以为天空、地平线、地面单独选择颜色 和它们之间混合
3)Color 指定颜色作为环境光光源颜色

Intensity Multiplier 环境光亮度
Ambient Mode 全局光照模式

只有启用了实时全局和全局烘焙时才有用
1)Realtime 已启用
2)Baked 烘焙

OtherSettings
Fog 雾开关
Color 雾颜色
Mode 雾的计算模式

1)Linear 随距离线性增加
start:离摄像机多远开始有雾
end:离摄像机多远完全遮挡
2)Exponential 随距离指数增加
Density 强度
3)Exponential Squared 随距离比指数更快地增加
Density 强度

Density 强度
Halo Texture 光源周围的光环纹理
Halo Strength 光环强度
Flare Fade Speed 耀斑淡出时间
Flare Strength 耀斑强度
Spot Cookie 聚光灯剪影纹理

物理系统之碰撞检测

刚体 Regidbody

碰撞产生的必要条件是两个物体都有碰撞器且至少有一个物体有刚体

Mass 质量

默认为千克 质量越大惯性越大

Drag 空气阻力

移动对象时受到的阻力大小 为0表示没有空气阻力

Angular Drag 旋转阻力

旋转对象时受到的阻力大小 为0表示没有空气阻力
例如一个刚体碰撞另一个刚体时,由于力的作用会导致两个碰撞的刚体边移动边旋转。当Angular Drag的值很大时,刚体会在段时间内停止旋转

Use Gravity 是否受重力影响
Is Kinematic 是否不受物理引擎驱动

如果启用此选项,则对象将不会被物理引擎驱动,只能通过Transform对其进行操作。

Interpolate 插值运算

让刚体物体运动更平滑
之所以刚体物体在力的作用下能够平滑运动,那是因为引擎的物理帧频默认值很小,每一物理帧计算物体的位置,肉眼看不出问题,但是如果手动将物理帧频调低,则会出来物体运动时的一顿一顿的现象。
物理帧频设置:Edit–>Project Settings–>Time–>Fixed Timestep
在这里插入图片描述

None 不应用插值运算(默认)
Interpolate 根据前一帧的变换来平滑

在物理帧频过小是,可以通过该方式平滑每物理帧之间的物体的位置变换。

Extrapolate 根据后一帧的变换来平滑

在物理帧频过小是,可以通过该方式平滑每物理帧之间的物体的位置变换。 一般使用Interpolate

Collision Detection 碰撞检测模式

用于防止快速移动的对象穿过其他对象而无法检测到碰撞的问题
性能消耗 Discrete < Continuous < Continuous Speculative < Continuous Dynamic

Discrete 离散检测(默认)
Continuous 连续检测
Continuous Dynamic 连续动态检测
Continuous Speculative 连续推测检测

两物体相互碰撞,不同的碰撞检测模式下最终采用的碰撞检测模式

Constraints 对刚体运动的限制
Freeze Position 对位置的约束

勾选x、y、z表示在力的作用对对应轴的坐标不会发生变化

Freeze Rotation 对旋转的约束

勾选x、y、z表示在力的作用对对应轴的旋转不会发生变化

碰撞器 Collider

碰撞器表示物体的物理形状

3D碰撞器种类
盒状碰撞器 Box Collider
球状碰撞器 Sphere Collider
胶囊碰撞器 Capsule Collider
网格碰撞器 Mesh Collider
轮胎碰撞器 Wheel Collider
地形碰撞器 Terrain Collider
共同参数
Is Trigger 触发器 默认不勾选

如果启用,表示该碰撞器将用于碰撞检测,但是不会产生物理效果。
主要用于进行没有物体效果的碰撞检测

Material 物理材质

可以确定碰撞体和其他对象碰撞时的交互(表现)方式

Center

碰撞器在物体局部空间中的中心点位置

常用碰撞器特有参数
盒状碰撞器 Box Collider
size:碰撞器在x、y、z方向上的大小
球状碰撞器 Sphere Collider
Raduis:碰撞器的半径大小
胶囊碰撞器 Capsule Collider
Radius:胶囊体的上下半球的半径大小
Height:胶囊体圆柱体的高度
Direction:胶囊体在对象局部空间中的轴向 默认是Y-Axis
异形物体使用多种碰撞器组合

刚体对象的子对象碰撞器参与碰撞检测
例如一个人物的模型,各个部位需要参与碰撞检测且又需要有刚体的效果。需要在人物的各个部位添加碰撞器,然后在父节点上添加一个刚体组件,即可实现节点下所有碰撞器有刚体的效果。

不常用碰撞器
网格碰撞器 Mesh Collider

性能消耗较高
如果为有网格碰撞器的物体添加刚体组件,则必须勾选Mesh Collider的Convex选项,否则会报错。网格碰撞器最多支持255个三角形

轮胎碰撞器 Wheel Collider

应用场景较少

地形碰撞器 Terrain Collider

性能消耗较高

物理材质

创建物理材质

Create–>Physica Material

物理材质参数
Dynamic Friction 移动时使用的摩擦力

值在0-1之间,值为0时就像冰一样,值为1时对象迅速静止(除非用很大的力推动对象)

Static Friction 静止时使用的摩擦力

值在0-1之间,值为0时就像冰一样,值为1时导致对象很难被移动

Bounciness 表面的弹性

值在0-1之间,值为0不会反弹,值为1时将在反弹时不产生任何能量损失

Friction Combine 两个碰撞对象摩擦力的计算方式
Average 对两个摩擦值求平均值
Mininum 使用两个摩擦力值中最小的
Maximum 使用两个摩擦力值中最大的
Multiply 两个摩擦力值相乘
Bounce Combine 两个碰撞对象反弹力的计算方式 同 Friction Combine

碰撞检测函数

碰撞触发函数属于特殊的生命周期函数,跟其他生命周期函数一样,也是Unity通过反射来调用,在FixedUpdate之后执行,每次在执行完FixedUpdate函数后都会相应碰撞检测

物理碰撞检测响应函数
// 碰撞时会自动执行的函数
private void OnCollisionEnter(Collision collision)
{
	// Collision类型的参数包含了碰到了自己的对象的相关信息
	// 关键参数:
	// 1、对象碰撞器的信息 collision.collider[Collider]
	// 2、对象信息 collision.gameObject[GameObject]
	// 3、对象位置信息 collision.transform[Transform]
	// 4、触碰点数量 collision.contactCount[int]
	// 5、接触点信息 collision.contacts[ContactPoint[]]
}
// 碰撞分离时会自动执行的函数
private void OnCollisionExit(Collision collision)
{   
}
// 两个物体互相接触摩擦时会不停调用该函数(当物体静止时就会停止调用该函数)
private void OnCollisionStay(Collision collision)
{
}
触发器检测响应函数
// 触发接触时会自动执行的函数
private void OnTriggerEnter(Collider other)
{
}
// 触发分离时会自动执行的函数(穿过体内时)
private void OnTriggerExit(Collider other)
{
}
// 触发接触中会自动执行的函数(穿出体内时)
private void OnTriggerStay(Collider other)
{
}
要明确什么时候会响应函数

只要两个物体满足碰撞或者触发的条件,不管它有没有刚体组件,都会触发对应的函数
如果是一个异形物体,刚体在父对象上,如果在子对象上挂脚本检测碰撞是不可以的,必须挂载到这个刚体父对象上

碰撞和触发器函数都可以写成虚函数,在子类中重写逻辑

一般会把想要重写的碰撞和触发响应函数写成protected类型的,没有必要写成public类型,因为这些函数都是Unity通过反射自动调用的,不需要手动调用。

刚体加力

刚体自带添加力的方法

给刚体加力的目标就是让其有一个速度 ,朝一个方向运动
获取rigidbody组件:

Rigidbody rigidbody = GetComponent<Rigidbody>()
添加力
相对世界坐标系
public void AddForce(Vector3 force);
相对本地坐标系
public void AddRelativeForce(Vector3 force);
添加扭矩力,让其旋转
相对世界坐标系
public void AddTorque(Vector3 torque);
相对本地坐标系
public void AddRelativeTorque(Vector3 torque);
直接改变速度
// 相对于世界坐标系
public Vector3 velocity { get; set; }
模拟爆炸效果
// 力的大小,爆炸中心,爆炸半径
public void AddExplosionForce(float explosionForce, Vector3 explosionPosition, float explosionRadius);
力的几种模式

在上面提到的添加里的方法有一个可选参数ForceMode,添加的力的模式
根据动量守恒定理:Ft = mv (力X时间=质量X速度),推导出v=Ft/m
在这里插入图片描述

Force 给物体添加一个持续的力,与物体的质量有关(较真实,因为不会忽略一些条件)

假设F = 10, m = 2kg
t = 0.02s
v = 10 * 0.02 / 2 = 0.1m/s
每物理帧移动=0.1m/s * 0.02s = 0.002m

Impulse 给物体添加一个瞬间的力,与物体的质量有关,忽略时间 默认是1

假设F = 10,m = 2kg
t = 1s
v = 10 * 1 / 2 = 5m/s
每物理帧移动=5m/s * 0.02s = 0.1m

VelocityChange 给物体添加一个瞬时速度,忽略质量,忽略时间

假设F = 10
t = 1s
m = 1kg
v = 10 * 1 / 1 = 10m/s
每物理帧移动=10m/s * 0.02s = 0.2m

Acceleration 给物体添加一个持续的加速度,忽略其质量

假设F = 10
t = 0.02s
m = 1kg
v = 10 * 0.02 / 1 = 0.2m/s
每物理帧移动=0.2m/s * 0.02s = 0.004m

力场脚本 ConstantForce

在这里插入图片描述
添加ConstantForce脚本时,如果物体没有添加刚体组件,则会自动添加该脚本
一般场景上一个持续运动的物体可以添加一个ConstantForce脚本,而不需要在代码里添加

刚体的休眠

Unity为了节省性能,会使刚体处于休眠状态(如,受重力影响的物体下落到地面上),此时如果旋转地面的角度,该物体的位置并不会变化,此时该刚体处于休眠状态
如下图:
在这里插入图片描述
在立方体和平面接触了之后,旋转平面,此时平面已经于立方体脱离了,但是立方体并没有反应。此时如果移动一下平面,则立方体才会有反应。
如果不想要物体休眠,可以在Update生命周期函数中做一下判断,如果刚体休眠了,则唤醒它。

if(rigidbody.IsSleeping())
{
	rigidbody.WakeUp();
}

音效系统

  • 11
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值