【笔记】UnityAPI学习笔记

前言

UnityAPI学习笔记

游戏对象脚本

  • 游戏对象脚本必须继承自MonoBehaviour
Script.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Script : MonoBehaviour
{
void Start()
{
...
}

void Update()
{
...
}
}

脚本的消息函数

  • 消息函数实质上就是回调函数

  • 消息函数执行顺序:第一个游戏对象的Awake()=>第二个游戏对象的Awake()=>…=>第一个游戏对象的Start()=>第二个游戏对象的Start()=>…=>每个游戏对象的Update()=>…

Awake():游戏对象初始化时调用,在Start()之前执行,无论游戏对象是否被禁用都会被调用,只会执行一次
Start():游戏对象初始化时调用,在Awake()之后执行,只有游戏对象启用时才会被调用,只会执行一次
Update():每当游戏对象帧更新时调用
OnEnable():每当每当游戏对象启用时调用
OnDisable():每当游戏对象禁用时调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void Start()
{
...
}

void Update()
{
...
}

void Awake()
{
...
}

void OnEnable()
{
...
}

void OnDisable()
{
...
}

脚本参数

  • 通过为类定义权限为public的属性来定义脚本参数

    • 属性名通常采用小驼峰命名
    • 属性值会作为脚本参数的默认值
  • 脚本参数会在Unity编辑器的检查器(Inspector)中显示,并可以修改

    • 在Unity编辑器中,脚本参名会自动根据驼峰拆分单词,每个单词首字母大写并用空格隔开

[ Tooltip("文本内容") ]:当鼠标悬浮在Unity编辑器的脚本参数名上时显示的提示内容

数据类型

值类型

intfloatboolstring

结构体类型

Vector3Color
GameObject:在检查器中通过拖拽的方式传递其他游戏对象,该游戏对象会作为参数
AudioSource:在检查器中通过拖拽的方式传递其他游戏对象,此时该游戏对象的对应类型组件会作为参数
其他脚本类名:在检查器中通过拖拽的方式传递其他游戏对象,此时该游戏对象的对应脚本文件会作为参数(因为脚本的本质就是一个组件)
AudioClip:在检查器中通过拖拽的方式传递音频文件

Script.cs
1
2
3
4
5
public class Script : MonoBehaviour
{
[ Tooltip("文本内容") ]
public 数据类型 脚本参数名 = 默认值;
}

主控脚本

  1. 创建一个空游戏对象(Empty)
  • +->Create Empty
  1. 为这个空游戏对象添加游戏对象脚本,在脚本中通过Awake()全局初始化
  2. 强制提升优先级
  • Edit->Project Settings->Script Execution Order->修改这个空游戏对象的优先级(数值越小,优先级越大)
1
2
3
4
5
6
7
8
9
10
11
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainScript : MonoBehaviour
{
void Awake()
{
...
}
}

输出语句

1
Debug.Log("");

指定帧率

  • 要求Unity尽可能在指定帧率下帧更新游戏对象
1
Application.targetFrameRate = 60;

随机数

  • 获取范围为[1,2)的随机整数
1
int num = Random.Range(1, 2);

游戏对象(GameObject)

获取游戏对象

获取当前游戏对象

1
GameObject gameObject = this.gameObject;

通过游戏对象名查找游戏对象

<name>:游戏对象名,如果有多个相同名称的游戏对象,则需要使用绝对路径

<name>:相当于在./目录下查找名为<name>的游戏对象
/<name>:相当于在/根目录下查找名为<name>的游戏对象
<dir>/<name>:相当于在<dir>目录下查找名为<name>的游戏对象

1
GameObject gameObject = GameObject.Find("<name>");

获取游戏对象名称

1
string name = gameObject.name;

获取当前游戏对象名称

1
string name = this.gameObject.name;
  • 简写
1
string name = this.name;

隐藏游戏对象

visibletrue表示显示,false表示隐藏

1
bool visible = gameObject.activeSelf;
1
gameObject.SetActive(false);

变换组件(Transform)

  • 每个游戏对象一定都有一个变换组件

获取游戏对象的变换组件

1
Transform transform = gameObject.transform;

获取当前游戏对象的变换组件

1
Transform transform = this.gameObject.transform;
  • 简写
1
Transform transform2 = this.transform;

位置(Position)

相对于世界原点的位置三维向量

1
Vector3 vector3 = transform.position;
1
transform.position = new Vector3(<x>, <y>, <z>);

相对于本地原点的位置三维向量

  • 相对于父对象的位置
1
Vector3 vector3 = transform.localPosition;
1
transform.position = new Vector3(<x>, <y>, <z>);

位置偏移方法

<dx>:x轴坐标偏移量
<dy>:y轴坐标偏移量
<dz>:z轴坐标偏移量

Space.Self:缺省值,参考本地坐标系偏移
Space.World:参考世界坐标系偏移

