unity笔记
文章目录
unity入门
-
Unity环境搭建
-
Unity界面基础
Scene场景和Hierarchy层级窗口
Game游戏和Project工程
lnspector检查和Console控制台
工具栏和父子关系
- Unity工作原理
反射机制和游戏场景
预设体和资源包的导入导出
- Unity脚本基础
脚本基本规则
生命周期函数
Inspector窗口可编辑的变量
Mono中的重要内容
- Unity重要组件和Api
最小单位Gameobject
时间相关Time
必不可少Transform
Input和Screen
必不可少Camera
- 核心系统
核心系统—光源
核心系统—物理系统之碰撞检测
核心系统—音效系统
——
GUI
PlayerPrefs
场景切换和游戏退出
鼠标隐藏锁定相关
随机数和Unity自带委托相关
模型资源的导入
Unity环境搭建
工程文件夹
-
Assets:工程资源文件夹(美术资源,脚本等等)
-
Library:库文件夹(Unity自动生成管理)
-
Logs:日志文件夹,记录特殊信息(Unity自动生成管理)
-
obj:编译产生中间文件(Unity自动生成管理)
-
Packages:包配置信息(Unity自动生成管理)
-
ProjectSettings:工程设置信息(Unity自动生成管理)
assets以外都可以删除,再启动会自动生成
unity hub中可以移除工程,不会实际删除工程
再打开,选择添加工程
Unity界面基础
窗口布局
右上角——layout
推荐选择:2by3
同时显示scene和game窗口
-
Inspector检查窗口:用于设置游戏对象具体信息
-
Console控制台窗口:用于显示调试信息,报错、警告、打印信息等
-
Scene场景窗口:所有游戏对象所在地
-
Hierarchy层级窗口:所有游戏的对象名单
-
Game游戏窗口:玩家看到的游戏画面
-
Project工程窗口:所有游戏资源和脚本内容
Hierarchy层级窗口
显示一个场景中的所有对象
创建或拖入各种游戏对象
模型、光源、图片UI等等内容
手指——
眼睛——隐藏对象
快捷键:
F2:对象改名 rename
Ctrl+C:复制 copy
Ctrl+V:粘贴 paste
Ctrl+D:克隆一个(复制粘贴)
Delete:删除
Scene场景
查看所有游戏对象
设置所有游戏对象
- 窗口上方工具条内容:
0.辅助线 可以选择XYZ轴向
1.渲染模式 shaded着色器 wireframe网格
2.2D、3D视图切换
3.光源、音效、特效显示开启
4.辅助功能,控制场景上提示图标等
5.搜索
6.场景轴向
点击中心:
ISO 正交模式 2D
persp 透视模式 3D
- 3D世界坐标轴:
红色为X轴正向
绿色为Y轴正向
蓝色为Z轴正向
- 以屏幕为参照物:
垂直屏幕向内为Z正方向
平行屏幕向右为X正方向
平行屏幕向上为Y正方向
- 窗口左侧工具条内容:
平移 Q
移动 W
旋转 E
缩放 R
2D T
综合 Y
旋转时轴的相对目标 global/local
磁铁 吸附移动(W global状态下) 快捷键按住ctrl
- 场景中的操作
左键相关
鼠标单击:选中单个物体
鼠标框选:选中多个物体
Ctrl+鼠标单击:多选物体
长按ALT键+鼠标左键+移动鼠标:相对观察视口中心点旋转
右键相关
鼠标右键按下+移动鼠标:旋转视口
鼠标右键按下+WASD:漫游场景
鼠标右键按下+WASD+Shift:快速漫游场景
长按ALT键+鼠标右键+移动鼠标:相对屏幕中心点拉近拉远
中键相关
滚动鼠标中间:相对屏幕中心点拉近拉远
鼠标中间按下+移动鼠标:平移观察视口
长按ALT键+滚动鼠标中间:鼠标指哪就朝哪拉近拉远
选中物体之后,按F键:居中显示物体
(或者在层级窗中双去对象)
Game游戏窗口
游戏画面窗口
场景中摄像机拍摄范围内的游戏对象
玩家能看到的画面内容
- 上方:
1.引擎中运行游戏
2.暂停运行
3.逐帧运行
- game窗口标志右键:
1.Warn if No Cameras Rendering
场景中没有摄像机时会发出警告
2.Clear Every Frame in Edit Mode
游戏未播放时,也更新Game窗口,避免显示问题
- 游戏窗口上方工具条:
显示设备选择 display1
屏幕分辨率 aspect
缩放大小 scale
运行时全屏 play maximized
静音
渲染统计信息
辅助功能 辅助图标显示
Project工程窗口
工程资源窗口
所有的工程资源都会在该窗口中显示
显示的内容为Assets文件夹中的所有内容
主要用来管理资源脚本文件
- 默认文件夹Scenes:
里面有一个默认空场景
- Packages:
官方拓展包
第三方插件
- Project工程窗口关键功能
1.窗口设置 右上角三点 一列显示/两列显示
2.创建相关资源文件 加号 folder文件夹 在外部打开
3.查找
4.按资源类型查找 相当于输入 t:
5.按标签查找
6.显示隐藏
- 文件右键
Ctrl+D:克隆
Delete:删除
- 资源类型
图片格式: jpg、png、tga
模型格式: fbx、max、maya
音效:wav、mp3、ogg
文本: txt、json、bytes
视频: mp4
lnspector检查窗口
查看场景中游戏对象关联的C#脚本信息
不选择场景中游戏对象或不进行任何相关设置,该界面不会显示任何信息
当选择场景中意游戏对象时,该界面将显示和该游戏对象关联的C#脚本信息
1.游戏对象基本设置 标签tag 大类型标签layer
2.关联的C#脚本 transform脚本——位置信息、旋转、缩放
3.脚本的公共成员变量
0.Add component 增加脚本
Console控制台窗口
用于查看调试信息的窗口
报错、警告、测试打印都可以显示在其中
默认未开启
可以在Window一>General中开启
快捷键:Ctrl+Shift+C
该窗口将显示代码编译过程中或者游戏运行过程中的报错、警告、测试信息
主要用于查错和调试用
1.清空控制台 运行时清空 构建时清空
2.相同内容折叠显示
3.报错暂停运行
1.是否显示错误信息
2.是否显示警告信息
3.是否显示打印信息
工具栏
重点:
File中的重要选项:
BuildSetting (工程发布打包)
Edit中的重要选项:
Project Setting (工程各系统设置)
Preferences(首选项,可以设置编程软件)
GameObject中的重要选项:
MoveToView、Align With View、Align View to Selected(几种快捷设置位置的功能)
具体:
1.文件操作:新建工程,新建场景,保存,打开,工程打包build setting
2.编辑操作:对象编辑操作相关,工程设置,引擎设置相关
ctrl+z撤销
ctrl+y取消撤销
project setting 与ProjectSettings文件夹相同
preference首选项 external tools开发工具 ide可以选择编辑器vs2019
shortcut快捷键设置
3.资源操作:基本等同于Project窗口中右键相关功能
创建资源 在外部打开
包导入导出
4.对象操作:基本等同于Hierarchy窗口中右键相关功能
创建对象
move to view设置对象到视图 ctrl+alt+f
align with view设置摄像机到视图
align view to selected到选中对象
对象失活激活 和inspector窗口打勾作用一样
5.脚本操作: Unity自带的脚本,可以添加各系统中的脚本
选中对象才可以添加脚本
和inspector中add component相同
7.窗口:可以打开Unity各核心系统的窗口
general常用窗口
asset store 官方市场(要上网站)
9.帮助:检杳更新,杳看版本等等功能
官方文档
unity manual
scripting reference
unity中国官网 可以看中文文档
父子关系
树形结构
1.子对象会随着父对象的变化而变化
2.子对象Inspector窗口中Transform信息是相对父对象的
3.Scene上方选择
Pivot中心点在父对象自身 center中心点在父子对象中心
Global坐标系 local
作用:
创建空对象,设置子对象
可以一起控制子对象
父对象做啥,子对象做啥;
子对象做啥,父对象不管
unity工作原理
unity自带脚本(gameObject,transform,物理,音效)+ 自定义脚本(玩家,怪物)——>游戏对象
游戏场景——面向对象,实例化对象
反射机制
反射的概念:
程序正在运行时,可以查看其它程序集或者自身的元数据
一个运行的程序查看本身或者其它程序的元数据的行为就叫做反射
在程序运行时,通过反射可以得到其它程序集或者自己程序集中代码的各种信息,比如类,函数,变量,对象等等,可以实例化它们,执行它们,操作它们
本质:
Unity引擎本质是一个软件
Unity开发的本质就是
在Unity引擎的基础上
利用反射和引擎提供的各种功能进行的拓展开发
GameObject:
GameObject类对象是Unity引擎提供给我们的
作为场景中所有对象的根本
GameObject对象必须有一个表示自己所在位置的信息
Transform:
Transform就是一个必不可少的脚本
(相当于就是用一个Transform类对象和GameObject类对象进行关联)
用于设置和得到演员在世界中的位置角度缩放等信息
- 反射机制的体现:
可以为(GameObject)关联各种(C#脚本)让它按照(代码逻辑中)的命令来处理事情
这个过程就是在利用反射new一个新的对象和(GameObject)对象进行关联
举例体现:
前提: Unity帮助我们实现了对象查找和关联
1.修改Inspector面板中Transform的内容
利用反射:已知对象,类名,变量名,通过反射为该对象设置变量值
2.新建一个脚本后,添加给一个指定的GameObject对象
利用反射:已知类名,可以获取所有公共成员,故可以在lnspector面板上创建各公共字段信息
游戏场景本质
1.游戏场景的新建
左上角file——new scene
2.游戏场景的保存
选中hierarchy窗口——ctrl+s——保存到scenes文件夹
project窗口 双击scenes内场景 切换场景
3.多个游戏场景叠加显示
project窗口场景拖到hierarchy窗口
可以同时显示多个场景
用处:方便拷贝对象到别的场景
4.游戏场景的本质
特殊格式的配置文件
包含GameObject,Transform
游戏场景文件后缀为.unity
本质就是一个配置文件
Unity有一套自己识别处理它的机制
但是本质就是把场景对象相关信息读取出来通过反射来创建各个对象关联各个脚本对象
可以用文本编辑器(记事本)打开
预设体
预制体
后缀prefab
可以用文本编辑器(记事本)打开
1.预设体是什么
保存单个物体的信息
预先设置,方便使用
- 2.创建预设体
在hierarchy窗口选中物体,拖入project窗口assets文件夹下
(蓝色图标 立方体)
可以在assets文件夹新建Prefabs文件夹,专门用于保存预设体
- 3.修改预设体
方法一:
在hierarchy中修改后,选中hierarchy预制体主体 ——>
在inspector中override ——>
——revert all恢复最初的预制体
——apply all保存修改应用到所有
方法二:
拖动修改后的物体,到assets文件夹原来的预设体上
直接覆盖
- 0.打开预设体,进行编辑
方法1:
project窗口assets文件夹中选中,在inspector窗口点open
方法2:
hierarchy窗口预设体 点击箭头>
- 在原预设体基础上,创建新的预设体
先破坏预设体:
hierarchy窗口,选中预设体,右键Prefab选择unpack
拖入assets文件夹
重名会自动加编号
- 4.删除预设体
资源包导入导出
文件后缀unity package
project窗口
- export package
默认包含关联
- import package
导入资源包
和直接拖入文件相同
unity脚本基础
设置编程用工具:
edit——>preference——>external tools——>ide选择vs2019
脚本基本规则
1.不在VS中创建脚本
在unity中创建,双击打开跳转vs
2.可以放在Assets文件夹下的任何位置
(建议同—文件夹管理) 创建文件夹Scripts
3.类名和文件名必须一致,不然不能挂载
(因为反射机制创建对象,会通过文件名去找Type)
必须同时修改
4.建议不要使用中文名命名
5.没有特殊需求不用管命名空间
默认创建的脚本 没有命名空间
6.创建的脚本默认继承MonoBehavior
MonoBehavior基类
1.创建的脚本默认都继承MonoBehaviour
继承了它才能够挂载在GameObject上
2.继承了MonoBehavior的脚本,不能new,只能挂
3.继承了MonnBehavior的脚本,不要去写构造函数
因为我们不会去new它,写构造函数没有任何意义
4.继承了MonoBehavior的脚本,可以在一个对象上挂多个
(如果没有加DisallowMultipleComponent特性)
特性写在类前[DisallowMultipleComponent]
5.继承MonoBehavior的类也可以再次被继承。
可以挂载
遵循面向对象继承多态的规则
不继承MonoBehavior的类
删除默认的继承MonoBehavior 以及 默认的函数
1.不继承Mono的类不能挂载在GameObject上
2.不继承Mono的类 想怎么写怎么写
如果要使用需要自己new
3.不继承Mono的类—般是单例模式的类(用于管理模块)
或者数据结构类(用于存储数据)
4.不继承Mono的类不用保留默认出现的几个函数
脚本执行的先后顺序
选择脚本后inspector窗口
Script Execution Order
——default time 默认时间——
增加脚本 设置时间
时间越小,越先执行
默认脚本内容
Ecitor\Data\Resources\ScriptTemplates
unity hub——>安装——>版本三点 在资源管理器中——>editor——>data——>Resources——>ScriptTemplates:txt文件
文件名称81-C# Script-NewBehaviourScript.cs
生命周期函数
帧
游的本质就是一个死循环
每一次循环处理游戏逻辑,就会更新—次画面
切换画面的速度到达—定时,人眼就认为画面是流畅的
—帧就是执行一次循环
fps (Frames Per Second) :即每秒钟帧数
—般我们说的60帧30帧
意思是1秒更新60次、30次画面
1s = 1000ms
60帧:1帧为
1000ms/60=16.66ms
30帧:1帧为
1000ms/30=33.33ms
人眼舒适放松时可视帧数是每秒24帧
游戏卡顿的原因:
跑1帧游戏逻辑中的计算量过大,
或者CPU不给力,不能在一帧的时间内处理完所有游戏逻辑
Unity底层已经帮助我内做好了死循环
我们需要学习Unity的生命周期函数
利用它做好的规则来执行我们的游戏逻辑就行了
生命周期函数的概念
所有继承MonoBehavior的脚本最终都会挂载到Gameobject游戏对象上
生命周期函数就是该脚本对象依附的Gameobject对象从出生到消亡整个生命周期中,会通过反射自动调用的一些特殊函数
unity帮助我们记录了,一个Gameobject对象依附了哪些脚本,会自动的得到这些对象,通过反射去执行一些固定名字的函数
生命周期函数
生命周期函数的访问修饰符一般为private和protected
因为不需要再外部调用,生命周期函数都是Unity自己帮助我们调用的
默认private
没有参数
支持继承多态
如果不在其中写逻辑,那就不要写生命周期函数;因为通过反射调用,找到就会调用
脚本可以关联多个对象,相互无关
对象一开始就失活,不会调用生命周期函数
分类:
-
只执行一次的
-
每一帧都执行的
-
特殊情况下执行的
- 对象出生
对象指脚本
- Awake
(自己这个类对象)出生时调用。类似构造函数
一个对象只会调用一次
可以在类对象创建时,进行一些初始化操作
- OnEnable
依附的GameObject对象 每次激活时调用
当一个对象被激活时进行一些逻辑处理
- Start
从自己被创建出来后。第—次帧更新之前调用
主要作用还是用于初始化信息的,但是它相对Awake来说要晚一点
因为它是在对象进行第一次帧更新之前才会执行的
一个对象只会调用一次
- FixedUpdate
物理帧更新
主要用于进行物理更新
固定时间间隔执行。间隔时间可以设置
时间间隔是可以在project setting中的 Time里fixed timestep去设置的
- Update
逻辑帧更新
每帧执行
主要用于处理游戏核心逻辑更新
- LateUpdale
每帧执行。
一般用来处理摄像机位置更新相关内容
于update之后执行
时间间隔和update相同,只是先后执行
Update和LateUpdate之间unity进了一些处理,处理我们动画相关的更新
- OnDisable
依附的GameObiect对象每次失活时调用
(inspector窗口取消打勾)
在一个对象失活时做一些处理
- OnDestroy
对象销毁时调用
依附的GameObiect对象被删除时
(会先调用ondisable)
只调用一次
- 对象死亡
unity中console打印信息:
1.没有继承MonoBehavior类的时候
Debug.Log("123");
Debug.LogError("出错了!");
Debug.LogWarning("警告!");
可以显示代码信息来源位置
2.继承了MonoBehavior 有一个线程的方法可以使用
print("1234");
Inspector窗口可编辑的变量
Inspector显示的可编辑内容就是脚本的成员变量
-
私有private和保护protectd无法显示编辑
-
让私有的和保护的也可以被显示
在需要使用的申明之前,加上强制序列化字段特性
[SerializeField]
序列化就是把一个对象保存到一个文件或数据库字段中去
特性与反射相关
- 公共的public可以显示编辑
可以初始化
- 公共的也不让其显示编辑
在变量前加上特性
[HideInInspector]
- 大部分类型都能显示编辑
如数组[],枚举enum,列表list,unity自带的类
不能编辑的类型:字典,结构体,(没有继承MonoBehavior的其他的)类
- 让自定义类型可以被访问
加上序列化特性
[System. Serializable]
默认脚本没有using system,所以使用时需要先写system点出
结构体,类可以;字典怎样都不行
注意:
1.Inspector窗口中的变量关联的就是对象的成员变量,
运行时改变他们就是在改变成员变量
2.拖曳到Gameobject对象后,再改变脚本中变量默认值,界面上不会改变
脚本移除,再重新添加;;或者inspector中修改
3.运行中修改的信息不会保存
可以在运行时copy component脚本,在运行结束后paste component values脚本
—些辅助特性
- 分组说明特性Header
为成员分组
[Header("分组说明")]
- 悬停注释Tooltip
为变量添加说明
[Tooltip(“说明内容")]
- 间隔特性Space()
让两个字段间出现间隔
[Space()]
- 修饰数值的滑条范围Range
[Range(最小值,最大值)]
滑条拖动 调整数值
- 多行显示 字符串
默认不写参数显示3行
写参数就是对应行
(不写特性普通的字符串 显示1行)
[Multiline(行数)]
6.滚动条显示 字符串
默认不写参数就是 超过3行显示滚动条
[TextArea(3,4)]
最少显示3行,最多4行,超过4行就显示滚动条
- 为变量添加快捷方法ContextMenuItem
参数1 显示按钮名
参数2 方法名 不能有参数 不能有返回值
[ContextMenuItem("显示按钮名",“方法名")]
一般用于重置变量
在inspector窗口变量上 右键,会显示按钮名称
- 为方法添加特性 能够在Inspector中执行
[ContextMenu("测试函数")]
”测试函数“是对方法的描述
一般用于测试
在inspector窗口脚本三点,会显示测试函数
Mono中的重要内容
monobehavior f12进去
或者官方文档api说明
重要成员
- 获取依附的Gameobject
this.gameObject
this可以省略
Gameobject的名称:
this.gameObject.name
- 获取依附的Gameobject的位置信息
this.transform
this.gameObject.transform
这种写法和上面是一样的效果都是得到依附的对象的位置信息
this.transform.position
位置
this.transform.eulerAngles
旋转角度rotation
this.transform.lossyScale
缩放大小
打印的时候会四舍五入
this都可以省略
- 获取脚本是否激活
inspector窗口脚本前面的勾勾,控制脚本是否激活
this.enabled
可以设置为true,false
this.enabled = false
- 获取别的脚本对象 依附的成员
public class Lesson3 : MonoBehaviour
{
public Lesson3 otherLesson3;
print(otherLesson3.gameobject.name);
print(otherLesson3.transform. position);
}
需要在unity中进行关联,将要关联的拖过去(hierarchy到inspector)
常见报错——:空
NullReferenceException: Object reference not set to an instance of an object
重要方法:
得到依附对象上挂载的其它脚本
只要能得到场景中别的对象,或者对象依附的脚本,那就可以获取到它的所有信息
-
得到自己依附对象挂载的单个脚本
(如果有多个一样名称脚本无法确定得到的是哪个
一般不会挂多个一样脚本)
- 根据脚本名获取
(例:Test为要得到的脚本class的名称)
Test t = this.GetComponent("要得到的脚本的名称Test") as Test;
返回值是component,需要as
如果获取失败,没有对应的脚本,默认返回空
一般需要判断 if (t!=null){//逻辑}
- 根据Type获取
Test t = this.GetComponent( typeof(Test) ) as Test;
- 根据泛型获取
建议使用泛型获取,因为不用二次转换
Test t = this.GetComponent<Test>();
-
得到自己依附对象挂载的多个脚本
(一般不会挂多个相同的脚本)
多个重载:通过type,list传结果,泛型数组等等
一:数组
Test[] array = this.Getcomponents<Test>();
二:返回列表
List<Test> list = new List<Test>();
this.GetComponents<Test>(list);
参数list即返回的列表
list必须初始化赋值
- 得到子对象挂载的脚本
(默认也会找自己身上是否挂载该脚本)
函数有一个参数,
默认不传是false,如果子对象失活,不会去找这个对象上是否有某个脚本;
如果传true,子对象失活也会找
得到一个:
Test t = this.GetComponentInChildren<Test>(true);
多个重载,有type,一般使用泛型
得到多个:
一:数组
Test[] t = this.GetComponentsInChildren<Test>(true);
二:返回列表
List<Test> list = new List<Test>();
this.GetComponentsInChildren<Test>(true,list);
两个参数,一个是失活是否查找,一个是返回的列表
- 得到父对象挂载的脚本
(它默认也会找自己身上是否挂载该脚本)
(子对象激活,父对象肯定是激活的)
可以查找父类的父类
得到一个:
Test t = this.GetComponentInParent<Test>();
得到多个:数组,列表(和上面一样)
Test[] t = this.GetComponentsInParent<Test>();
- 尝试获取脚本
一个更加安全的,获取单个脚本的方法
如果得到了会返回true
if(this.TryGetComponent<Test>(out t))
{
//逻辑处理
}
Unity重要组件和Api
最小单位Gameobject
成员变量
- 名字
this,gameObject.name
可以改名,直接赋值
this,gameObject.name = "名字";
- 是否激活
this.gameObject.activeSelf
返回bool类型
- 是否是静态
this.gameObject.isStatic
- 层级
this.gameObject.layer
返回int类型
- 标签
this.gameObject.tag
- transform
this.transform
通过Monobehavior得到信息
this.gameObject.transform
通过gameobject得到信息
得到的信息是一样,都是依附的Gameobject的位置信息
静态方法
- 创建自带几何体
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
PrimitiveType点出几何体类型
命名几何体
obj.name ="立方体";
- 查找对象
只能找到激活的对象,不能找失活的对象
如果场景中存在多个满足条件的对象,无法准确确定找到的是谁
(得到某一个单个对象2种方式:)
1.是public从外部面板拖进行关联(推荐使用)
2.通过API去找
- 查找单个对象
通过对象名查找(Find)
查找效率比较低下,会在场景中的所有对象去查找
没有找到就会返回null
GameObject obj = GameObject.Find("名称");
if( obj != null )
{
print(obj.name);
}
else
{
print("没有找到对应对象");
}
通过tag来查找对象(FindWithTag)(FindGameObjectWithTag)
GameObject obj = GameObject.FindWithTag("P1ayer");
//GameObject obj = GameObject.FindGameObjectWithTag("P1ayer");
//效果一样,方法名称不一样
if (obj != nul1)
{
print("根据tag找的对象" + obj.name);
}
else
{
print("根据tag没有找到对应对象");
}
找到场景中挂载某一个脚本的对象
效率更低,遍历对象、对象的脚本
Test o = GameObject.FindObjectOfType<Test>();
- 查找多个对象
只能通过tag去找多个
通过名字是没有找多个的方法的
GameObject[] objs = GameObject.FindGameObjectsWithTag("Player");
用的比较少,是Gameobject父类 object提供的方法
Unity里面的object不是指的万物之父object,同名类,命名空间不同
Unity里的object 命名空间在unityEngine中的,是继承万物之父的一个自定义类
C#中的object命名空间是在system中的
- 实例化对象
克隆对象
根据一个Gameobject对象创建出一个和它一模一样的对象
//准备用来克隆的对象
//1.直接是场景上的某个对象
//2.可以是一个预设体对象
public Gameobject obj;
//在unity内拖动关联
Gameobject.Instantiate(obj);
可以操作这个对象
Gameobject obj1 =Gameobject.Instantiate(obj);
如果继承了 MonoBehavior,可以不用写Gameobject,这个方法是unity里面的object基类提供的
Instantiate(obj);
- 删除对象
删除对象有两种作用:
1.删除指定的一个游戏对象
2.删除一个指定的脚本对象
destroy方法:
destroy方法不会马上移除对象,只是给这个对象加了一个移除标识
会在下一帧时,把这个对象移除,并从内存中移除
建议使用Destroy方法,因为是异步的,降低卡顿的几率
第一个参数:删除的对象
Gameobject.Destroy(obj);
第二个参数:延迟几秒钟删除
Gameobject.Destroy(obj,5);
Destroy不仅可以删除对象还可以删除脚本
Gameobject.Destroy(this);
Gameobject.Destroy(this.gameObject);
DestroyImmediate:
立即把对象从内存中移除
Gameobject.DestroyImmediate(obj);
继承MonoBehavior的类不用写Gameobject:
Destroy (obj);
DestroyImmediate(obj);
过场景不移除:
默认情况,在切换场景时,场景中对象都会被自动删除掉
如果希望某个对象过场景不被移除
不想谁过场景被移除,就传谁
一般都是传依附的Gameobject对象
自己依附的Gameobject对象过场景不被删除
Gameobject.DontDestroyOnLoad(this.gameObject);
DontDestroyOnLoad(this.gameObject);
重要成员方法
- 创建空物体
new一个Gameobject就是在创建一个空物体
GameObject obj = new GameObject();
GameObject obj = new GameObject("空物体名称");
GameObject obj = new GameObject("空物体名称",typeof(Test2),typeof(Test1);
参数一:空对象名称
之后的参数:可变数组,空对象上挂的脚本
- 为对象添加脚本
继承MonoBehavior的脚本,是不能够去new
动态的添加继承MonoBehavior的脚本在某一个对象上,使用Gameobject提供的方法AddComponent
Test t = obj.AddComponent( typeof(Test) ) as Test;
用泛型更方便
Test t = obj.Addcomponent<Test>();
通过返回值可以得到加入的脚本信息
- 得到脚本
得到脚本的成员方法,和继承Mono的类得到脚本的方法一模一样
看上面mono中的重要内容
- 标签比较
if(this.gameObject.CompareTag("P1ayer"))
{
print("对象的标签是Player");
}
if(this.gameObject.tag =="Player")
{
print("对象的标签是Player");
}
CompareTag返回bool值
tag返回tag名称
- 设置激活失活
false失活
true激活
obj.SetActive(false);
次要成员方法
不建议使用
通过广播或者发送消息的形式,让自己或者别人执行某些行为方法
- 通知自己执行什么行为
命令自己去执行这个TestFun这个函数
找到自己身上所有的脚本有这个名字的函数去执行
this.gameObject.SendMessage( "TestFun");
参数一:方法名称
后面的参数:传给方法的参数
- 广播行为,让自己和自己的子对象执行
this.gameObject.BroadcastMessage(""函数名");
- 向父对象和自己发送消息并执行
this.gameObject.SendMessageUpwards("函数名");
时间Time
主要用于游戏中参与位移、记时、时间暂停等#endregion
- 时间缩放比例
时间停止
Time.timeScale = 0;
回复正常
Time.timeScale = 1;
2倍速
Time.timeScale = 2;
- 帧间隔时间
主要是用来计算位移
路程=时间*速度
帧间隔时间:最近的一帧用了多长时间(秒)
受scale影响
Time.deltaTime
不受scale影响的帧间隔时间
Time.unscaledDeltaTime
- 游戏开始到现在的时间
单机游戏中计时
受scale影响
Time.time
不受scale影响
Time.unscaledTime
- 物理帧 间隔时间 Fixedupdate
受scale影响
Time.fixedDeltaTime
不受scale影响
Time.fixedUnscaledDeltaTime
- 帧数
从开始到现在,游戏跑了多少帧 (次循环)
Time.frameCount
Transform
游戏对象(Gameobject)位移、旋转、缩放、父子关系、坐标转换等相关操作
unity提供的类
vertor3
表示三维坐标系中的一个点或者一个向量
参数是float类型
- 申明
Vector3 v = new Vector3();
v.x = 10;
v.y = 10;
v.z =10;
省略new
Vector3 v;
v.x = 10;
v.y = 10;
v.z =10;
一步到位(常用)
Vector3 v = new Vector3(10,10,10);
只传xy,默认z是0
Vector3 v = new Vector3(10,10);
- 基本计算
加减±:对应xyz加减运算
乘除一个数:对应xyz运算
- 常用(x,y,z)
Vector3.zero
(0,0,0)
Vector3.one
(1,1,1)
Vector3.right
(1,0,0)
Vector3.left
(-1,0,0)
Vector3.forward
(0,0,1)
Vector3.back
(0,0,-1)
Vector3.up
(0,1,0)
Vector3.down
(0,-1,0)
常用forward:z轴 作为 面朝向
- 常用方法:计算两个点之间的距离
Vector3.Distance(v1,v2)
位置
- 相对世界坐标系
this.transform.position
相对于世界坐标系的原点的位置
可能和面板上显示的是不一样的
- 相对父对象
this.transform.localPosition
面板坐标就是相对父对象的位置
相对父对象localPosition(面板)和相对世界坐标系position一样:
1.父对象的坐标就是世界坐标系原点(0,0,0)
2.对象没有父对象
- 对象当前的各朝向
通过trnasform.出来
对象当前的面朝向
this.transform.forward
对象当前的头顶朝向
this.transform.up
对象当前的右手边
this.transform.right
- 改变位置
位置transform的赋值不能直接改变x,y,z
不能单独改xy z某一个值
- 只能整体改变
this.transform.position=new Vector3(10,10,10);
this.transform.localPosition = Vector3.up * 10;
如果只想改一个值x,y和z要保持原有坐标一致
- 直接赋值
使用原来的transform的坐标值
this.transform.position = new Vector3(1,this.transform.position.y, this.transform.position.z)
- 先取出来再赋值
transform不可以直接改xyz
vector3可以直接改xyz的
Vector3 vPos = this.transform.localPosition;
vPos.x = 10;
this.transform.localPosition = vPos;
位移
坐标系下的位移计算公式:路程=方向*速展时间
- 自己计算
变化position:当前的位置+路程=最终所在的位置
方向决定了前进方向
vector3朝世界坐标方向;transform朝自己的朝向
this.transform. position = this.transform.position + this.transform.up * 1 *Time.deltaTime
this.transform.position += Vector3.forward * 1 *Time.deltaTime;
使用复合运算符+=
- API
一般使用API来进行位移
存在多个重载
参数一:位移 = 方向*速度*时间
参数二:相对坐标系,可以不填,默认是相对于自己坐标系
(相当于位移的方向,和相对坐标系的方向 矢量和)
-
不写第二个参数,朝自己的面朝向移动
this.transform.Translate(Vector3.forward* 1 * Time.deltaTime);
-
(Vector3)(world)相对于世界坐标系的 z轴动,始终是朝世界坐标系朝向移动
this.transform.Translate(Vector3.forward* 1 * Time.deltaTime,Space.World);
-
(transform)(world)相对于世界坐标的 自己的面朝向去动,始终朝自己的面朝向移动
this.transform.Translate(this.transform.forward * 1 *Time.deltaTime,Space.World);
-
(transform)(self)相对于自己的坐标系下的 自己的面朝向向量移动(千万不要用)
this.transform.Translate(this.transform.forward * 1 *Time.deltaTime,Space.Self);
-
(Vector3)(self)相对于自己的坐标系下的 z轴正方向移动,始终朝自己的面朝向移动
this.transform.Translate(Vector3.forward * 1 * Time.deltaTime,Space.Self);
角度
不写rotation(返回值是四元数)
- 相对世界坐标角度
this.transform.eulerAngles
- 相对父对象角度(界面显示的角度)
this.transform.localEulerAngles
设置角度和设置位置一样,不能单独设置xyz,要一起设置
this.transform.localEulerAngles = new Vector3(10,10,10);
旋转
和位移一样,要写在update里面
经常朝y轴转
-
自己计算:和位置一样,不停改变角度即可
-
API
自转
多个重载
重载一:每个轴 具体转多少度
第一个参数:旋转的角度 * 每一帧时间
第二个参数:相对的坐标系,默认不填就是相对于自己坐标系进行的旋转self
this.transform.Rotate(new Vector3(0,10,0)* Time.deltaTime);
this.transform.Rotate(new vector3(0,10,0)*Time.deltaTime,Space.World);
重载二:相对于某个轴转多少度
参数一:相对哪个轴进行转动
参数二:转动的角度是多少
参数三:相对的坐标系,默认不填就是相对于自己的坐标系进行旋转
this.transform.Rotate(Vector3.up,10 * Time.deltaTime);
this.transform.Rotate(Vector3.up,10 * Time.deltaTime,Space.World);
绕某一个点转
参数一:相当于哪一个点转圈
参数二:相对于那一个点的哪一个轴转圈
参数三:转的度数 = 旋转角度速度*时间
this.transform.RotateAround(Vector3.zero,Vector3.right,10 *Time.deltaTime);
缩放
- 相对世界坐标系
this.transform.lossyScale
只能得不能改
- 相对本地坐标系 (父对象)(界面显示的)
this.transform.localScale
修改不能只改xyz,只能一起改
this.transform.localScale = new Vector3(3,3,3);
Unity没有提供关于缩放的API,只能自己算
this.transform.localScale += Vector3.one * Time.deltaTime;
看向
让一个对象的面朝向,可以一直看向某一个点或者某一个对象
写在update里,可以一直朝着看
- 看向一个点 相对于世界坐标系的
this.transform.LookAt(Vector3.zero);
- 看向一个对象 就传入一个对象的Transform信息
public Transform lkobj;
public后在界面关联对象
this.transform.LookAt(lkobj);
对象变化,朝向也跟着变
父子关系
获取和设置父对象
- 获取父对象
this.transform.parent.name
- 设置父对象
parent类型是transform
可以find查找对象,也可以public之后拖动关联对象
this.transform.parent = Gameobject.Find("Fathec2").transform;
断绝父子关系 即父对象=null
this.transform.parent = null;
- 通过API 设置父子关系
this.transform.SetParent(Gameobject.Find("Father2").transform);
断绝父子关系
this.transform.SetParent(null);
参数一:我的父亲
参数二:是否保留世界坐标的位置角度缩放信息
true会保留世界坐标下的状态,和父对象进行计算得到本地坐标系的信息
false不会保留,会直接把世界坐标系下的位置角度缩放 直接赋值到本地坐标系下
this.transform.SetParent(Gameobject.Find("Father3" ).transform,false);
- 与所有的儿子断绝关系
只能断绝第一层的关系
this.transform.DetachChildren();
- 获取子对象
this.transform.Find( "名字").name
可以找到失活的对象,gameObject方法不能找到失活对象
不能找到儿子的儿子
(this都是可以省略的,只是方便理解)
- 得到有多少个儿子
1.失活的儿子也算数
2.找不到孙子,所以孙子不会算数量
this.transform.childCount
- 遍历儿子
通过索引号去得到自己对应的儿子
编号超出了儿子数量的范围,直接报错
返回值是transform,可以得到对应儿子的位置相关信息
this.transform.GetChild(0);
for (int i=0;i< this.transform.childCount;i++)
{
print("儿子的名字:" + this.transform.GetChild(i).name);
}
儿子的操作
- 判断自己的爸爸是谁
一个对象 判断自己是不是另一个对象的儿子
返回bool值
son.IsChildOf(this.transform)
- 得到自己 作为儿子的编号
son.GetSiblingIndex()
- 把自己设置为第一个儿子
son.SetAsFirstSibling();
- 把自己设置为最后一个儿子
son.setAsLastSibling();
- 把自己设置为指定个儿子
填的数量超出了范围(负数或者更大的数)不会报错 会直接设置成最后一个编号
son.SetSiblingIndex(1);
坐标转换
- 把世界坐标系的点 转换为相对本地坐标系的点
受到缩放影响
this.transform.InverseTransformPoint(Vector3.forward)
- 把世界坐标系的方向 转换为相对本地坐标系的方向
不受缩放影响
this.transform.InverseTransfonmDirection(Vector3.forward)
受缩放影响
this.transform.InverseTransformVector(Vector3.forward)
- 本地坐标系的点 转换为相对世界坐标系的点
受到缩放影响
this.transform.TransformPoint(Vector3.forward)
- 本地坐标系的方向 转换为相对世界坐标系的方向
不受缩放影响
this.transform.TransformDirection(Vector3.forward)
受缩放影响
this.transform.TransformVector(Vector3.forward)
Input
- 鼠标在屏幕的位置
Input.mousePosition
屏幕坐标的原点是在屏幕的左下角;往右是x轴正方向,往上时Y轴正方向
返回值时Vector3,但是只有x和y有值,z一直是0;因为屏幕本来就是2D的不存在z轴
检测鼠标输入
- 鼠标按下一瞬间进入
0左键,1右键,2中键
只要按下的这一瞬间,进入一次
Input.GetMouseButtonDown(0)
返回bool类型
- 鼠标抬起一瞬间进入
Input.GetMouseButtonUp(0)
- 鼠标长按 按下抬起都会进入
当按住按键不放时会一直进入这个判断
Input.GetMouseButton(0)
- 中键滚动
返回值的y: -1往下滚,0没有滚,1往上滚
返回值是vector2的值,鼠标中键滚动会改变其中的Y值
Input.mouseScrollDelta
检测键盘输入
- 键盘某个键按下 一瞬间
返回bool值
一:传keycode
Input.GetKeyDown(KeyCode.W)
KeyCode枚举中提供了所有按键
二:传入字符串
Input.GetKeyDown("q")
只能传入小写字符串
- 键盘抬起
Input.GetKeyup(KeyCode.W)
- 键盘长按
Input.GetKey(KeyCode.W)
检测默认轴输入
GetAxis方法参数查看和设置:edit——project setting——input manager
unity提供的方法,帮助我们控制对象的位移和旋转
GetAxis返回值是float -1到1之间渐变(小数)
- 键盘AD按下时 返回-1到1之间的变换
得到的这个值就是我们的 左右方向(相当于x轴,左边-1 ,右边1)
通过它来控制对象左右移动或者左右旋转
Input. GetAxis ("Horizontal")
- 键盘SW按下时 返回-1到1之间的变换
得到的这个值就是我们的上下方向(相当于y轴,下面-1 ,上面1)
通过它来控制对象上下移动或者上下旋转
Input.GetAxis ( "Vertical")
- 鼠标横向移动时 -1到1 左右
Input.GetAxis ( “Mouse X”)
- 鼠标竖向移动时 -1到1 下上
Input.GetAxis(“Mouse Y”)
- GetAxisRaw方法和GetAxis使用方式相同
只不过它的返回值只会是-101,不会有中间值
其他
- 是否有任意键或鼠标长按
Input.anyKey
返回bool值
- 是否有任意键或鼠标按下
Input.anyKeyDown
- 这一帧的键盘输入
Input.inputString
和anyKeyDown配合使用
手柄
得到连接的手柄的 所有按钮名字
string[] strs = Input.GetJoystickNames()
某一个手柄键按下
Input.GetButtonDown("Jump")
某一个手柄键抬起
Input.GetButtonup("Jump")
某一个手柄键长按
Input.GetButton("Jump")
移动设备
- 触摸touch
(实际上的移动游戏触碰和ui有关)
if(Input.touchCount > 0)
{
Touch t1 =Input.touches[0];//位置
print(t1.position);//相对上次位置的变化
print(t1.deltaPosition);//长按相关有用
}
- 是否开启多点触控
Input.multiTouchEnabled = false;
-
陀螺仪(重力感应)
-
是否开启陀螺仪
必须开启才能正常使用
Input.gyro.enabled = true;
- 重力加速度向量
Input.gyro.gravity
- 旋转速度
Input.gyro.rotationRate
- 陀螺仪当前的旋转四元数
比如用这个角度信息来控制场景上的一个3D物体受到重力影响//手机怎么动它怎么动
Input.gyro.attitude
Screen
静态属性
- 当前屏幕分辨率
返回值是resolution
Resolution r = Screen.currentResolution;
分辨率包括屏幕 宽r.width 高r.height 刷新频率
不是unity中的分辨率,是自己电脑的分辨率
- 屏幕窗口当前宽高
当前窗口的宽高,不是设备分辨率的宽高
一般写代码要用窗口宽高做计算时就用他们
Screen.width
Screen.height
- 屏幕休眠模式
Screen.sleepTimeout = sleepTimeout. NeverSleep;
- 运行时是否全屏模式
Screen.fullScreen = true;
- 窗口模式
独占全屏 FullScreenMode. ExclusiveFullScreen
全屏窗口 FullScreenMode. FullScreenWindow
最大化窗口 FullScreenMode. MaximizedWindow
窗口模式 FullscreenMode. Windowed
Screen.fullScreenMode = FullScreenMode.Windowed;
- 移动设备屏幕转向
允许自动旋转为左横向 Home键在左
Screen.autorotateToLandscapeLeft = true;
允许自动旋转为右横向 Home键在右
Screen.autorotateToLandscapeRight = true;
允许自动旋转到纵向 Home键在下
Screen.autorotateToPortrait = true;
允许自动旋转到纵向倒着看 Home键在上
Screen.autorotateToPortraitUpsideDown = true;
指定屏幕显示方向 横向Landscape 纵向Portrait
Screen.orientation = ScreenOrientation.Landscape;
静态方法
- 设置分辨率
一般移动设备不使用
宽,高,是否全屏
Screen.SetResolution(1920,1080,false);
Camera
可编辑参数
Clear Flags
skybox 天空盒 用于3D游戏
Solid Color 颜色填充 用于2D游戏 游戏窗口 全黑全白
Depth only 只画该层,背景透明 用于多个摄像机叠加使用
Don’t Clear 不移除,覆盖渲染 不擦除上一帧内容
Culling Mask
选择性渲染部分层级
可以指定只渲染对应层级的对象
Projection
- Perspective透视模式
Field of view 视口大小 默认值60
FOV Axis 视场角轴 决定了光学仪器的视野范围
Physical Camera 物理摄像机 勾选后可以模拟真实世界中的摄像机
Focal Lengthe焦距
Sensor Type传感器类型
Sensor Size传感器尺寸
Lens Shift透镜移位
Gate Fite阐门配合
- orthographic正交摄像机
(一般用于2D游戏制作)
Size 摄制范围 默认值一般不改
Clipping Planes
裁剪平面距离
Depth
渲染顺序上的深度
多个摄像机覆盖的方式
高深度在叠加在上面
一般上层的选择depth only模式,透明,不会挡住下面
Target Texture
渲染纹理
在Project右键创建Render Texture,拖动关联
可以把摄像机画面渲染到一张图上
主要用于制作小地图
Occlusion Culling
是否启用剔除遮挡
Viewport Rect
视口范围
屏幕上绘制该摄像机视图的位置
主要用于双摄像机游戏 多人游戏
0~1相当于宽高百分比
Redering path
渲染路径
Allow HDR
是否允许高动态范围渲染
Allow MSAA
是否允许抗锯齿
Allow Dynamic Resolution
是否允许动态分辨率星现
Target Display
用于哪个显示器
主要用来开发有多个屏幕的平台游戏
代码
重要静态成员
- 获取摄像机
主摄像机的获取
要通过这种方式快速获取摄像机,那么场景上必须有一个tag为MainCamera的摄像机
Camera.main.name
- 获取摄像机的数量
Camera.allCamerasCount)
- 得到所有摄像机
Camera[] allcamera=Camera.allCameras;
-
渲染相关委托
-
摄像机剔除前处理的委托函数
Camera.onPreCull += (c)=>{};
- 摄像机渲染前处理的委托
Camera.onPreRender += (c)=>{};
- 摄像机渲染后处理的委托
Camera.onPostRender +=(c)=>{};
重要成员
界面上的参数都可以在Camera中获取、设置
Camera.main.depth = 10;
- 世界坐标转屏幕坐标
转换过后x和y对应的就是屏幕坐标,z对应的是这个3D物体里我们的摄像机有多远
通常做头顶血条相关的功能
Vector3 v = Camera.main. WorldToScreenPoint(this.transform.position);
- 屏幕坐标转世界坐标
如果不改z默认为0,转换过去的世界坐标系的点永远都是一个点,可以理解为视口相交的焦点
如果改变了z,转换过去的世界坐标的点,就是相对于摄像机前方多少个单位的横截面上的世界坐标点
Vector3 v = Input.mousePosition;
v.z = 5;
Vector3 w = Camera.main.ScreenToworldPoint(v);
核心系统
光源
光源组件
需要下载默认资源
window——>资源商店——>搜索standard标准资源——>download——>import
主要使用effect——lightcookie,lightflare
- Type光源类型
(在hierarchy中创建时候选择)
Spot 聚光灯
——Range发光范围距离
——Spot Angle光锥角度
Directionalo方向光(环境光)
Point点光源
Area面光源 只在烘焙光源有用
(烘焙——提前算好)
-
color 颜色
-
mode 光源模式
realtime
实时光源
每帧实时计算,效果好,性能肖耗大
baked
烘焙光源
事先计算好,无法动态变化
mixed
混合光源
预先计算+实时运算
-
intensity 光源亮度
-
Shadow Type阴影类型
NoShadows
关闭阴影
HardShadows
生硬阴影
SoftShadows
柔和阴影
-
Cookie 投影遮罩
-
Draw Halo 球形光环开关 光晕
-
Flare 耀斑
-
Culling Mask
剔除遮罩层,决定哪些层的对象受到该光源影响
- lndirect Multiplier
改变间接光的强度
低于1,每次反弹会使光更暗
大于1,每次反弹会使光更亮
- RealtimeShadows阴影
strength阴影暗度 0~1之间,越大越黑
Resolution阴影贴图渲染分辨率,越高越逼真。消耗越高
Bias阴影推离光源的距离
Normall Bias阴影投射面沿法线收缩距离
Near Panel渲染阴影的近裁剪面
- cookie size
方向光中有
- Render Mode 渲染优先级
Auto 运行时确定
lmportant以像素质量为单位进行渲染,效果逼真,消耗大
Not lmportant 以快速模式进行渲染
代码
面板参数都可以用代码控制
light类型
在unity关联
光面板
打开光设置面板window——rendering——lighting setting
Environment环境相关设置
- Skybox Material天空盒材质
project右键可以创建材质——着色器 太空盒 六个面
可以改变天空
- Sun Source太阳来源
不没置会默认使用场景中最亮的方向光代表太阳
- Environment Lighting环境光没置
Source环境光光源颜色
Skybox天空盒材质作为环境光颜色
Gradient可以为天空、地平线、地面单独选挥颜色和他们之间混合
lntensity Multiplier
环境光亮度
Ambient Mode全局光照模式
只有启用了实时全局和全局烘焙时才有用
Realtime(已弃用)
Baked
其他
- fog 雾的开关
color颜色
mode雾计算模式
——Linear
随距离线性增加
Start离摄像机多远开始有雾
End离摄像机多远完全遮挡
——Exponential
随距离指数增加
Density强度
——Exponential Qquare
随距离比指数更快的增加
Density强度
-
Halo Texturee光源周围光环的纹理
-
Halo Strength光环可见性
-
Flare Fade Speedo
耀斑淡出时间
最初出现之后淡出的时间
-
Flare Strengthe耀斑可见性
-
Spot Cookie聚光灯剪影纹理
物理系统之碰撞检测
碰撞产生的必要条件:两个物体都有碰撞器,至少
一个物体有刚体
刚体
rigidbody
受到力的作用
- Mass
质量(默认为千克)
质量越大惯性越大
- Drag
空气阻力
根据力移动对象时,影响对象的空气阻力大小
0表示没有空气阻力
- Angular Drag
根据扭矩旋转对象时,影响对象旋转的空气阻力大小。
0表示没有空气阻力。
- Use Gravity
是否受重力影响
- ls Kinematic
如果启用此选项,则对象将不会被物理引擎驱动
只能通过(Transform)对其进行操作。
对于移动平台,或者如果要动画化附加了HingeJoint的刚体,此属性将非常有用。
- Interpolate
插值运算
让刚体物体移动更平滑
和帧更新间隔时间有关,要把物理帧更新时间变长时有用
——None
不应用插值运算
——lnterpolate
根据前一帧的变换来平滑变换。
——Extrapolate
差值运算
根据下一帧的估计变换来平滑变换。
- Collision Detection(碰撞检测模式)
用于防止快速移动的对象穿过其它对象而不检测碰撞
——Discrete(离散检测)
对场景中的所有其他碰撞体使用离散碰撞检测。
其他碰撞体在测试碰撞时会使用离散撞检测。
用于正常碰撞(这是默认值)
——Continuous(连续检测)
对动态碰撞体(具有刚体)使用离散碰撞检测
并对静态碰撞体(没有刚体)使用连续碰撞检测。
设置为连续动态(Continuous Dynamic)的刚体将在测试与该刚体的碰撞时使用连续碰撞检测。
(此属性对物理性能有很大影响,如果没有快速对象的碰撞问题,请将其保留为Discrete设置)
其他刚体将使用离散碰撞检测。
——Continuous Dynamic(连续动态检测)性能消耗高
对设置为连续(Continuous)和连续动态(Continuous Dynamic)碰撞的游戏对象使用连续碰撞检测。还将对静态碰撞体(没有刚体)使用连续碰撞检测。
对于所有其他碰撞体,使用离散碰撞检测。
用于快速移动的对象。
——continuous Speculative(连续推测检测)
对刚体和碰撞体使用推测性连续碰撞检测。
该方法通常比连续碰撞检测的成本更低。
性能消耗关系
连续动态检测>连续推测检测>连续检测>离散检测
Continuous Dynamic > Continuous Speculativec > Continuous > Discrete
- Constraints约束
对刚体运动的限制
——Freeze Position
有选择地停止刚体沿世界X、Y和Z轴的移动。
——Freeze Rotation
有选择地停止刚体围绕局部X、Y和Z轴旋转。
碰撞器
collider
表示3D物体的体积
添加碰撞器:物体add component——collider——分3D和2D
3D碰撞器的种类:1.盒状2.球状3.胶囊4.网格5.轮胎6.地形
共同参数:
- ls Trigger
是否是触发器
如果启用此属性,则该碰撞体将用于触发事件,并被物理引擎忽略
主要用于进行没有物理效果的碰撞检测
一般用在可以穿越的物体,魔法,剑
- Material
物理材质,可以确定碰撞体和其它对象碰撞时的交互(表现)方式。
- Center
碰撞体在对象局部空间中的中心点位置
- edit collider
可以编辑碰撞器
常用碰撞器
- BoxCollider
盒状碰撞器
——Size
碰撞体在X、Y、Z方向上的大小
- Sphere Collider
球状碰撞器
——Radius
球形碰撞体的半径大小
- Capsule Collider
胶囊碰撞器
——Radius
胶囊体的半径
——Height
胶囊体的高度
——Direction
胶囊体在对象局部空间中的轴向
异形物体 使用多种碰撞器组合
刚体对象的子对象碰撞器信息,参与碰撞检测
子对象的碰撞器组合影响
不常用碰撞器
- Mesh Collider网格碰撞器
根据面来计算碰撞,性能消耗大,准确性高
——Convex
勾选此复选框可启用Convex。
如果启用此属性,该Mesh Collider将与其他Mesh Collider "发生碰撞。
Convex Mesh Collider最多255个三角形。
——Cooking Options
启用或禁用影响物理引擎对网格处理方式的网格烹制选项。
——Mesh
引用需要用于碰撞的网格。
-
wheel Collider环状碰撞器
轮胎碰撞器
在赛车游戏里有用
和刚体父对象配合使用,轮胎子对象
父对象质量要足够大,不然会弹飞
- Terrain Collider地形碰撞器
效率较低,使用少
——Terrain Data
地形数据
——Enable Tree Colliders
选中此属性时,将启用树碰撞体
物理材质
碰撞器上面使用材质
创建材质:project窗口右键——physical material
- Dynamic Friction
在移动时使用的摩擦力。
通常为0到1之间的值。
值为0就像冰一样,值为1将使对象迅速静止(除非用很大的力或重力推动对象)
- Static Friction
当对象静止在表面上时使用的摩擦力。
通常为0到1之间的值。
值为0就像冰一样,值为1将导致很难让对象移动。
- Bounciness
表面的弹性
值为0将不会反弹。
值为1将在反弹时不产生任何能量损失,预计会有一些近似值,但可能只会给模拟增加少量能量。
- Friction Combine
两个碰撞对象的摩擦力的组合方式。
-Average
对两个摩擦值求平均值。
-Minimum
使用两个值中的最小值。
-Maximum
使用两个值中的最大值。
-Multiply
两个摩擦值相乘。
- unce Combine
两个碰撞对象的弹性的组合方式。
其模式与Friction Combine模式相同
碰撞检测函数
知识点回顾
1.如何让两个游戏物体之间产生碰撞(至少1个刚体和两个碰撞器)
2.如何让两个物体之间碰撞时表现出不同效果(物理材质)
3.触发器的作用是什么(让两个物体碰撞没有物理效果,只进行碰撞处理)
碰撞和触发响应函数属于特殊的生命周期函数也是通过反射调用
物理碰撞检测响应函数
- 碰撞触发接触时,会自动执行这个函数
private void OnCollisionEnter(Collision collision){}
- 碰撞结束分离时,会自动执行的函数
private void OnCollisionExit(Collision collision){}
- 两个物体相互接触摩擦时,会不停的调用该函数
private void OnCollisionStay(Collision collision){}
Collision类型的参数
包含了碰到自己的对象的相关信息
只要得到了碰撞到的对象的任意一个信息,就可以得到它的所有信息
关键参数:
1.碰撞到的对象碰撞器的信息
collision.collider
2.碰撞对象的依附对象(Gameobject)
collision.gameObject
3.碰撞对象的依附对象的位置信息
collision.transform
4.触碰点数相关
collision.contactCount
接触点具体的坐标
ContactPoint[] pos = collision. contacts;
触发器检测响应函数
接触 穿越 参数是collider类型
- 触发开始的函数
当第一次接触时会自动调用
private void OnTriggerEnter(Collider other){}
- 触发结束的函数
当水乳相融的状态结束时,会调用一次
private void OnTriggerExit(Collider other){}
- 触发状态持续
当两个对象水乳相融的时候,会不停调用
private void OnTriggerStay (Collider other){}
要明确什么时候会响应函数
1.只要挂载的对象、能和别的物体产生碰撞或者触发那么对应的这6个函数就能够被响应
2.6个函数不是都得写,根据需求选择
3.如果是一个异形物体,刚体在父对象上,如果你想通过子对象上挂脚本检测碰撞是不行的,必须挂载到这个刚体父对象上才行
4.要明确物理碰撞和触发器响应的区别
碰撞和触发器函数都可以写成虚函数,在子类去重写逻辑
一般会把想要重写的碰撞和触发函数写成保护类型的
没有必要写成public,因为不会自己手动调用
都是Unity/通过反射,帮助我们自动调用的
刚体加力
刚体自带添加力的方法
给刚体加力的目标就是
让其有一个速度朝向某一个方向移动
- 1.首先应该获取刚体组件
RigidBody rigidBody= this.GetComponent<Rigidbody>();
- 2.添加力
加力过后对象是否停止移动,是由阻力决定的
如果阻力为0,那给了一个力过后始终不会停止运动
即使有阻力也希望对象一直动那你就一直“推”就行了:写在update里面
——相对世界坐标
世界坐标系z轴正方向加了一力:
rigidBody.AddForce(Vector3.forward* 10);
让对象相对于自己的面朝向动:
rigidBody.AddForce(this.transform.forward * 10);
——相对本地坐标
rigidBody.AddRelativeForce(Vector3.forward * 10);
- 3.添加扭矩力,让其旋转
——世界坐标
rigidBody.AddTorque(Vector3.up * 10);
——相对本地坐标
rigidBody.AddRelativeTorque(Vector3.up * 10);
- 4.直接改变速度
这个速度方向是相对于世界坐标系的
用的少
rigidBody.velocity = Vector3.forward* 5;
5.模拟爆炸效果
模拟爆炸的力一定是所有希望产生爆炸效果影响的对象都需要得到他们的刚体来执行这个方法才能都有效果
rigidBody.AddExplosionForce( 100,Vector3.zero,10);
力的模式
第二个参数:力的模式
计算方式不同,最终的移动速度就会不同
rigidBody . AddForce(Vector3.forward * 10,ForceMode.Acceleration);
——动量定理
Ft =mv
v=Ft/m;
F:力
t:时间
m:质量
v:速度
- 1.Acceleration
给物体增加一个持续的加速度,忽略其质量
v = Ft/m
F: (0,0,10)
t:0.02s(时间设置中设置的)
m:默认为1
V = 10*0.02/ 1 = 0. 2m/s
每物理帧移动0.2m/s*0.02 = 0.004m
- 2.Force
给物体添加一个持续的力,与物体的质量有关(正常用)
v = Ft/m
F:(0,0,10)
t:0.02s
m: 2kg
v = 10*0.02/ 2 =0. 1m/s
每物理帧移动0.1m/s*0.02 = 0.002m
- 3.Impulse
给物体添加一个瞬间的力,与物体的质量有关,忽略时间,默认为1
v= Ft/m
F:(0,0,10)
t:默认为1
m : 2kg
V = 10*1/ 2 = 5m/s
每物理帧移动5m/s*0.02 = 0.1m
4.velocityChange
给物体添加一个瞬时速度,忽略质量,忽略时间
v= Ft/m
F:(0,0,10)
t:默认为1
m:默认为1
v =10*1/ 1 = 10m/s
每物理帧移动10m/s*0.02= 0.2m
力场脚本
add component——>
constant force脚本
刚体的休眠
节省能耗
//获取刚体是否处于休眠状态,如果是
if (rigidBody.IsSleeping())
{
//就唤醒它
rigidBody.Wakeup();
}
音效系统
unity基础
- 3D数学
数学计算公共类Mathf
三角函数
Unity中的坐标系
Vector3向量
向量模长和单位向量,向量加减乘除
向量点乘,向量差乘,差值运算
Quaternion四元数
- Mono中的重要内容
延迟函数
协同程序
协同程序原理
- Resources资源动态加载
Unity中特殊文件夹
Resources同步加载
Resources异步加载
Resources卸载资源
-
场景异步切换
-
辅助功能Linerender
-
核心系统
物理系统之范围检测
物理系统之射线检测
——
NGUI
XML
配置文件
unity核心
认识模型的制作流程
-
2D相关
-
图片导入相关设置
参数设置—纹理类型
参数设置—纹理形状
参数设置—高级设置
参数设置一平铺拉伸
参数设置一平台设置(非常重要】 -
Sprite
Sprite Editor
Sprite Renderer
Sprite Creator
Sprite Mask
Sorting Group图集制作
-
2D物理系统
刚体
碰撞器
物理材质
恒定力
效应器 -
Spriteshape
Sprite Shape Profile精灵形状概述文件
Sprite Shape RendererSprite Shape Controller精灵形状渲染器和控制器 -
Tilemap瓦片地图
瓦片资源
瓦片调色器窗口使用
瓦片地图关键脚本和碰撞器官方拓展包导入
官方拓展包—新增瓦片类型官方拓展包—新增笔刷类型
代码控制相关
-
-
动画基础
Animation动画窗口
Animator动画状态机
- 2D动画
序列帧动画
2D骨骼动画
2D Animation
Spine
- 模型导入相关设置
模型导入概述
Model模型页签
Rig操纵(骨骼)页签
Animation动画页签
Materials材质纹理页签
- 3D动画相关
3D动画的使用
动画分层和遮罩
动画1D混合
动画2D混合
动画子状态机
动画lk控制
动作目标四配
Statemachinebehaviour状态机行为脚本
状态机复用
-
角色控制器
-
导航寻路系统
导航寻路系统概述
导航网格生成
导航网格寻路组件
导航网格外连接组件
导航网格动态障碍组件
——
UGUI
json配置表
unity进阶
- 核心系统
输入系统Input System
资源寻址系统Addressable
物理系统之较链和布料
粒子系统
光照系统
Dots
Time Line
地形系统
- 功能相关
Scriptable Object
Animation Curve
Www和Unity Web Request
C#相关
- 插件相关
Text Mesh Pro
Do Tween
- 优化相关
优化指什么
性能检测窗口
静态批处理
动态批处理
网格合并
——
FairyGUI
加力过后对象是否停止移动,是由阻力决定的
如果阻力为0,那给了一个力过后始终不会停止运动
即使有阻力也希望对象一直动那你就一直“推”就行了:写在update里面
——相对世界坐标
世界坐标系z轴正方向加了一力:
rigidBody.AddForce(Vector3.forward* 10);
让对象相对于自己的面朝向动:
rigidBody.AddForce(this.transform.forward * 10);
——相对本地坐标
rigidBody.AddRelativeForce(Vector3.forward * 10);
- 3.添加扭矩力,让其旋转
——世界坐标
rigidBody.AddTorque(Vector3.up * 10);
——相对本地坐标
rigidBody.AddRelativeTorque(Vector3.up * 10);
- 4.直接改变速度
这个速度方向是相对于世界坐标系的
用的少
rigidBody.velocity = Vector3.forward* 5;
5.模拟爆炸效果
模拟爆炸的力一定是所有希望产生爆炸效果影响的对象都需要得到他们的刚体来执行这个方法才能都有效果
rigidBody.AddExplosionForce( 100,Vector3.zero,10);
力的模式
第二个参数:力的模式
计算方式不同,最终的移动速度就会不同
rigidBody . AddForce(Vector3.forward * 10,ForceMode.Acceleration);
——动量定理
Ft =mv
v=Ft/m;
F:力
t:时间
m:质量
v:速度
- 1.Acceleration
给物体增加一个持续的加速度,忽略其质量
v = Ft/m
F: (0,0,10)
t:0.02s(时间设置中设置的)
m:默认为1
V = 10*0.02/ 1 = 0. 2m/s
每物理帧移动0.2m/s*0.02 = 0.004m
- 2.Force
给物体添加一个持续的力,与物体的质量有关(正常用)
v = Ft/m
F:(0,0,10)
t:0.02s
m: 2kg
v = 10*0.02/ 2 =0. 1m/s
每物理帧移动0.1m/s*0.02 = 0.002m
- 3.Impulse
给物体添加一个瞬间的力,与物体的质量有关,忽略时间,默认为1
v= Ft/m
F:(0,0,10)
t:默认为1
m : 2kg
V = 10*1/ 2 = 5m/s
每物理帧移动5m/s*0.02 = 0.1m
4.velocityChange
给物体添加一个瞬时速度,忽略质量,忽略时间
v= Ft/m
F:(0,0,10)
t:默认为1
m:默认为1
v =10*1/ 1 = 10m/s
每物理帧移动10m/s*0.02= 0.2m
力场脚本
add component——>
constant force脚本
刚体的休眠
节省能耗
//获取刚体是否处于休眠状态,如果是
if (rigidBody.IsSleeping())
{
//就唤醒它
rigidBody.Wakeup();
}
音效系统
unity基础
- 3D数学
数学计算公共类Mathf
三角函数
Unity中的坐标系
Vector3向量
向量模长和单位向量,向量加减乘除
向量点乘,向量差乘,差值运算
Quaternion四元数
- Mono中的重要内容
延迟函数
协同程序
协同程序原理
- Resources资源动态加载
Unity中特殊文件夹
Resources同步加载
Resources异步加载
Resources卸载资源
-
场景异步切换
-
辅助功能Linerender
-
核心系统
物理系统之范围检测
物理系统之射线检测
——
NGUI
XML
配置文件
unity核心
认识模型的制作流程
-
2D相关
-
图片导入相关设置
参数设置—纹理类型
参数设置—纹理形状
参数设置—高级设置
参数设置一平铺拉伸
参数设置一平台设置(非常重要】 -
Sprite
Sprite Editor
Sprite Renderer
Sprite Creator
Sprite Mask
Sorting Group图集制作
-
2D物理系统
刚体
碰撞器
物理材质
恒定力
效应器 -
Spriteshape
Sprite Shape Profile精灵形状概述文件
Sprite Shape RendererSprite Shape Controller精灵形状渲染器和控制器 -
Tilemap瓦片地图
瓦片资源
瓦片调色器窗口使用
瓦片地图关键脚本和碰撞器官方拓展包导入
官方拓展包—新增瓦片类型官方拓展包—新增笔刷类型
代码控制相关
-
-
动画基础
Animation动画窗口
Animator动画状态机
- 2D动画
序列帧动画
2D骨骼动画
2D Animation
Spine
- 模型导入相关设置
模型导入概述
Model模型页签
Rig操纵(骨骼)页签
Animation动画页签
Materials材质纹理页签
- 3D动画相关
3D动画的使用
动画分层和遮罩
动画1D混合
动画2D混合
动画子状态机
动画lk控制
动作目标四配
Statemachinebehaviour状态机行为脚本
状态机复用
-
角色控制器
-
导航寻路系统
导航寻路系统概述
导航网格生成
导航网格寻路组件
导航网格外连接组件
导航网格动态障碍组件
——
UGUI
json配置表
unity进阶
- 核心系统
输入系统Input System
资源寻址系统Addressable
物理系统之较链和布料
粒子系统
光照系统
Dots
Time Line
地形系统
- 功能相关
Scriptable Object
Animation Curve
Www和Unity Web Request
C#相关
- 插件相关
Text Mesh Pro
Do Tween
- 优化相关
优化指什么
性能检测窗口
静态批处理
动态批处理
网格合并
——
FairyGUI
2进制配置