Unity脚本常见API(第一集)

161 阅读4分钟

image.png

这篇文章主要记录自学 Unity 过程中常见的 API 。


一个空的C#脚本文件

从下面的代码中,可以看到一个新的C#脚本文件:
它包含两个生命周期函数:Start()Update()\color{blue}{它包含两个生命周期函数:Start() 和 Update()。}
Start()为整个脚本文件的入口,同时Start()会先执行,Update()再跟着执行。\color{blue}{Start()为整个脚本文件的入口,同时Start()会先执行,Update()再跟着执行。}
Start()只会在场景开始时的第一帧执行一次,可以用来做初始化。\color{blue}{Start()只会在场景开始时的第一帧执行一次,可以用来做初始化。}
Update()则是每帧都执行(Unity中是160)\color{blue}{Update()则是每帧都执行(Unity中是1秒60帧)。}

using UnityEngine:
这个就是引入了 Unity 框架,表示我们可以使用 Unity 里的 API 了。

MonoBehaviour:
在 Unity 里编写的 C# 脚本就需要继承 MonoBehaviour 来实现跨平台。并且不继承它的话就无法将脚本挂载到物体上。

注意事项

  1. 类名和脚本名必须一致。
  2. print()的打印方式是来自于MonoBehaviour类。
  3. Debug.Log()的打印方式是来自于UnityEngine命名空间。
  4. Player中默认的权限访问修饰符为:private。
  5. 命名空间的默认权限访问修饰符为:internal(仅访问当前的程序集)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()                  // 生命周期函数
    {
        // 整个脚本的入口

        // 场景开始的第一帧执行
    }
    // Update is called once per frame
    void Update()                // 生命周期函数
    {
        // 场景开始后每帧执行
    }
}

生命周期函数:
除了 Start() 和 Update() 之外,还有许多的生命周期函数,例如:

void Awake() 
{ 
    Debug.Log("Awake方法用于初始化并且永远只会执行一次,它比Start()执行时间更早。"); 
}

Input类

  1. Input.GetKey();             : 按住执行,每帧执行
  2. Input.GetKeyUp();        : 抬起执行一次
  3. Input.GetKeyDown();   : 按下执行一次
  4. KeyCode         : 这是一个枚举,里面存放了键盘上的键所对应的值。

使用方法:

Input.GetKey(KeyCode.W);        // 按住执行,每帧执行 
Input.GetKeyUp(KeyCode.S);      // 抬起执行一次
Input.GetKeyDown(KeyCode.A);    // 按下执行一次
//KeyCode :这是一个枚举,里面存放了键盘上的键所对应的值

控制物体的移动

第一种:
transform: 这是当前物体的一个组件,表示物体的位置、大小和旋转\color{green}{位置、大小和旋转}
Translate: 移动的方法,参数为一个三维向量。
Vector3.forward: 这是一个三维向量(通过z轴实现向前移动)\color{green}{(通过z轴实现向前移动)},它的值为(0,0,1),也就是说每执行一次,就会将 z轴的值加一。

transform.Translate(Vector3.forward);   // 每帧移动 Vector3.forward 距离。
// 需要写在每帧执行的生命周期函数里。

第二种:
position: transform组件中控制物体位置的向量坐标(场景中的每一个物体都有这个组件)\color{green}{(场景中的每一个物体都有这个组件)}
Time.deltaTime: 这个是每帧的间隔时间(很小,是一个0.0000xxxx的数)。
(Unity中每秒60,通过Time.deltaTime来将其缩小)\color{green}{(Unity中每秒60帧,通过Time.deltaTime来将其缩小)}

float speed = 2;          //自定义的移动速度。
transform.position += Vector3.forward * speed * Time.deltaTime;

第三种:
Rigidbody: 通过刚体组件来对物体施加力,从而实现物体移动。

// speed是自定义的速度属性
body.AddForce(Vector3.forward * speed);

获取物体对象/组件

// 默认的就是 private 
//这两个属性如果写为 public 的话,就可以直接在 Unity中拖过来
GameObject TopWall;
Rigidbody body;
// Start is called before the first frame update
void Start()                  
{
    // 获取名称为 TopWall 的物体对象
    TopWall = GameObject.Find("TopWall");
    // 获取当前物体的上的 Rigidbody 组件
    body = gameObject.GetComponent<Rigidbody>();
}

相机跟随物体移动小案例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 相机的脚本文件
public class cam : MonoBehaviour
{
    // 目标物体的位置
    Transform target;

    // 目标和相机之间的距离
    Vector3 dir;