1
transform.Translate(<dx>, <dy>, <dz>);
1
transform.Translate(<dx>, <dy>, <dz>, Space.Self);
1
2
3
Verctor3 vector3 = new Vector3(<dx>, <dy>, <dz>);

transform.Translate(vector3, Space.Self);

旋转(Rotation)

相对于世界原点的旋转三维向量

  • 欧拉角(EulerAngle)
1
Verctor3 vector3 = transform.eulerAngle;
1
transform.eulerAngle = new Vector3(<x>, <y>, <z>);

相对于本地原点的旋转三维向量

  • 欧拉角(EulerAngle)
1
Verctor3 vector3 = transform.localEulerAngle;
1
transform.localEulerAngle = new Vector3(<x>, <y>, <z>);

角度偏移方法

1
transform.Rotate(<dx>, <dy>, <dz>);

将游戏对象z轴朝向另一个游戏对象

1
2
3
4
Transform transform = this.gameObject.transform;
Transform otherTransform;

transform.LookAt(otherTransform);

通过变换组件获取游戏对象名称

1
string name = transform.gameObject.name;
  • 简写
1
string name = transform.name;

三维向量(Vector3)

创建三维向量

1
Vector3 vector3 = new Vector3(<x>, <y>, <z>);
1
Vector3 vector3 = new Vector3(<x>, <y>, <z>, Space.Self);

常量

(0, 0, 0)

1
Verctor3 verctor3 = Vector3.zero;

(0, 1, 0)

1
Vector3 vector3 = Vector3.up;

(0, 0, 1)

1
Vector3 vector3 = Vector3.forward;

(1, 0, 0)

1
Vector3 vector3 = Vector3.right;

向量的属性

位置属性

1
float x = vector3.x;
1
float y = vector3.y;
1
float z = vector3.z;

向量运算

1
2
3
4
Verctor3 verctor31;
Verctor3 verctor32;

Verctor3 result = verctor31 + verctor32;
1
2
3
4
Verctor3 verctor31;
Verctor3 verctor32;

Verctor3 result = verctor31 - verctor32;
  • 标准乘法
1
2
3
4
Verctor3 verctor31;
Verctor3 verctor32;

Verctor3 result = verctor31 * verctor32;
  • 点积
1
2
3
4
Verctor3 verctor31;
Verctor3 verctor32;

Verctor3 result = Verctor3.Dot(verctor31, verctor32);
  • 差积
1
2
3
4
Verctor3 verctor31;
Verctor3 verctor32;

Verctor3 result = Verctor3.Cross(verctor31, verctor32);

向量的长度

1
int magnitude = vector3.magnitude;

计算两个向量的距离

1
2
3
4
5
Vector3 vector3 = this.gameObject.transform.position;
Vector3 otherVector3;
Verctor3 direction = otherVector3 - vector3;

float distance = direction.magnitude;
1
float distance = Vector3.Distance(vector3, otherVector3);

标准化向量

  • 缩放一个变量,使其长度为1
1
Verctor3 verctor3 = vector3.normalized;

三位向量转换为字符串

1
string result = vector3.toString("F3");

游戏时间(Time)

游戏对象初始化到现在的时间差

  • 单位为秒
1
float time = Time.time;

游戏对象上一次帧更新到现在的时间差

1
float deltaTime = Time.deltaTime;

获取输入

鼠标输入

鼠标按键按下

<code>:鼠标按键码值

0:鼠标左键
1:鼠标右键
2:鼠标中键

1
bool yes = Input.GetMouseButtonDown(<code>);

鼠标按键抬起

1
bool yes = Input.GetMounseButtonUp(<code>);

鼠标按键按住

1
bool yes = Input.GetMouseButton(<code>);

获取鼠标当前的屏幕位置

  • 原点为屏幕左下角
1
Vector3 vector3 = Input.mousePosition;

键盘输入

<key_code>:键码值

KeyCode.A:A键

键盘按键按下

1
bool yes = Input.GetKeyDown(<key_code>);

键盘按键抬起

1
bool yes = Input.GetKeyUp(<key_code>);

键盘按键按住

  • 只要是鼠标按键按住,则始终返回true
1
bool yes = Input.GetKey(<key_code>);

游戏对象位置转换为屏幕位置

1
Vector3 vector3 = Camera.main.WorldToScreenPoint(this.gameObject.transform.position);

屏幕尺寸

1
2
int width = Screen.width;
int height = Screen.height;

组件(Component)

获取游戏对象的组件

1
数据类型 组件变量名 = gameObject.GetComponent<数据类型>();

获取当前游戏对象的组件

1
数据类型 组件变量名 = this.gameObject.GetComponent<数据类型>();
  • 简写
1
数据类型 组件变量名 = this.GetComponent<数据类型>();

组件属性

  • 获取组件属性
1
数据类型 变量名 = 组件变量名.属性名;
  • 修改组件属性
1
组件变量名.属性名 = 值;

