Unity3D脚本编程笔记–基础的脚本知识

从脚本开始

将脚本添加给GameObject

有三种方法可以将脚本添加给一个GameObject让其成为它的Component。

  • 将创建的脚本文件直接拖动给目标GameObject
  • 将脚本文件拖动到该GameObject的Inspector面板中
  • 在该GameObject的Inspector面板中最下方选择Add Component然后创建一个新的脚本,直接添加给该GameObject

访问限定词

  • public 修饰的变量在Inspector面板中可见并且可以直接进行调整
  • private 修饰的变量只能在脚本程序中使用,在Inspector面板中不可见
  • public 修饰的变量或者方法,在其他类中使用该类的实例,可以访问该类下的这些变量与方法
  • private 修饰的变量只能在本类中使用和调用,不能被其实例访问

几个周期函数

  • Awake()
    • 在脚本被初始化的时候调用,尽管该脚本可能已经被禁用
    • 在整个脚本的生命周期中只调用一次
  • Start()
    • 在脚本第一次要Update之前,必须是在该脚本是enable的情况下
    • 在整个脚本的生命周期中只调用一次
  • Update()
    • 在每一帧出现时调用
    • 每次更新的时间间隔不同
    • 一般用于:
      • 移动非物理化物体的时候
      • 简单的定时器
      • 接收到输入的时候
  • FixedUpdate()
    • 每次物理操作之后调用
    • 两次更新时间间隔一致
    • 一般用于:
      • 调整物理物体(Rigidbody,刚体)

Unity3D中的向量

向量运算

  • 二维向量 Vector2

  • 三维向量 Vector3

    • 向量的模:magnitude
    • 计算向量的模的平方,单纯为了比较大小,比计算模速度快:sqrMagnitude
    • 判定向量相等:Equals
    • 向量转化成字符串:ToString
    • 向量的内积(点乘)运算:Dot
      Vector3.Dot(VectorA, VectorB)
      向量的内积(点乘)
    • 向量的外积(叉乘)运算:Cross
      Vector3.Cross(VectorA, VectorB)
      右手坐标系
      向量的外积(叉乘)
      向量的外积(叉乘)

GameObject与Component

获取Component

  • 获取同GameObject下的Component
    ComponentType componentName = GetComponent<ComponentType>();
  • 获取其他GameObject下的Compnent
    • 先声明一个public变量,然后将其他GameObject的相应的Component拖动到该变量处赋值
    • 先找到该GameObject再获取Component
      1
      2
      GameObject gameObjectName = GameObject.Find("  ");
      ComponentType componentName = gameObjectName.GetComponent<ComponentType>();

控制Component是否可用

1
2
3
// if  componentName  is a component got already
componentName.enabled=false; //disable the component
componentName.enabled=true; //enable the component

获取GameObject

  • 获取脚本所属GameObject:直接使用 gameObject
  • 获取其他/一般的GameObject
  • 声明一个public变量,将目标GameObject拖到该参数处为其赋值
  • 使用Find方法
    GameObject gameObjectName = GameObject.Find(" ");
  • 使用FindGameObjectsWithTag或者FindWithTag获取:为GameObject添加Tag可以在Instector面板中完成
    为GameObject添加Tag
    为GameObject添加Tag
    1
    2
    ComponentType componentName = GameObject.FindGameObjectsWithTag("tag");
    ComponentType componentName = GameObject.FindWithTag("tag");

控制GameObject是否可用

1
2
3
// if  gameObjectName  is a GameObject got already
gameObjectName.SetActive(false); //disable the GameObject
gameObjectName.SetActive(true); //enable the GameObject

判断GameObject是否可用

// if gameObjectName is a GameObject got already

语法 作用
gameObjectName.activeSelf 判断其本身是否active,其父物体为disable,但是其本身可能还是active
gameObjectName.activeInHierarchy 判断其所在分级是否active,即其父物体是否active

获取Transform

  • 获取脚本所在GameObject的Transform:直接使用 transform
  • 获取其他GameObject的Transform:先使用上述方法得到GameObject,然后使用 gameObjectName.transform

移动(Translate)和旋转(Rotate)

  • Translate:Transform的方法,以一个Vector3为参数,按照Vector3所描述的方向与大小移动
  • Rotate:Transform的方法,以一个Vector3为参数,按照Vector3所描述的方向与大小旋转
  • LookAt:摄像机跟踪目标:Transform.LookAt():以一个transform为参数,使得摄像机的transform跟随参数的transform变动,即实现跟踪

销毁(Destroy)

1
2
Destory(GameObject/Component);
Destory(GameObject/Component,DelaySecond);

获取输入

获取按键输入

  • ButtonInput:获取键钮,在 Edit -> Project Settings -> Input 中可以看到各种预设好的按键,读取这些键钮的名称作为GetButton的参数
