03. CodeGenKit 脚本生成

在这一篇,我们学习几乎每个项目都要用到并且从中受益的功能:自动生成脚本并绑定,简称脚本生成。

基本使用

我们先在场景中,随便创建一些有父子结构的 GameObject,如下所示:

接着给 Player 挂上 ViewController,快捷键 (Alt + V),如下图所示:

然后填写 刚刚添加的组件信息:

在这里,可以填写命名空间,要生成的脚本名,以及脚本生成的目录,当然这里也可以直接将要生成的目录拖到大方块中。

如果拖拽了目录,就会自动填写脚本生成目录,如下图所示:

之后,我们可以给 Player GameObject 一个子节点挂上 Bind 组件(快捷键,alt + b),如下所示

Weapon 挂上的组件如下所示:

接下来我们可以点击图中的 生成代码按钮 或者是 Player 上 ViewController 的 生成代码按钮,两者点击哪个都可以。

点击之后,就会生成代码,等待编译,结果如下:

脚本目录:

我们在看下场景中的 Player 的 Inspector 如下图所示:

我们看到,Player 自动获得了 Weapon 的引用。

而且,在 Player.cs 中可以直接访问到 Weapon,如下图所示:

增量生成

我们再看下目录:

这里有两个文件 Player 和 Player.Designer。

其中 Player 是用来给大家写逻辑用的,所以 Player 只会生成一次。

而 Player.Designer 每次点击生成代码都会重新生成。

我们看下 Player.Designer 的代码,如下:

// Generate Id:471bf5e6-b60b-42b8-b5c8-b070a963ab4ausing UnityEngine;

// 1.请在菜单 编辑器扩展/Namespace Settings 里设置命名空间
// 2.命名空间更改后,生成代码之后,需要把逻辑代码文件(非 Designer)的命名空间手动更改
namespace QFramework.Example
{
    public partial class Player
    {

        public Transform Weapon;

    }
}

代码中只有一个 Weapon 。

接着,我们再给 Player 的另一个子 GameObject 挂上 Bind 脚本,如下:

然后点击生成代码,操作如下:

生成之后,结果如下:

Player 多了一个 Ground Check

再看下 Player.Designer 的代码,如下:

// Generate Id:f512c2ed-6243-4a89-897e-bdaaabe50d63using UnityEngine;

// 1.请在菜单 编辑器扩展/Namespace Settings 里设置命名空间
// 2.命名空间更改后,生成代码之后,需要把逻辑代码文件(非 Designer)的命名空间手动更改
namespace QFramework.Example
{
    public partial class Player
    {

        public Transform Weapon;

        public Transform GroundCheck;

    }
}

这次多了一个 GroundCheck。

而 Player 代码则未发生任何变化。

所以每次生成代码,Player.cs 只会生成一次,Player.Designer.cs 每次都重新生成,所以大家放心在 Player.cs 里写代码。

类型选择

之前我们用 Bind 绑定的 GameObject 都是 Transform 类型的,这次我们尝试绑定一下其他类型。

我们给 Weapon GameObject 挂上一个 Sprite Renderer 如下所示:

然后,我们点击 Bind 的类型,显示如下:

也就是说 Bind 可以选择挂在此 GameObject 上的组件。

我们选择 Sprite Render 类型,如下:

然后点击生成代码,结果如下:

Player 引用的 Weapon 变成了 Sprite Renderer 类型。

Player.Designer.cs 的代码变成了如下:

// Generate Id:de59e915-d1b6-40aa-a8e5-6fc4a8bf8e3eusing UnityEngine;

// 1.请在菜单 编辑器扩展/Namespace Settings 里设置命名空间
// 2.命名空间更改后,生成代码之后,需要把逻辑代码文件(非 Designer)的命名空间手动更改
namespace QFramework.Example
{
    public partial class Player
    {

        public UnityEngine.SpriteRenderer Weapon;

        public Transform GroundCheck;

    }
}

Weapon 从原来的 Transform 类型变成了 SpriteRenderer 类型。

这样我们在 Player.cs 就可以拿到 SpriteRenderer 类型的 Weapon 了,如下图所示:

如何设置默认的 命名空间 和 脚本生成目录

很简单,打开 QFramework 编辑器面板,(快捷键 ctrl + e 或 ctrl + shift + e)

在 CodeGenKit 设置里就可以更改默认的命名空间和默认的脚本生成位置。

当然在这里生成了,也还是可以在 ViewController Inspector 上进行设置。

我们先改下命名空间和脚本生成路径,如下:

然后我们创建一个 GameObject 挂上 ViewController 组件,结果如下:

这样默认的命名空间就生效了。

ViewController 与 ViewController 嵌套

ViewController 与 ViewController 之间可以嵌套

我们在 Player 的 Weapon GameObject 再创建一个 WeaponEffect GameObject 如下:

然后将 WeaponEffect 挂上 Bind 脚本,如下:

接着给 Weapon 挂一个 ViewController 脚本,如下:

我们将脚本生成目录修改一下,修改成与 Player.cs 同一个目录,如下:

点击生成代码,如下所示:

生成完了之后,我们再将 Weapon 上的 Bind 类型改成 Weapon,如下:

然后点击 Bind 上的生成代码,结果如下:

这样 ViewController 与 ViewController 嵌套绑定就实现了。

在 Player.cs 中可以按照如下的方式调用 Weapon 的子 GameObject 如下:

当然可以在 Weapon.cs 中写 Weapon 自己的逻辑。

生成 Prefab

在 ViewController 或 生成脚本的 Inspector 上,有一个生成 prefab 的选项

勾选后,如下所示:

这里可以修改要生成的目录,笔者选择和脚本生成的目录一致,如下:

然后点击,生成代码,结果如下:

场景中的 Player 变成了 prefab

生成目录中也有了 prefab

Why?

为什么要搞一个 CodeGenKit?

因为创建脚本目录、创建脚本文件、声明成员变量或者通过 transform.Find 获取子节点的引用、然后挂脚本、拖拽赋值,这些工作量非常多,而且很繁重,如果能够把这部分工作量通过代码生成并自动赋值的方式给优化掉,那么项目的开发效率就会得到及大地提升。

CodeGenKit 中的 ViewController 除了可以用于普通的 GameObject,还可以支持 NGUI 和 UGUI 等 UI 组件。

好了,关于脚本生成的功能介绍到这里。