Unity引擎入门
一、Scene场景和Hierarchy层级窗口
1、Scene场景
(1)新建
Ctrl+N / File -> New Scene
(2)场景叠加
直接将Scene拖入Hierarchy窗口中
(3)
2、Scene场景窗口
(1)工具栏
(2)坐标
以屏幕为参照物
垂直屏幕向内为Z正方向
平行屏幕向右为X正方向
平行屏幕向上为Y正方向
(3)常用操作
3、Hierarchy中的快捷键
F2:对象改名
Ctrl+C:复制
Ctrl+V:粘贴
Ctrl+D:克隆一个
Delete:删除
二、Game和Project窗口
1、Game窗口按钮
2、Project窗口功能
1.窗口设置
2.创建相关资源文件
3.查找
4.按资源类型查找
5.按名字查找
3、可用资源类型
图片格式:jpg、png、tga
模型格式:fbx、max、maya
音效:wav、mp3、ogg
文本:txt、json、bytes
视频:mp4
三、Inspector检查窗口和Console控制台
1、Inspector
//强制序列化字段,把一个对象保存到文件或数据库字段中去
//显示protected、private的变量
[SerializeField]
protected int x;
//隐藏public的变量
[HideInInspector]
public int z;
//Inspector面板默认不能显示字典、自定义类
//结构体、自定义类前面加 [System.Serializable] 可以显示,字典类都无法显示
public MyStruct ms;
//其他特性
[Header("[Header(分组特性)]")]
public int header;
[Tooltip("信息")] //鼠标悬停显示信息
public int tp;
[Range(0,10)] //设置范围
public float range;
[Multiline(4)] //多行文本输入,无滚动条
public string multiLineStr;
[TextArea(2, 4)] //文本输入,最少两行,最多四行,带滚动条
public string textArea;
//[ContextMenuItem("右键显示的文本", "方法名")]
[ContextMenuItem("重置钱", "ResetMoney")]
public int money;
public void ResetMoney() {
money = 10;
}
//在脚本组件右侧省略符号里添加功能按钮
[ContextMenu("测试方法")]
public void testFunc() {
print("测试方法");
}
2、Console控制台按钮
1.清空控制台
2.相同内容折叠显示
3.运行时清空
4.构建时清空
5.报错暂停运行
6.是否显示错误信息
7.是否显示警告信息
8.是否显示打印信息
四、工具栏和父子关系
1、工具栏
(1)GameObject
操作 | 含义 |
---|---|
Move To View | 选中物体放到场景中视野相机的中心 |
Align With View | 选中物体放到场景中视野相机的位置 (设置相机位置) |
Align View To Selected | 看向物体的某一轴正方向 |
Toggle Active State | 切换物体激活状态 |
(2)父子关系
五、生命周期函数
六、MonoBehavior常用API
1、成员变量
//打印脚本依附的游戏对象
print(this.gameObject);
// = print(gameObject);
//脚本依附的游戏对象的transform组件
print(this.transform.eulerAngles);//角度
print(this.transform.position);//位置
print(this.transform.lossyScale);//缩放
// = print(transform);
//可获取其他脚本依附的对象
Mono m=new Mono();
print(m.gameObject);
//此脚本激活状态
this.enabled = true;
2、静态方法
(1)获取挂载在gameobject上的单个脚本
//通过脚本名称
MonoTest monoTest = this.GetComponent("MonoTest") as MonoTest;
//通过脚本类型
monoTest = this.GetComponent(typeof(MonoTest)) as MonoTest;
//通过泛型
monoTest = this.GetComponent<MonoTest>();
若一个物体挂载多个相同脚本,不能确定获取的是哪个。
(2)得到多个脚本
//通过数组
Mono[] mono = this.GetComponents<Mono>();
//通过列表
List<Mono> monos= new List<Mono>();
this.GetComponents<Mono>(monos);
一般不挂多个相同脚本
(3)得到子对象挂载的脚本,默认同时会从获得自身的该脚本
//参数为true,指子对象或该脚本失活时也获得其对应脚本
//单个
MonoTest mono1 = this.GetComponentInChildren<MonoTest>(true);
print(mono1);
//多个,数组、列表
MonoTest[] mono = this.GetComponentsInChildren<MonoTest>();
List<MonoTest> monos = new List<MonoTest>();
this.GetComponentsInChildren<MonoTest>(monos);
方法里有默认参数为false,指对象或脚本失活就不获取脚本
(4)得到父对象脚本,大致同子对象,无失活参数,因为父对象失活,子对象必失活。
5、尝试获取脚本
MonoTest monoTest;
if(this.TryGetComponent<MonoTest>(out monoTest)) {
print(monoTest);
}
更加安全,防止null
七、GameObject常用变量及方法
1、成员变量
//名字
print(this.gameObject.name);
this.gameObject.name = "newname";
print(this.gameObject.name);
//是否激活
print(this.gameObject.activeSelf);
//是否是静态
print(this.gameObject.isStatic);
//层级
print(this.gameObject.layer);
//标签
print(this.gameObject.tag);
//transform
print(this.gameObject.transform.position);
2、静态方法
GameObject gameObject;
GameObject[] gameObjects;
(1) 创建自带几何体物体
gameObject = GameObject.CreatePrimitive(PrimitiveType.Cube);
gameObject.name = "脚本创建的立方体";
(2)查找单个对象,无法找到失活的对象
//通过姓名
gameObject = GameObject.Find("name");
//通过tag
gameObject = GameObject.FindWithTag("Player");
// = GameObject.FindGameObjectWithTag("Player");
若场景存在多个满足条件的对象,无法确定找到的是哪个。
得到某一对象目前方法:①从Inspector面板拖来进行关联;②通过以上方法获取。
(3)查找多个对象,只能通过tag,找到激活状态的对象
gameObjects = GameObject.FindGameObjectsWithTag("Player");
//除此之外,其他查找方法由UnityEngine的Object类提供
MonoTest monoTest = GameObject.FindObjectOfType<MonoTest>();
由UnityEngine的Object类提供的方法效率更低,遍历游戏对象,再遍历脚本
(4)实例化对象
GameObject go=GameObject.Instantiate(prefab);
(5)删除对象或脚本
//1、异步删除,不会马上删除,而是添加移除标志,在下一帧进行移除并从内存中删除
GameObject.Destroy(go);
GameObject.Destroy(go,5f);//延迟五秒
//2、马上删除
GameObject.DestroyImmediate(go);
//3、过场景不移除
//作用:过场景时,对象默认都会被移除,此方法可保留作为参数的对象
GameObject.DontDestroyOnLoad(this.gameObject);
3、成员方法
(1)创建空物体
GameObject gameObject1 = new GameObject();
GameObject gameObject2 = new GameObject("gameObject2");
//添加名字+脚本
GameObject gameObject3 = new GameObject("gameObject3",typeof(MonoTest));
(2)为对象动态添加脚本
//原理:继承MonoBehaviour不能new,可直接挂载
MonoTest monoTest1 = gameObject1.AddComponent(typeof(MonoTest)) as MonoTest;
MonoTest monoTest2 = gameObject1.AddComponent<MonoTest>();
(3)获取脚本的方法和继承MonoBehaviour类的方法一样
(4)标签比较
if (gameObject1.CompareTag("Palyer")) {
print("gameObject1's tag is Player");
}
if (gameObject1.tag=="Palyer") {
print("gameObject1's tag is Player");
}
(5)对象激活失活
gameObject2.SetActive(false);
(6)对象之间通信
//通知自己调用函数以及传参
gameObject3.SendMessage("TestFunc");
gameObject3.SendMessage("TestFunc",100);
//通知自己和子对象
gameObject3.BroadcastMessage("TestFunc");
//通知自己和父对象
gameObject3.SendMessageUpwards("TestFunc");
效率低避免使用
八、Time
主要用于游戏中参与位移计算、记时、时间暂停等
1、 时间缩放比例
Time.timeScale = 0; //时间停止
Time.timeScale = 1; //恢复正常
Time.timeScale = 2; //2倍速
2、帧间隔时间
帧间隔时间:最近的一帧 用了多长时间(秒)
//受scale影响
print("帧间隔时间" + Time.deltaTime);
//不受scale影响的帧间隔时间
print("不受scale影响的帧间隔时间" + Time.unscaledDeltaTime);
帧间隔时间 主要是用来计算位移
路程 = 时间*速度
根据需求 选择参与计算的间隔时间
如果希望 游戏暂停时就不动的 那就使用deltaTime
如果希望 不受暂停影响 unscaledDeltaTime
3、游戏开始到现在的时间
它主要用来计时 单机游戏中计时
//受scale影响
print("游戏开始到现在的时间:" + Time.time);
//不受scale影响
print("不受scale影响的游戏开始到现在的时间:" + Time.unscaledTime);
4、物理帧间隔时间 FixedUpdate
//受scale影响
print(Time.fixedDeltaTime);
//不受scale影响
print(Time.fixedUnscaledDeltaTime);
九、Transform
1、Vector3基础
//Vector3主要是用来表示三维坐标系中的 一个点 或者一个向量
Vector3 v = new Vector3();
v.x = 10; v.y = 10; v.z = 10;
//只传xy 默认z是0
Vector3 v2 = new Vector3(10, 10);
//一步到位
Vector3 v3 = new Vector3(10, 10, 10);
Vector3 v4;
v4.x = 10; v4.y = 10; v4.z = 10;
//Vector的基本计算 + - * /
Vector3 v1 = new Vector3(1, 1, 1);
Vector3 v12 = new Vector3(2, 2, 2);
// 对应用x+或者-x.....
print(v1 + v12);
print(v1 - v12);
print(v1 * 10);
print(v12 / 2);
//常用
print(Vector3.zero);//000
print(Vector3.right);//100
print(Vector3.left);//-100
print(Vector3.forward);//001
print(Vector3.back);//00-1
print(Vector3.up);//010
print(Vector3.down);//0-10
//计算两个点之间的距离的方法
print(Vector3.Distance(v1, v12));
2、Position
(1)位置
//通过position得到的位置是相对于世界坐标系的原点的位置
//如果对象有父子关系,且父对象位置不在原点,那么和面板上的就不一样
print(this.transform.position);
//相对父对象
//以面板坐标为准来进行位置设置,一定是通过localPosition来进行设置的
print(this.transform.localPosition);
//他们两个可能出现是一样的情况
//1.父对象的坐标 就是世界坐标系原点0,0,0
//2.对象没有父对象
(2)位置赋值
//注意:位置的赋值不能直接改变x,y,z 只能整体改变
//不能单独改 x y z某一个值,即this.transform.position.x = 10;
this.transform.position = new Vector3(10, 10, 10);
this.transform.localPosition = Vector3.up * 10;
//如果只想改一个值x y和z要保持原有坐标一致
//1.直接赋值
this.transform.position = new Vector3(19, this.transform.position.y, this.transform.position.z);
//2.先取出来 再赋值
//虽然不能直接改 transform的 xyz 但是 Vector3是可以直接改 xyz的
//所以可以先取出来改Vector3 再重新赋值
Vector3 vPos = this.transform.localPosition;
vPos.x = 10;
this.transform.localPosition = vPos;
(3)朝向
//对象当前的面朝向 z轴
print(this.transform.forward);
//对象当前的头顶朝向 y
print(this.transform.up);
//对象当前的右手边 x
print(this.transform.right);
(4)位移
方法一:路程 = 方向 * 速度 * 时间
this.transform.position += Vector3.forward * 1 * Time.deltaTime;
this.transform.position += this.transform.forward * 1 * Time.deltaTime;
方法二:API
参数一:表示位移多少,路程 = 方向 * 速度 * 时间
参数二:表示相对坐标系,默认该参数是相对于自己坐标系的
//相对于世界坐标系的Z轴正方向移动
this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.World);
//相对于世界坐标的自己的面朝向移动
this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.World);
//以自己的坐标系为世界坐标系,叠加自己的面朝向
this.transform.Translate(this.transform.forward * 1 * Time.deltaTime, Space.Self);
//相对于自己的坐标系下的Z轴正方向移动
this.transform.Translate(Vector3.forward * 1 * Time.deltaTime, Space.Self);
(5)总结
vector3.forward的值永远等于(0,0,1)。
transform.forward的值则等于当前物体的自身坐标系z轴在指定参数坐标上指向(默认世界坐标系)。