前言
利用Unity创建C#脚本,可以将脚本作为作为组件挂载到游戏物体上,这样脚本组件就会出现在检视窗口,可以像其他内置组件一样方便修改。
一、创建和使用脚本
在工程窗口的某个目录中操作,右键Create->C# Script即可,要注意初始化命名,文件名要与脚本中的类名保持一致,如果修改了脚本,类名也要随之改变。
二、 初识脚本
新建的脚本都会有以下内容:
示例代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
// Start is called before the first frame update
void Start(){ }
// Update is called once per frame
void Update(){ }
}
Unity规定脚本中必须包含一个类,且继承Unity内置的MonoBehaviour类。
在Unity中,MonoBehaviour是用于创建脚本的基类,它是一个C#类,继承自UnityEngine.Object类。
MonoBehaviour提供了一系列的内置函数(如Start、Update、OnTriggerEnter等),这些函数可以在脚本中被重写和使用,用于控制游戏对象的行为和属性。它支持与Unity的生命周期函数进行交互,可以让开发者在不同的游戏阶段调用不同的函数,实现游戏对象的初始化、运行和销毁等操作。
通过继承MonoBehaviour类,开发者可以在脚本中使用Unity API,比如操作游戏对象、控制音频、动画、碰撞等效果。同时,MonoBehaviour还支持序列化,可以在Unity编辑器中直接修改脚本中的属性值,方便开发者进行调试和测试。
MonoBehaviour是Unity中的一个重要类,它提供了一系列内置函数和支持Unity API的功能,方便开发者控制游戏对象的行为和属性,实现游戏的功能和效果。
之后有两个函数:
Update函数会在每一帧被调用,可以实现用户输入、角色移动、角色行为等功能。
Start函数在物体刚刚被创建时调用,即在第一个Update之前只被调用一次。
三、用脚本控制游戏物体
把脚本拖动到游戏物体检视窗口下方的空白区域即可。
成功的话可以看到新添加了一个名称和类名相一致的组件。
可以使用Debug.Log("hello,world")
语句进行调试,可以在Unity的控制台窗口看到输出。(类似于js中的Console.log语句)
四、变量与检视窗口
自定义脚本相当于自定义了一种新的组件,内置组件的参数可以在编辑器中进行调整,脚本也可以!
示例代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Name : MonoBehaviour
{
public string Myname;
// Start is called before the first frame update
void Start()
{
Debug.Log("my name is " + Myname);
}
}
在代码中定义了一个公共变量,在检视窗口的脚本组件上就可以编辑参数。
然后就可以在控制台看到my name is llz了!
甚至可以在游戏运行时修改,不需要反复启动和停止游戏。
五、通过组件控制游戏物体
通过检视窗口可以随时修改参数,但是通过脚本修改参数更为普遍。大多数组件参数都可以修改,例如刚体的质量、渲染器的材质,组件的开关。
5.1 访问组件
在脚本中获取一个组件,可以用内置的GetComponent函数,可以实现把一个组件保存到一个变量之中。
示例代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Visit : MonoBehaviour
{
public Rigidbody rb; //需要在函数外定义
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>(); //获取刚体组件
rb.mass = 10f; //定义刚体质量为10kg
rb.AddForce(Vector3.up * 10f); //施加一个向上的,大小为10N的力(只在刚创建物体时生效)
}
// Update is called once per frame
void Update()
{
rb.AddForce(Vector3.up * 110f); //持续施加一个向上的,大小为110N的力
}
}
首先定义刚体组件,这样rb就是该物体刚体组件的引用变量,只要是刚体组件支持的操作,可以在脚本中任意使用。
其中,定义一个数字变量为 10f,其中的“f”表示这是一个浮点数(float),而不是整数(int)。在 C# 中,如果要定义一个浮点数,需要在数字后面加上“f”,以区分整数。如果不加上“f”,编译器会默认这是一个整数。如果要定义一个整数变量,可以这样写:int myInt = 10;
以及为什么是10kg而不是10g,是因为Unity 中的物理系统是基于米-千克-秒(MKS)单位的,所以 Mass 属性的值应该是千克(kg)而不是克(g)
对于一个物体能挂多少脚本并没有限制。
脚本组件也可以用GetComponent获得,例如获取名为Myname.cs的组件,可以写为GetComponent<Myname>();
六、访问其他游戏物体
一个脚本不仅可以对当前挂载的物体进行操作,还可以引用其他物体。
6.1 用变量引用游戏物体
在脚本中添加 public GameObject变量,不需要设置初始值。
示例代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public GameObject player;//定义游戏物体
void Start()
{
transform.position = player.transform.position - Vector3.forward * 10f;
//读取player的位置,并设置本物体的位置在它后方
}
}
这样检视窗口就会出现其他游戏物体的变量,只需要将相应物体拖动到变量的文本框里即可。如下图所示:
另外,引用其他物体时,变量类型不仅可以是GameObject或者一个组件,也可以将游戏物体拖到这个变量上,只要被拖拽的物体确实有这个组件就可以。
(不要用面向对象的方式去理解)组件和物体可以是对应的关系。
6.2 查找子物体
当管理一系列同类型的游戏物体时,有时候需要在脚本中用数组或者容器的方式来管理它们。
可以将一群敌人都放在一个物体之下,通过查找子物体的方法遍历所有物体。
代码如下(示例):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaypointManager : MonoBehaviour
{
public Transform[] waypoints;
// Start is called before the first frame update
void Start()
{
waypoints = new Transform[transform.childCount];
int i = 0;
//用foreach循环访问所有子物体
foreach(Transform t in transform)
{
waypoints[i++] = t;
}
}
}
也可以用transform.Find("Gun");
来查找某一物体,但是效率不好估计。
6.3 通过标签或名称查找物体
如果要查找的物体不是子物体,也可以通过特定信息来查找。例如,可以使用GameObject.Find
方法通过名称查找物体。如果用标签寻找,可以用GameObject.FindWithTag
方法或者GameObject.FindGameObjectsWithTag
方法。
代码示例如下
GameObject player;
GameObject player2;
GameObject[] enemies;
void Start()
{
player = GameObject.Find("Player");
player2 = GameObject.FindWithTag("Player");
enemies = GameObject.FindGameObjectsWithTag("Enemy");
}
使用标签查找时,需要给物体设置标签
七、常用事件函数
Unity会在特定事件发生时调用不同的函数,这些特定的函数被称为事件函数,因为是在特定事件发生时由引擎层调用的。
7.1 基本更新函数
在每一帧刚开始的时候(渲染之前),对物体的位置、状态或行为进行计算,然后渲染出来。Update函数在每一帧刚刚开始时被调用。
示例代码如下:
void Update()
{
float distance = speed * Time.deltaTime * Input.GetAxis("Horizontal");
transform.Translate(Vector3.right * distance);
}
物理引擎也会按照物理帧更新,机制与Update类似,但是更新时机不同,要尽可能在FixedUpdate中进行物理相关的操作。
示例代码如下:
private void FixedUpdate()
{
Vector3 force = transform.forward * driveForce * Input.GetAxis("Vertical");
rigidbody.AddForce(force);
}
有时候不仅需要在每帧之前操作物体,还需要在所有的Update函数之后再进行一些操作,例如更新相机位置等。
示例代码如下:
private void LateUpdate()
{
//在一帧的最后阶段,将摄像机转向玩家角色的位置。这样相机旋转会更加流畅
Camera.main.transform.LookAt(target.transform);
}
7.2 初始化函数
在每一帧之前,往往需要做一些初始化的工作,Start函数会在第一次Update等函数和物体加载出来之前被调用。
Awake函数比Start函数调用还要早,在场景加载时就会被调用。
八、时间和帧率
Update函数可以用来侦测输入或者其他事件,并作出相应的行为。但是游戏的帧率并不是一个固定的值,如果按照帧率考虑物体的移动,可以给出以下代码:
public float diantancePerFrame;
void Update()
{
transform.Translate(0, 0, diantancePerFrame);//按照帧率前进,不一定是匀速运动
transform.Translate(0, 0, diantancePerFrame * Time.deltaTime);//匀速
}
引入Time.deltaTime
之后,可以通过每一帧移动的距离*两帧之间的时间间隔得到一个固定速率,这样就可以实现物体的匀速运动了!
九、创建和销毁物体
大部分游戏会在游戏运行中实时生成角色、宝物、子弹等,Unity中提供了Instantiate函数专门创建一个新的物体。
示例代码如下:
public GameObject enemy;
void Start()
{
//以enemy为模板,生成五个敌人
for(int i = 0; i < 5; i++)
{
Instantiate(enemy);
}
}
可以用已经存在的物体作为模板(最常用的是使用预制体作为模板)
另外,还可以用Destory函数摧毁游戏物体或者组件。
示例代码如下:
private void OnCollisionEnter(Collision collision)
{//导弹发生碰撞时摧毁这枚导弹
if (collision.gameObject.tag == "Missile")
{
Destroy(gameObject, 0.5f);
//第二个参数代表0.5s后才会执行销毁动作
}
}
十、脚本无效化
游戏物体可以标记为不被激活的状态,相当于临时在场景中删除,可以使用脚本实现无效化,也可以勾选检视窗口的激活复选框。
当一个父物体被标记为不被激活时,会覆盖所有子物体的激活状态。
附录
事件 | 说明 |
---|---|
Update | 每一帧被调用 |
LateUpdate | 每一帧游戏逻辑之后,渲染之前调用 |
FixedUpdate | 固定更新,用于物理系统 |
Awake | 当一个脚本实例被载入时调用 |
Start | 在Update函数第一次调用之前调用 |
Reset | 重置为默认值时调用 |
OnMouseEnter/Over/Exit/Down/Up/Drag | 当鼠标光标进入/悬浮/移出/单击/释放单击/拖拽GUI元素或碰撞体中时调用 |
OnTriggerEnter/Exit/Stay | 当碰撞体进入/脱离/接触触发器时调用 |
OnCollisionEnter/Exit/Stay | 当此Collider/Rigidbody触发/停止触发/持续触发另一个时被调用 |
OnEnable/Disable/Destoroy | 对象变为激活/非激活/MonoBehavior被摧毁状态时可使用 |
OnGUI | 渲染和处理GUI事件时调用,每帧调用一次 |
总结
以上就是这篇文章的主要内容,本文简单介绍了C#脚本的创建和使用、用脚本控制游戏物体等内容,同时介绍了一些常用事件函数。文章来源:https://www.toymoban.com/news/detail-767012.html
如果有错误或者补充可以在留言处提出~文章来源地址https://www.toymoban.com/news/detail-767012.html
到了这里,关于【Unity】脚本与组件操作 C#版的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!