1
2
3
Input.GetButtonDown("name");     // 键钮按下时的一帧为true
Input.GetButton("name"); // 键钮按下时保持为true
Input.GetButtonUp("name"); // 键钮按下然后释放后的状态下保持为true
  • KeyInput:获取键钮
    1
    2
    3
    Input.GetKeyDown(KeyCode.name);     // 键钮按下时的一帧为true
    Input.GetKey(KeyCode.name"); // 键钮按下时保持为true
    Input.GetKeyUp(KeyCode.name"); // 键钮按下然后释放后的状态下保持为true

    KeyCode完整参考:https://docs.unity3d.com/ScriptReference/KeyCode.html

获取水平/竖直轴向输入

使用以下函数均可传入一个参数的两个值:“horizontal”、“vertical”来分别表示水平和竖直方向的运动

1
2
Input.GetAxisRaw() //在参数设置的方向上返回 -1 或 1 两个值中的一个,即即止即停
Input.GetAxis() //在参数设置的方向上返回一个 -1 到 1 之间的float值,即有一定的缓冲变动的效果

获取鼠标输入

  • OnMouseDown():当鼠标点击GUIElement或者Collider时触发
  • OnMouseDrag():当鼠标点击GUIElement或者Collider并仍然按住时触发
  • OnMouseEnter():当鼠标进入GUIElement或者Collider时触发
  • OnMouseExit():当鼠标离开GUIElement或者Collider时触发
  • OnMouseOver():只要鼠标在GUIElement或者Collider上时的每一帧都会触发
  • OnMouseUp():当鼠标被释放时触发
  • OnMouseUpAsButton():当鼠标在点击了GUIElement或者Collider后并且释放时触发

DeltaTime

DeltaTime是指的每两个 Update() 函数或者 FixedUpdate() 函数调用之间的时间间隔,使用 Time.deltaTime 获得

数据类型

数据类型
数据类型

类(Classes)

  • 脚本名称和类名需要相同
  • 详细情况与C#类一致

实例化预设体(Instantiate Prefab)

使用 Instantiate 来创建某个预设体(Prefab)的复制品(Clones):
首先使用public变量来获取目标Prefab:public PrefabType prefabName

  • Instantiate(prefabName):从prefabName的预设体创建一个克隆体生成在坐标原点处
  • Instantiate(prefabName,Position,Rotation):规定预设体的位置与角度
  • Type referencereference = Instantiate(prefabName,Position,Rotation) as Type;:将预设体生成在指定位置与角度并且进行类型转换成Type类型

Instantiate完整参考:https://docs.unity3d.com/ScriptReference/Object.Instantiate.html?_ga=2.116872129.693619093.1552224779-1809290818.1551791741

数组(Arrays)

在Unity的脚本中声明一个 public 类型的数组变量,不需要传入具体的大小,这样的数组可以在Inspector处直接更改数组大小,并且随着数组大小的改变还会自动为你添加每一个数组的参数值。
然后使用 foreach 循环或者 for 循环可以很方便的遍历整个数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public GameObject[] gameObjects;

void Start()
{
Debug.Log("Using For");
for(int i = 0; i < gameObjects.Length; i++)
{
Debug.Log(gameObjects[i].name);
}

Debug.Log("Using Foreach");
foreach(GameObject items in gameObjects)
{
Debug.Log(items.name);
}
}
使用public的数组赋值
使用public的数组赋值

其他

调用(Invoke)

Invoke()函数可以在一定时间后以及每一定时间间隔内调用某个方法,要求该方法必须是 0个参数,void返回值的函数。

比如我们有一个函数 LogHello

1
2
3
4
void LogHello()
{
Debug.Log("Hello World!");
}

使用 Invoke 来调用该方法:

  • Invoke("LogHello", delayTime):第一个参数为要调用的方法的名称(字符串),第二个参数为要推迟多少时间调用该方法(单位:s)
  • InvokeRepeating("LogHello", delayTime, gapTime):前两个参数同上,第三个参数规定在第一次调用后每隔多长时间调用一次(单位:s)
  • CancelInvoke("LogHello"):传入要停止Invoke的方法名称(字符串)

线性插值(Linear Interplotation)

线性插值是在两个给定值之间找到一个百分比的值。比如在3和5之间找到一个50%处的值,即f4

  • Mathf.Lerp:三个float类型参数,前两个规定起止值,最后一个规定百分比,返回一个float类型的值
    float result = Mathf.Lerp (3f, 5f, 0.5f); // result = 4
  • Color.Lerp:返回两个颜色值的百分比处的插值结果
  • Vector3.Lerp:返回两个三维向量的百分比处的插值结果
  • 1
    2
    3
    Vector3 from = new Vector3 (1f, 2f, 3f);`
    Vector3 to = new Vector3 (5f, 6f, 7f);
    Vector3 result = Vector3.Lerp (from, to, 0.75f); // result = (4, 5, 6)