1.常用组件
组件 | 作用 |
---|---|
Transform | 存储个处理游戏对象的位置、旋转和缩放 |
Mesh Filter | 显示网格 |
Rigidbody | 刚体,使物体能在物理控制下运动 |
Collider | 碰撞器,和刚体一起来是游戏对象发生碰撞 |
Renderer | 渲染器,使物体在屏幕上显示出来 |
Audio Source | 音频源,在场景中可以播放音频剪辑 |
Animation | 播放指定的动画剪辑 |
Animator | 通过动画控制器设置角色上的行为 |
Script | 定义自定义功能和各种交互操作 |
Particle System | 用于创作烟雾,气流,火焰,瀑布,喷泉等效果 |
2.常用周期事件
事件方法 | 说明 |
---|---|
Awake | 唤醒事件,在脚本实例被创建时调用,只执行一次 |
OnEnable | 启用事件,在每次激活脚本时调用 |
Start | 开始事件,用于游戏对象或游戏场景的初始化,在场景被加载时调用,只执行一次 |
FixedUpdate | 固定更新事件,0.02秒执行一次。所有物理组件相关的更新都在这个事件中处理。 |
Update | 更新事件,每帧执行一次 |
LateUpdate | 延迟更新,每帧执行一次,在Update事件之后执行。和相机有关的更新一般都放在这。 |
OnGUI | 用来绘制交互界面,每帧会调用多次 |
OnDisable | 禁用事件,取消脚本的激活状态后调用 |
OnDestroy | 当前脚本被销毁时调用 |
二维向量Vector2 | 方法 |
---|---|
down | Vector2(0,-1) |
left | Vector2(-1,0) |
one | Vector2(1,1) |
right | Vector2(1,0) |
up | Vector2(0,1) |
zero | Vector2(0,0) |
magnitude | 返回向量长度 |
normalized | 单位化向量,长度变为 1,方向不变 |
//静态变量.类名来调用
print(Vector2.down);
print(Vector2.up);
print(Vector2.left);
print(Vector2.right);
print(Vector2.zero);
print(Vector2.one);
//创建向量
Vector2 a = new Vector2(4,5);
Vector2 b = new Vector2(1,3);
//返回向量长度
print(a.magnitude);
print(b.magnitude);
//返回单位化向量,原向量不变
print(a.normalized);
print(a.x + "," + a.y);
print(b.normalized);
print(b.x + "," +b.y);
//对向量进行单位化,原向量改变
a.Normalize();
print(a.x + "," + a.y);
//输出两个向量之间的距离
print(Vector2.Distance(a, b));
//输出两向量之间的角度
print(Vector2.Angle(a, b));
三维向量Vector3 | 方法 |
---|---|
back | Vector3(0,0,-1) |
down | Vector3(0,0,-1) |
forward | Vector3(0,0,1) |
left | Vector3(-1,0,0) |
one | Vector3(1,1,1) |
right | Vector3(1,0,0) |
up | Vector3(0,1,0) |
zero | Vector3(0,0,0) |
Angle | 两向量的夹角 |
Cross | 叉乘,满足左手法则,结果为一个向量 |
Dot | 点乘,结果为一个值 |
MoveTowards | 由当前位置匀速移动到目标位置 |
Slerp | 对长度和角度进行插值,用于对象的转向,比较平滑 |
+,-,*,/,!=,== | 相关运算 |
4.键盘和鼠标输入
相关方法 | 说明 |
---|---|
Input.GetKey() | 按下某键,持续返回true |
Input.GetKeyDown | 按下某键的一瞬间,返回true |
Input.GetKeyUp | 松开某键的一瞬间,返回true |
Input.GetMouseButton(0) | 持续检测是否按鼠标左键(针对鼠标左中右键,三个方法同) |
Input.GetMouseButtonDown(1) | 检测是否按下了右键,检测一次 |
Input.GetMouseButtonUp(2) | 检测是否按下了鼠标中键[参数左键(0),右键(1),中键(2) ] |
Input.GetButton | 持续检测 |
Input.GetButtonDown | 检测是否按下,检测一次 |
Input.GetButtonUp | 检测是否松开,检测一次 |
Input.GetAxis | 获取虚拟轴,返回-1到1之间的浮点数,有渐变效果 |
Input.GetAxisRow | 返回-1,0,1三个值,没有渐变效果 |
OnMouseDrag | 当鼠标拖动(获取鼠标的行为事件,不针对左中右键,下同) |
OnMuseDown | 当鼠标按下 |
OnMouseUp | 当鼠标抬起 |
OnMouseEnter | 当鼠标进入 |
OnMuseExit | 当鼠标退出 |
OnMuseOver | 当鼠标经过 |
//获取键盘的输入,检测按下和松开。
if(Input.GetKey(KeyCode.A))
print("GetKey:A");
if(Input.GetKeyDown(KeyCode.A))
print("GetkeyDown:A");
if(Input.GetKeyUp(KeyCode.A))
print("GetKeyUp:A");
//检测鼠标右键状态
if (Input.GetMouseButton(1))
print("Mouse right");
if (Input.GetMouseButtonDown(1))
print("Mouse right down");
if (Input.GetMouseButtonUp(1))
print("Mouse right up");
获取按钮和虚拟轴:
通过Edit–>Project Setting–>Input Manager–>Axes打开,可以查看相关配置信息。如Fire1的配置如下。按下鼠标左键(Mouse 0)和按下左边的Ctrl都会响应。
//检测按钮Fire1状态
if (Input.GetButton("Fire1"))
print("Button Fire1");
if (Input.GetButtonDown("Fire1"))
print("Button Fire1 Down");
//获取虚拟轴的状态
//一般用来控制物体的左右,前后移动或者旋转
float h1 = Input.GetAxis("Horizontal");
print(h1);
float h2= Input.GetAxisRaw("Horizontal");
print(h2);
改变一个游戏对象的颜色。
private void OnMouseEnter()
{
gameObject.GetComponent<MeshRenderer>().material.color = Color.red;
}
private void OnMouseExit()
{
gameObject.GetComponent<MeshRenderer>().material.color = Color.white;
}
5.Time类及其成员变量
通过Time类可以获取和时间有光的信息,用来计算帧速率,调整时间流逝的速度等。
成员变量 | 功能 |
---|---|
Time | 游戏开始到现在的时间( 秒) |
deltaTime | 上一帧消耗的时间 |
fixedTime | 最近FixedUpdate已经开始的时间,该时间从游戏开始计算 |
fixedDeltaTime | 物理引擎和FixedUpdate更新时间间隔 |
timeScale | 时间流逝速度比例。可以用来制作慢动作特效 |
frameCount | 已渲染的帧总数 |
smoothDeltaTime | Time.deltaTime的平滑淡出 |
timeSinceLevelLoad | 此帧的开始时间,从关卡加载完成开始计算 |
maximumDeltaTime | 一帧的最大耗费时间 |
realtimeSinceStartup | 游戏开始到现在经历的真实时间,该时间不会受timeScale的影响 |
captureFramerate | 固定帧设置 |
print("Time.time:" + Time.time);
print("Time.deltaTime:" + Time.deltaTime);
print("Time.fixedDeltaTime:" + Time.fixedDeltaTime);
print("Time.fixedTime:" + Time.fixedTime);
print("Time.timeScale:" + Time.timeScale);
//通过计时器来控制Cube的状态
private float time = 3.0f;
//运行时在Unity面板上设置值
public float speed;
public float rotaeSpeed;
private void Update()
{
time -= Time.deltaTime;
if(time<=0)
{
time = 3.0f;
//处理逻辑,该属性取反,禁用时,不渲染。
GetComponent<MeshRenderer>().enabled = !GetComponent<MeshRenderer>().enabled;
}
//控制物体每秒移动多少米
transform.Translate(Vector3.right * Time.deltaTime*speed);
//控制物体每秒旋转的角度
transform.Rotate(Vector3.up * Time.deltaTime * rotaeSpeed);
//通过按键来控制时间流速的大小
if (Input.GetKeyDown(KeyCode.Q))
Time.timeScale = 10.0f;
if (Input.GetKeyDown(KeyCode.P))
Time.timeScale =0.0f;
}
6.预制体
预制体:Perfab,预先准备好的物体,可以重复使用,是Unity中很重要的资源。
预制体的创建方法:
创建游戏对象的三种方法:
public GameObject CubePrefab;
private GameObject g2;
GameObject g1;
void Start()
{
g1= new GameObject("g1");
GameObject.CreatePrimitive(PrimitiveType.Cube);
Vector3 pos = new Vector3(-1f, 2f, 0f);
//使用as将Instantiate的返回值转化为GameObject类型
g2=Instantiate(CubePrefab, pos, Quaternion.identity) as GameObject;
print(g2.name);
}
运行前将准备好的预制体赋值给CubePrefab,如下:
结果如图:
游戏对象的销毁:
void Update()
{
if (Input.GetKeyDown(KeyCode.D))
{
GameObject.Destroy(g2);
GameObject.Destroy(g1, 5f);
}
}
7.查找物体
若物体没激活,则通过名称和标签查不到,通过路径和和根据父物体可以查到。
方法 | 说明 |
---|---|
GameObject.Find() | 可通过名称全局查找或根据路径查找子对象 |
GameObject.Find(“Cube”).transform.GetChild(0) | 通过父物体查找子物体 |
FindWithTag/FindGameObjectWithTag/FindGameObjectsWithTag | 通过标签名查找 |
GameObject go1=GameObject.Find("s");
print(go1.name);
Transform tf1= transform.Find("g1/s");
print(tf1);
Transform tf2=GameObject.Find("g1").transform.GetChild(0);
print(tf2);
//设置s和g2的标签为Player;
GameObject go2=GameObject.FindGameObjectWithTag("Player");
print(go2);
GameObject[] gArray = GameObject.FindGameObjectsWithTag("Player");
print(gArray.Length);
print(gArray[0].name);
8.启用和禁用
函数 | 功能 |
---|---|
SetActive | 参数true为启用,false为禁用 |
activeSelf | 父物体禁用,自身未禁用,则返回true |
activeInHierarchy | 父物体禁用,则返回false |
public GameObject Cube;
void Update()
{
if (Input.GetKeyDown(KeyCode.D))
{
Cube.SetActive(false);
print(Cube.activeSelf);
print(Cube.activeInHierarchy);
}
if (Input.GetKeyDown(KeyCode.A))
{
Cube.SetActive(true);
print(Cube.activeSelf);
print(Cube.activeInHierarchy);
}
}
void Start()
{
BoxCollider box= gameObject.GetComponent<BoxCollider>();
box.size *= 3;
//获取脚本组件
s c=gameObject.GetComponent<s>();
c.name = "txy";
c.print();
}
组价的启用和禁用
void Update()
{
//组件的添加和删除
if(Input.GetKeyDown(KeyCode.A))
{
gameObject.AddComponent<Rigidbody>();
}
if (Input.GetKeyDown(KeyCode.D))
{
GameObject.Destroy(gameObject.GetComponent<Rigidbody>());
}
//组件的启用和禁用
if (Input.GetKeyDown(KeyCode.E))
{
gameObject.GetComponent<BoxCollider>().enabled = true;
}
if (Input.GetKeyDown(KeyCode.F))
{
gameObject.GetComponent<BoxCollider>().enabled =false ;
}
}
移动物体
void Update()
{
//控制物体的移动
//1.通过改变位置信息,添加一个增量,来持续改变位置信息
transform.position += new Vector3(Time.deltaTime * 0.5f,0, 0);
//2.通过transform.Translate来移动,默认朝自身坐标系方向运动,可以设置为朝世界坐标系
transform.Translate(Vector3.right * Time.deltaTime * 0.5f,Space.World);
//3.通过Vector3.Lerp方法,通过插值,运动为先快后慢
Vector3 target = new Vector3(4f, 3f, 2f);
transform.position=Vector3.Lerp(transform.position, target, Time.deltaTime);
//4.通过Vector3.MoveTowards方法,匀速移动,z增量为Time.deltaTime
transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime);
//5.通过A,S,D,W键来控制物体的移动;虚拟轴的值正负来控制移动的方向
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
transform.Translate(Vector3.right * h * Time.deltaTime);
transform.Translate(Vector3.forward * v * Time.deltaTime);
}
物体的旋转
void Start()
{
//欧拉角与四元素介绍
//获取物体的欧拉角
print(transform.eulerAngles);
//获取四元数
print(transform.rotation);
//四元素与欧拉角的相互转换
print(transform.rotation.eulerAngles);//四元数-->欧拉角
print(Quaternion.Euler(transform.eulerAngles));// 欧拉角-- > 四元数
}
// Update is called once per frame
void Update()
{
//1.使用transform.Rolate方法,y轴每秒旋转30度
transform.Rotate(Vector3.up * Time.deltaTime * 30);
//2.使用四元数的乘法来实现,在其基础上y轴旋转5度;
Quaternion q1 = transform.rotation;
Vector3 vd = new Vector3(0, 5, 0);
Quaternion q2 = Quaternion.Euler(vd);
if(Input.GetKeyDown(KeyCode.R))
{
transform.rotation=q1* q2;
}
}
Invoke相关方法
函数 | 功能 |
---|---|
Invoke(string funname,float time) | 调用函数。多少秒后执行函数funname,只会调用一次 |
InvokeRepeating(string ,float,float) | 重复调用函数。多少秒后执行某个函数,并且以后每个多少秒都会执行该函数一次 |
CancelInvoke | 取消这个脚本中的所有Invoke调用 |
CancelInvoke(string fun) | 取消某个函数的Invoke调用 |
IsInvokeing(string ) | 判断某个函数是否在等待调用 |
void Start()
{
//调用函数CreateBox,延迟两秒
// Invoke("CreateBox", 2f);
InvokeRepeating("CreateBox", 4f, 2f);
}
// Update is called once per frame
void Update()
{
bool r = IsInvoking("CreateBox");
print(r);
if(Input.GetKeyDown(KeyCode.D))
{
//CancelInvoke();
CancelInvoke("CreateBox");
}
}
void CreateBox()
{
print("生成物体");
}
}
9.协成
协成:协成程序,即主程序在运行的同时开启另外一段出路逻辑。
协成方法与普通方法的区别:
协成方法的定义:
例子 | 说明 |
---|---|
yield return null/数字/字符串 | 暂停协成,下一帧在继续执行,用来延迟一帧执行 |
yield return new WaitForSeconds(2f) | 暂停协成,2秒后再往下执行 |
yield return StartCoroutine(“Funname”) | 暂停协成,启动协成Funname,执行完后再继续往下执行 |
yeild new WaitForFixedUpdate() | 暂停协成,等下一次调用FixedUpdate方法是在继续执行下去 |
void Start()
{
//普通方法
print("任务1");
print("任务2");
//print("任务3");
//开启协成
StartCoroutine("Task3");
print("任务4");
}
//定义协成
IEnumerator Task3()
{
yield return new WaitForSeconds(2f);
print("任务3");
}
void Update()
{
//停止协成
if(Input.GetKeyDown(KeyCode.Space))
{
StopCoroutine("Task3");
}
}
10.物理引擎
具有刚体组件的物体,满足物理规律,具有碰撞体的物体能进行碰撞检测。
private Rigidbody r;
// Start is called before the first frame update
void Start()
{
r = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//刚体移动
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
r.MovePosition(r.position + transform.right * h * Time.deltaTime * 2f);
r.MovePosition(r.position + transform.forward * v * Time.deltaTime * 2f);
}
碰撞事件检测方法
函数 | 功能 |
---|---|
OnCollisionEnter(Collision) | 当碰撞开始时,调用该方法一次 |
OnCollisionExit(Collision) | 当碰撞结束时,调用该方法一次 |
OnCollisionStay(Collision) | 当碰撞进行中是,持续调用该方法 |
private void OnCollisionEnter(Collision collision)
{
print("Enter"+collision.gameObject.name);
}
private void OnCollisionExit(Collision collision)
{
print("Enter" + collision.gameObject.name);
}
private void OnCollisionStay(Collision collision)
{
print("Enter" + collision.gameObject.name);
}
碰撞检测条件
触发器事件
触发器检测条件:
private void OnTriggerEnter(Collider other)
{
if(other.name !="Plane")
{
print(other.gameObject.name);
print(other.name);
}
}
private void OnTriggerExit(Collider other)
{
if (other.name != "Plane")
{
print(other.gameObject.name);
print(other.name);
}
}
private void OnTriggerStay(Collider other)
{
if (other.name != "Plane")
{
print(other.gameObject.name);
print(other.name);
}
}
物理射线
物理射线检测方法:
private Ray ray;
private RaycastHit hit;
void Update()
{
if(Input.GetMouseButtonDown(0))
{
//获取摄像机,创建一条射线,方向为摄像机到鼠标点击的位置
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
}
//碰撞检测,通过结构体hit和返回关键字out返回碰撞信息
if(Physics.Raycast(ray, out hit))
{
//把碰撞的物体销毁
GameObject.Destroy(hit.collider.gameObject);
}
}
附:
学习至中国大学mooc-Unity2D游戏程序设计