Unity C#脚本的基本使用方法

2022年4月24日 6278点热度 6人点赞 0条评论

前言

Unity 引擎使用C#语言作为脚本语言,所以在学习Unity之前应该先了解C#的基本语法,如果你是老道的java或者C++程序员,那么相信你大致了解一下C#的语言,就可以达到基本可使用的状态了。

Unity虽然提供了相当多的游戏组件供用户使用,但是要开发一个完整的游戏,仅仅使用组件又是不够的。

游戏脚本可以触发游戏事件,随时修改组件的属性,并以所需的任何方式响应用户的输入。

创建最简单的C#脚本

在资源窗口右键,create-> C# scrite 可以直接创建一个脚本。也可以通过从主菜单选择 Assets > Create > C# Script 来新建脚本。

比如创建一个FirstScrite的脚本,脚本中会自动生成这样的代码。

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

public class FirstScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

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

    }
}

脚本中会实现一个继承于MoniBehaviour的,与文件名相同的类。

类中会实现两个函数,这两个函数会在脚本声明周期里被自动调用

  1. start() 类被初始化时调用,可以在函数中初始化类中的成员变量。
  2. update() 在游戏的每一帧更新前会被调用。

将脚本附加到游戏对象

拿精灵对象举例,精灵的Inspector Window 中有一个 Add Component 的选项,点击之后选择Script就可以看到新建的脚本。

当然也可以直接将脚本拖拽致Inspector Window中。

Unity_Script_Test

当然,因为脚本里什么都没有,所以运行时不会看到跟之前有什么区别。

可以在脚本中添加一段改变精灵位置的代码,看一下精灵在场景中的反应。

    void Update()
    {
        int speed = 2;
        Vector3 endPos = transform.position + Vector3.left * speed;
        transform.position = Vector3.Lerp(transform.position, endPos, Time.deltaTime);
    }

这段代码写到Update()中,游戏每一帧更新前都会被调用。代码的功能是线性的改变精灵的位置,每一秒的速度是2。

Unity_Script_Test1

需要注意的是,将脚本附加到游戏对象时,脚本文件名必须与类名一致,如果文件中有多个类,也只会附加与脚本名称相同的类。

Inspector Window

C# 的public 成员都会被显示到Inspector Window中,可以在Inspector Window中编辑这些成员的值,十分方便。如果不想public 成员被显示到Inspector Window,需要额外配置属性,下文会关于特性会详细介绍。

比如上文的脚本中,将speed 声明为一个public 成员。

public int speed = 2;

image-20220423165309518

在Inspector Window中就可以看到Speed 这个变量,甚至可以修改它的值,修改了之后,精灵移动的速度也会跟着改变。

细看会发现 Inspector Window中的变量似乎跟脚本中的有点不一样,是的s被改成了大写。

这是因为在显示名称时有一套固定的规则来处理变量名,具体如下:

  1. 删除变量名开头的”m_“
  2. Removes “k” from the beginning 官方文档是这么写的,我理解的是删除变量名开头的k字母,但是经过测试好像不是这样的,我也搞不懂。
  3. 删除变量名开头的“_”
  4. 首字母改为大写
  5. 在小写字母和大写字母之间添加空格
  6. 如果是连续的大写字母,会在最后的两个大写字母之间增加空格(其实就是分割简写词)

来测试一下,为脚本添加这些public成员:

    public int m_name_m;
    public int _name_;
    public int nameAmiao;
    public int GKDName;

image-20220423170905517

MonoBehaviour 类

MonoBehaviour 类是一个基类,所有 Unity 脚本都默认派生自该类。从 Unity 的项目窗口创建一个 C# 脚本时,它会自动继承 MonoBehaviour,并实现Start()和Update函数。

继承它的是为了连接到Unity的架构,可以将它视作一个蓝图,用于创建可富家到游戏的对象的新组件类型。是的,如果你想你的脚本可以附加到游戏对象,那么继承Monibehaviour是必须的。

事件函数

除了Start() 和Update()之外,MonoBechaviour还有许多其他的事件函数。