    // Start is called before the first frame update
    void Start()
    {
        // 找到目标物体对象的位置
        target = GameObject.Find("Sphere").transform;
        // 拿到相机与目标之间的距离
        dir = target.position - transform.position;
    }

    // Update is called once per frame
    void Update()
    {
        // 重新计算相机的位置
        Vector3 pos = target.position - dir;
        // 更新相机的位置
        transform.position = pos;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// 小球的脚本
public class Ball : MonoBehaviour
{
    // 小球移动的速度
    public float speed;
    // 小球的刚体组件
    Rigidbody body;
    // Start is called before the first frame update
    void Start()
    {
        // 拿到刚体组件
        body = gameObject.GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        // 前
        if (Input.GetKey(KeyCode.W))
        {
            body.AddForce(Vector3.forward * speed);
        }
        // 后
        if (Input.GetKey(KeyCode.S))
        {
            body.AddForce(Vector3.back * speed);
        }
        // 左
        if (Input.GetKey(KeyCode.A))
        {
            body.AddForce(Vector3.left * speed);
        }
        // 右
        if (Input.GetKey(KeyCode.D))
        {
            body.AddForce(Vector3.right * speed);
        }
    }
}

Unity截图:

image.png

物体旋转

主要通过 Transform 组件中的 Rotate(x,y,z) 函数来实现。 (注意这里的是Rotate()函数,而不是rotation属性)\color{blue}{(注意这里的是 Rotate()函数 ,而不是 rotation 属性)}

旋转的方向:

  1. Rotate(1,0,0): 表示物体的 x 值发生变化,也就是上下旋转,且x为正数,则表示物体向上旋转\color{blue}{物体向上旋转}
  2. Rotate(0,1,0): 表示物体的 y 值发生变化,也就是左右旋转,且y为正数,则表示物体向左旋转\color{blue}{物体向左旋转}
  3. Rotate(0,0,1): 表示物体的 z 值发生变化,也就是从右面上下旋转,且z为正数,则表示物体从右面向上旋转\color{blue}{物体从右面向上旋转}
void Update()
{
    transform.Rotate(0, 0, 1);
}

视角:

image.png

物体的碰撞方式

主要有两大类:
Collision(不可重叠,可阻挡)\color{blue}{Collision(不可重叠,可阻挡)}:

  1. OnCollisionEnter(Collision collision) :  进入执行一次\color{green}{进入执行一次}
  2. OnCollisionExit(Collision collision) :  离开/结束执行一次\color{green}{离开/结束执行一次}
  3. OnCollisionStay(Collision collision) :  碰撞时一直执行,每帧的\color{green}{碰撞时一直执行,每帧的}

Trigger(可重叠,不可阻挡)\color{blue}{Trigger(可重叠,不可阻挡)}:

  1. OnTriggerEnter(Collider other) :  进入执行一次\color{green}{进入执行一次}
  2. OnTriggerExit(Collider other) :  离开/结束执行一次\color{green}{离开/结束执行一次}
  3. OnTriggerStay(Collider other) :  碰撞时一直执行,每帧的\color{green}{碰撞时一直执行,每帧的}

搭配使用的两个方法:

  1. xxx.gameObject.name == "xxx"    通过物体的名字来判断\color{green}{通过物体的名字来判断}
  2. xxx.gameObject.tag == "xxx"    通过标签来判断\color{green}{通过标签来判断}

(注意:使用Trigger(碰撞器),需要在Unity中将isTrigger勾选上。)\color{red}{(注意:使用Trigger(碰撞器),需要在Unity中将isTrigger勾选上。)}:

private void OnCollisionEnter(Collision collision)
{
    // 一旦碰到名字为 Cube 的物体就进入if语句
    if(collision.gameObject.name == "Cube")
    {
        // 销毁目标对象
        Destroy(collision.gameObject);
    }

}

切换场景

在Unity中场景的切换也是很高频的操作,而具体实现如下:

1.先增加一个命名空间:usingUnityEngine.SceneManagement;\color{blue}{1. 先增加一个命名空间:using UnityEngine.SceneManagement;} 2.使用方法完成场景的切换:SceneManager.LoadScene("xxx");\color{blue}{2. 使用方法完成场景的切换:SceneManager.LoadScene("xxx");} (xxx就是需要切换的场景名)\color{red}{(xxx就是需要切换的场景名)}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;      // 添加命名空间

public class Cub : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        SceneManager.LoadScene("xxx"); // 使用转换场景方法
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

内容过长不利于巩固复习,下篇继续。