以下均为来自中国大学mooc 游戏引擎原理及应用时的学习笔记,不含商用,仅供学习交流使用,如果侵权请联系作者删除。
5.1 组件和脚本
脚本语言的特点:
使用简单 语法简单 跨平台
和计算机硬件不直接打交道
新建脚本的名字和脚本里面的类名是对应的
使得人物往前走的方法:
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}
(这个只能断断续续的走
脚本可以挂接在物体上成为物体的组件
unity的功能其实都是用脚本实现的
//这一节内容都挺简单 以前就应该学会了不少
5.2 重要函数或类
游戏其实是不断刷新重绘的
Update():每一帧执行时,都会立即调用此方法。 LateUpdate():LateUpdate 是在所有 Update
方法调用之后被调用(语出圣典)。 FixedUpdate():固定更新。默认情况下,系统每0.02秒调用一次。 具体的间隔时间可以在
TimeManager 中配置(详见文末)。 区别
总体来说,Update() 和 LateUpdate() 属于立即更新,更新之间的频率是不固定的,比如某一g帧有一个耗时操作时,就会影响到下
一帧更新时间,所以对更新频率要求比较稳定的物理系统(如Rididbody)就不太适合在这里处理更新。
FixedUpdate() 虽然是固定更新,但是其实也是相对固定的,比如某一帧耗了好几秒,它依然会卡住。不过正常的程序会优化耗时操作,小范围的帧率波动是正常的,可以让它更新的时间间隔稍微长一点,这样它的更新是比较平滑的。
在实际的开发中,例如以秒为单位的倒计时,并不需要每一帧去判断时间,所以用 FixedUpdate 就再合适不过
Awake函数在Start函数之前被执行
Vector3 force = transform.forward * 10 * Input.GetAxis("Vertical");
GetComponent<Rigidbody>().AddForce(force);
给物体施加力的方法(建议放在FixedUpdate函数中执行
Debug.Log("输出语句");//这个方法可以在unity的界面输出语句
private void OnCollisionEnter(Collision collision){
if(collision.gameObject.GetComponent<Arraw>()){
hp=hp-10;
}
}
5.3 函数执行顺序
5.4 序列化过程
在unity中实现
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class xuliehua : MonoBehaviour
{
[Serializable]//必须要加上这个 还有上面的using System才能使得下面的公开能在系统里面被看到
public class Node
{
public string value;
public List<Node> children = new List<Node>();
}
public Node root = new Node();
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
通过这个手段就可以实现在unity中实现根节点及其子结点的存储
(就可以存储下来值 (在重新加载关卡的时候就能保存下来值)
5.5 协程
有时候我们会遇到需要持续执行的循环。换句话说,一个程序循环,它是在一段时间内逐步地完成的,而不是在一个更新帧内把这个循环都做完,那么这个时候就需要用到协程函数。
左边这个函数在一帧之内就完成
右边这个函数执行一次就返回回来 到下一次继续执行
右边这个函数还可以改进
有时候我们希望这个函数是和时间相关而不是和帧相关
类是继承自MonoBehaviour,只有当MonoBehaviour被彻底摧毁的时候,其中的协程才会停止
所以某些时候我们需要刻意地停止某些协程
在停止的时候我们可以调用StopCoroutine或者StopAllCoroutine
来把对应的或者所有的协程来停止掉
在unity中进行演示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript1 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
StartCoroutine("Fade");//用字符串的形式调用协程函数
}
}
IEnumerator Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = GetComponent<MeshRenderer>().material.color;
c.a = f;
GetComponent<MeshRenderer>().material.color = c;
yield return new WaitForSeconds(0.1f);
}
}
}
给小球一个透明材质,渲染模式还要选中transparent
然后把上面那段脚本给小球,进入游戏按下F就可以看到小球渐变成透明
(注意这里犯了一个错误,如果将脚本拖拽给某个物体时,出现这个错误,不一定是这个脚本出错,可能是其他物体出错了
5.6 预制件
把物体拖拽到文件夹中,自动会变蓝,说明此时成为了预制体
预制件的改变某个参数会影响所有的副本,但是如果副本自己改变了某个参数的话,此时改变预制体的任何参数,都不会影响那个特定的个体。
改变文件夹中的sphere 其他三个物体也会跟着改变,但是那个特定的物体不会改变
习题