Awake Awake 在加载脚本实例时调用。
FixedUpdate 用于物理计算且独立于帧率的 MonoBehaviour.FixedUpdate 消息。
LateUpdate 如果启用了 Behaviour,则每帧调用 LateUpdate。
OnAnimatorIK 用于设置动画 IK(反向运动学)的回调。
OnAnimatorMove 用于处理动画移动以修改根运动的回调。
OnApplicationFocus 当玩家获得或失去焦点时,发送给所有 GameObject。
OnApplicationPause 当应用程序暂停时,发送给所有 GameObject。
OnApplicationQuit Sent to all GameObjects before the application quits.
OnAudioFilterRead 如果实现了 OnAudioFilterRead,Unity 将在音频 DSP 链中插入一个自定义滤波器。
OnBecameInvisible OnBecameInvisible 在渲染器对任何摄像机都不可见时调用。
OnBecameVisible OnBecameVisible 在渲染器变为对任意摄像机可见时调用。
OnCollisionEnter 当该碰撞体/刚体已开始接触另一个刚体/碰撞体时,调用 OnCollisionEnter。
OnCollisionEnter2D 当传入碰撞体与该对象的碰撞体接触时发送(仅限 2D 物理)。
OnCollisionExit 当该碰撞体/刚体已停止接触另一个刚体/碰撞体时,调用 OnCollisionExit。
OnCollisionExit2D 当另一个对象上的碰撞体停止接触该对象的碰撞体时发送(仅限 2D 物理)。
OnCollisionStay OnCollisionStay is called once per frame for every Collider or Rigidbody that touches another Collider or Rigidbody.
OnCollisionStay2D 在另一个对象上的碰撞体正在接触该对象的碰撞体时发送每个帧(仅限 2D 物理)。
OnConnectedToServer 成功连接到服务器后在客户端上调用。
OnControllerColliderHit 当该控制器在执行 Move 时撞到碰撞体时调用 OnControllerColliderHit。
OnDestroy 销毁附加的行为将导致游戏或场景收到 OnDestroy。
OnDisable 该函数在行为被禁用时调用。
OnDisconnectedFromServer 当连接丢失或与服务器断开连接时,在客户端上调用。
OnDrawGizmos 如果您想绘制能够选择并且始终绘制的辅助图标,则可以实现 OnDrawGizmos。
OnDrawGizmosSelected 如果选择了对象,则实现 OnDrawGizmosSelected 来绘制辅助图标。
OnEnable 该函数在对象变为启用和激活状态时调用。
OnFailedToConnect 出于某种原因连接尝试失败时,在客户端上调用。
OnFailedToConnectToMasterServer 在连接到 MasterServer 时发生问题的情况下,在客户端或服务器上调用。
OnGUI 系统调用 OnGUI 来渲染和处理 GUI 事件。
OnJointBreak 在附加到相同游戏对象的关节断开时调用。
OnJointBreak2D 在附加到相同游戏对象的 Joint2D 断开时调用。
OnMasterServerEvent 在从 MasterServer 报告事件时,在客户端或服务器上调用。
OnMouseDown 当用户在 Collider 上按下鼠标按钮时,将调用 OnMouseDown。
OnMouseDrag 当用户单击 Collider 并仍然按住鼠标时,将调用 OnMouseDrag。
OnMouseEnter 当鼠标进入 Collider 时调用。
OnMouseExit 当鼠标不再处于 Collider 上方时调用。
OnMouseOver 当鼠标悬停在 Collider 上时,每帧调用一次。
OnMouseUp 当用户松开鼠标按钮时,将调用 OnMouseUp。
OnMouseUpAsButton 松开鼠标时,仅当鼠标在按下时所在的 Collider 上时,才调用 OnMouseUpAsButton。
OnNetworkInstantiate 在已通过 Network.Instantiate 进行网络实例化的对象上调用。
OnParticleCollision 当粒子击中碰撞体时,将调用 OnParticleCollision。
OnParticleSystemStopped 系统中的所有粒子都死亡时,便会调用 OnParticleSystemStopped,然后将不再产生新粒子。在调用 Stop 之后,或者超过非循环系统的 Duration 属性时,将停止产生新粒子。
OnParticleTrigger 粒子系统中的任何粒子满足触发模块中的条件时,将调用 OnParticleTrigger。
OnParticleUpdateJobScheduled 调度粒子系统的内置更新作业时,会调用 OnParticleUpdateJobScheduled。
OnPlayerConnected 每当有新玩家成功连接,就在服务器上调用。
OnPlayerDisconnected 每当有玩家与服务器断开连接,就在服务器上调用。
OnPostRender Event function that Unity calls after a Camera renders the scene.
OnPreCull Event function that Unity calls before a Camera culls the scene.
OnPreRender Event function that Unity calls before a Camera renders the scene.
OnRenderImage Event function that Unity calls after a Camera has finished rendering, that allows you to modify the Camera's final image.
OnRenderObject 在摄像机渲染场景后,将调用 OnRenderObject。
OnSerializeNetworkView 用于在网络视图监视的脚本中自定义变量同步。
OnServerInitialized 每当调用 Network.InitializeServer 并且完成时,对该服务器调用该函数。
OnTransformChildrenChanged 当 GameObject 的变换的子项列表发生更改时,将调用该函数。
OnTransformParentChanged This function is called when a direct or indirect parent of the transform of the GameObject has changed.
OnTriggerEnter GameObject 与另一个 GameObject 碰撞时,Unity 会调用 OnTriggerEnter。
OnTriggerEnter2D 当另一个对象进入附加到该对象的触发碰撞体时发送(仅限 2D 物理)。
OnTriggerExit 当 Collider other 已停止接触该触发器时调用 OnTriggerExit。
OnTriggerExit2D 当另一个对象离开附加到该对象的触发碰撞体时发送(仅限 2D 物理)。
OnTriggerStay 对于接触触发器的每一个 Collider /other/,每次物理更新调用一次 OnTriggerStay。
OnTriggerStay2D 在另一个对象位于附加到该对象的触发碰撞体之内时发送每个帧(仅限 2D 物理)。
OnValidate Editor-only function that Unity calls when the script is loaded or a value changes in the Inspector.
OnWillRenderObject 如果对象可见并且不是 UI 元素,则为每个摄像机调用 OnWillRenderObject。
Reset 重置为默认值。
Start 在首次调用任何 Update 方法之前启用脚本时,在帧上调用 Start。
Update 如果启用了 MonoBehaviour,则每帧调用 Update。

来自Unity官方文档,更详细的介绍可以自行前去查看。

特别注意

  1. 继承MonoBegaviour的类初始化成员变量时,一定要在start()函数中进行。因为脚本的调用依托于Unity框架,所以类在实例化时也是由框架完成的。Unity在生成对象时做了一些特殊的操作,所以非常不建议为类实现构造函数,会对框架造成很大的影响。
  2. 忘了,记起来再补。。。。。。。。。。。

特性(Attribute)

在成员变量或者函数上可以添加一些特殊行为的标记。

[HideInInspector]
public int speed = 2;

[HideInInspector] 是表示下方的变量不会显示到Inspector Window中。

所以这段代码加到之前的脚本中之后,Inspector Window中就不会显示speed变量了。

Unity 提供了许多特性,详情参阅文档:

大脸猫

这个人虽然很勤快,但什么也没有留下!

文章评论