音频组件(AudioSource)

获取游戏对象的音频组件

1
AudioSource audioSource = gameObject.GetComponent<AudioSource>();
获取当前游戏对象的音频组件
1
AudioSource audioSource = this.gameObject.GetComponent<AudioSource>();
  • 简写
1
AudioSource audioSource = this.GetComponent<AudioSource>();

判断当前是否播放中

1
bool yes = audioSource.isPlaying;

播放

1
audioSource.Play();

停止

1
audioSource.Stop();

暂停

1
audioSource.Pause();

自动播放

1
bool yes = audioSource.playOnAwake;
1
audioSource.playOnAwake = false;

播放一次指定音频

1
2
3
AudioClip audioClip;

audioSource.PlayOneShot(audioClip);

网格渲染组件(MeshRenderer)

获取游戏对象的材质组件

1
MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer>();
获取当前游戏对象的材质组件
1
MeshRenderer meshRenderer = this.gameObject.GetComponent<MeshRenderer>();
  • 简写
1
MeshRenderer meshRenderer = this.GetComponent<MeshRenderer>();

修改材质

1
2
3
Material material;

meshRenderer.material = material;

调用其他游戏对象的指定组件的方法

通过定义游戏对象作为脚本参数

A.cs
1
2
3
4
5
public class A : MonoBehaviour
{
public void method(string arg)
{}
}
B.cs
1
2
3
4
5
6
7
8
9
public class B : MonoBehaviour
{
public GameObject gameObject;

void method()
{
gameObject.GetComponent<A>().method("");
}
}

通过定义游戏对象的指定组件作为脚本参数

A.cs
1
2
3
4
5
public class A : MonoBehaviour
{
public void method(string arg)
{}
}
B.cs
1
2
3
4
5
6
7
8
9
public class B : MonoBehaviour
{
public A a;

void method()
{
a.method("");
}
}

通过发送消息

A.cs
1
2
3
4
5
public class A : MonoBehaviour
{
public void method(string arg)
{}
}
  • 向其他游戏对象发送消息,目标游戏对象所有组件中只要有这个方法就都会被调用
B.cs
1
2
3
4
5
6
7
8
9
public class B : MonoBehaviour
{
public GameObject gameObject;

void method()
{
gameObject.SendMessage("method", "");
}
}

父子级

  • Unity中的父子级关系是在变换组件中维护的,也就是说只能获取变换组件的父子级而不是直接获取游戏对象的父子级,但是游戏对象和变换对象是一对一映射的,所以可以通过变换组件间接获取游戏对象父子级关系

获取父级变换对象

1
Transform fatherTransform = this.gameObject.transform.parent;

获取所有子级变换对象

1
2
3
4
foreach (Transform childTransform in this.gameObject.transform)
{
...
}

获取指定索引子级变换对象

<index>:子级索引

1
Transform childTransform = this.gameObject.transform.GetChild(<index>);

通过游戏对象名查找子级变换对象

<name>:子级游戏对象名,如果需要查找孙子,则需要使用绝对路径

1
Transform childTransform = this.gameObject.transform.Find("<name>");

修改父级变换对象

指定根作为新的父级

1
this.gameObject.transform.setParent(null);

指定其他变换对象作为新的父级

1
2
3
Transform otherTransform;

this.gameObject.transform.setParent(otherTransform);

定时器(Invoke)

延迟执行定时器

<delay>:延迟时间,单位秒

1
2
3
void method() {}

this.Invoke("method", <delay>);

反复执行定时器

1
2
3
void method() {}

this.InvokeRepeating("method", <delay>, <interval>);

判断定时器是否存在于定时器队列

1
2
3
void method() {}

bool exist = IsInvoking("method");

停止执行定时器

停止所有定时器

1
CancelInvoke();

停止指定定时器

1
2
3
void method() {}

CancelInvoke("method");

线程(Thread)

获取当前线程

1
Thread thread = Thread.CurrentThread;

获取当前线程号

1
int threadId = thread.ManagedThreadId;

预制体

通过预制体创建游戏对象

指定根作为父级

1
2
3
GameObject prefab;

GameObject gameObject = Object.Instantiate(prefab, null);

销毁游戏对象

  • Destroy()会在本轮Update()执行结束后才会执行
1
Object.Destroy(gameObject);

物理引擎

消息函数

OnCollisionEnter():每当游戏对象开始碰撞时调用
OnCollisionStay():每当游戏对象持续碰撞时每帧调用
OnCollisionExit():每当游戏对象结束碰撞时调用

1
2
3
4
5
6
7
8
9
10
11
12
void OnCollisionEnter(Collision collision)
{
...
}
void OnCollisionStay(Collision collision)
{
...
}
void OnCollisionExit(Collision collision)
{
...
}

获取碰撞目标游戏对象

1
GameObject gameObject = collision.gameObject;

完成

参考文献

哔哩哔哩——阿发你好
知乎——博毅创为