Newer
Older
DungeonShooting / DungeonShooting_Document / 帮助文档 / 武器制作流程.md
@小李xl 小李xl on 16 Apr 2024 11 KB 更新文档

武器制作流程

[TOC]

在本文档中, 预制体=场景

1.创建武器预制体和武器脚本

武器预制体(场景)路径: res://prefab/weapon/

首先创建一个武器预制体, 右键res://prefab/weapon/WeaponTemplate.tscn, 选择新建继承场景

image-20240415202728855

创建完成后需要修改武器场景根节点名称

武器命名规范: Weapon+武器唯一Id

这个武器唯一Id就是填在配置表中的id, 后面会讲到, 这里先确保唯一即可

image-20240415203013811

以下是武器所有的节点

image-20240415204040594

所有节点详细描述和注意事项:

  • ShadowSprite: 武器的阴影节点, 默认texture是空的, 游戏会自动根据AnimatedSprite节点当前帧创建对应的阴影序列帧, 如果需要自定义阴影纹理, 例如一个阴影圈, 那么就可以手动给texture属性赋值
  • AnimatedSprite: 武器帧动画节点, 模板武器不包含sprite_frames数据, 需要自己创建
  • ShellPoint: 弹壳投抛位置, 手动移动到合适位置即可
  • FirePoint: 子弹射出位置, 手动移动到合适位置即可
  • Collision: 武器碰撞器, shape默认为空, 必须创建RectangleShape2D(矩形)类型碰撞器
  • AnimationPlayer: 武器动画播放器, 可以创建武器自定义动画, 例如, 换弹, 上膛, 空闲动画等, 动画播放器默认包含floodlight动画, 该动画为武器在地上时的高亮动画, 请不要编辑或者删除

接下来就是创建武器脚本, 武器基类为Weapon(路径:src/game/activity/weapon/Weapon.cs), 并且Weapon为抽象类, 因此我们需要创建一个子类并继承Weapon

我们创建一个MyGun.cs, (如果不想自己实现武器逻辑, 可以直接跳过这一步, 并使用默认的枪类实现: Gun, 路径: src/game/activity/weapon/gun/Gun.cs)

using Godot;

[Tool] //这个[Tool]必须添加, 否则将会在运行游戏时报错!
public partial class MyGun : Weapon
{
    protected override void OnFire()
    {
        //单次开火时调用的函数
    }

    protected override void OnShoot(float fireRotation)
    {
        //发射子弹时调用的函数, 每发射一枚子弹调用一次, 如果做霰弹武器效果, 一次开火发射5枚子弹, 则该函数调用5次
        //fireRotation – 开火时枪口旋转角度, 弧度制
    }
}

至于开火和发射子弹的具体逻辑, 这里不过多介绍, 请参照Gun

写完脚本后我们需要点击Godot右上角的编译按钮

image-20240415211532558

编译完成后就可以将MyGun挂载到武器根节点下了(如果使用默认枪逻辑, 直接挂载Gun脚本即可)

刚挂载脚本下面导出的属性都时空的, 不要害怕, 这一步不需要手动赋值

注意: 如果挂载脚本后没有出现以下属性, 说明脚本编译出错或者没有编译脚本

image-20240415211851366

这里需要手动关闭场景再打开或者切换到其它页签再切回来, 导出的属性就会自动赋值, 最后记得ctrl+s保存一下

image-20240415212203925

到这里武器预制体创建完成

2.创建子弹预制体和子弹脚本

子弹预制体路径: res://prefab/bullet/

该文件夹目前包含三个子文件夹, 分别对应三种子弹类型

  • normal: 正常子弹类型, 实体子弹
  • laser: 激光
  • explode: 爆炸效果

我们以最基础的normal子弹为例

子弹不像武器有模板场景, 需要自由发挥, 但是我们可以直接复制其它子弹预制体, 然后改个名称即可

image-20240415213104129

子弹命名方式和武器类似, 这里按照其它子弹照葫芦画瓢即可

以下是子弹所有的节点(我们是复制的Bullet0001.tscn场景, 其它子弹场景可能会有所不同)

image-20240415213609059

所有节点详细描述和注意事项:

  • ShadowSprite: 同武器介绍
  • AnimatedSprite: 同武器介绍
  • CollisionArea: 子弹伤害检测区域, 检测子弹撞到的目标, 并调用目标的IHurt.Hurt()函数, 目标必须实现IHurt接口
  • CollisionShape2D: 子弹伤害碰撞器检测区域, 建议这个区域比Collision稍微大一点, 大一点点即可
  • Collision: 同武器介绍, 但是需要注意的是和CollisionShape2D的区别, CollisionShape2D是用于子弹击中目标检测的碰撞器, 而该节点为子弹运动的碰撞器, 这个是检测墙壁并反弹的, 这里不要搞混了

到这里你就会发现, 武器和子弹都包含了 ShadowSprite, AnimatedSpriteCollision 这三个节点, 那是因为这三个节点是ActivityObject类提供的, 而武器和子弹都是ActivityObject的子类, 因为游戏中基本上所有的实体物体都是ActivityObject或者子类

接下来创建子弹脚本, 子弹没有硬性要求必须继承哪个父类, 相反, 它只需要实现IBullet接口即可(路径: src/game/activity/bullet/normal/IBullet.cs)

但是我们上面的操作复制的是Bullet0001.tscn场景, 该场景为ActivityObject场景, 所以我们的代码需要继承ActivityObject

子弹的实现非常复杂, 非常不建议自己从0开始实现, 直接抄作业使用现成的类Bullet(路径: src/game/activity/bullet/normal/Bullet.cs)

如果你非得头铁完全自己实现子弹逻辑, 那么有请, 已经起好了开头:

[Tool]
public partial class MyBullet : ActivityObject, IBullet
{

最后将脚本挂载到场景根节点即可

和武器一样, 这里会有几个引用需要复制

image-20240415215932786

复制的流程也和武器一样, 要手动关闭场景再打开或者切换到其它页签再切回来, 自动赋值完成, 最后记得保存

子弹制作完成

Tips: laser(激光)explode(爆炸)并不是ActivityObject, 它们是由其它Godot原生节点实现的, 具体实现直接看它们挂载的脚本即可, 前提先把normal类型的子弹玩明白

3.在配置表中配置武器和子弹, 并配置武器和子弹的属性

游戏中配置表路径: excel/, 注意在godot工程根目录下

不过也有快捷按钮, 在godot编辑器中

image-20240415232132040

先认识以下几张表

image-20240415232554395

ActivityBase.xlsx: 负责注册ActivityObject物体, 所有继承自ActivityObject的场景都需要在这张表中填写配置信息, 这张表包含物体id, 物体名称, 物体品质, 物体类型, 物体物理材质, 预制体路径等基本数据

WeaponBase.xlsx: 负责记录武器属性数据, 比如弹容量, 射速, 散射值, 连发属性, 射出的子弹, 音效

BulletBase.xlsx: 负责记录子弹的属性数据, 比如伤害, 击退值, 子弹速度, 射程, 穿透次数, 反弹次数

第一步我们我们需要把子弹和物体都配置到ActivityBase.xlsx表中

武器: 填上id和名称, 物体类型为5, 再填上预制体路径和图标即可

image-20240415234801153

子弹: 同样填上id和类型, 因为不需要显示在编辑器中, 名称可以不填, 再填上预制体路径即可

image-20240415235034598

想偷懒可以直接复制其他行数据粘贴再改一改就行了

第二步把子弹属性填写到BulletBase.xlsx表中

子弹表字段不多, 描述基本上都介绍的非常详细了

image-20240416002316491

这里提醒一下Prefab字段, 当Type字段值不同时, Prefab填的内容也不相同

这张表Id建议和ActivityBase.xlsx表中的Id的最后的一串数字对应

第三步把武器属性填写到WeaponBase.xlsx表中

武器表字段非常多, 武器各种属性区分的非常详细, 这里截图不会展示所有字段, 仅保留需要注意的字段

image-20240415235823784

这张表需要注意的是一把武器需要填写两条武器数据, 这样做的目的就是为了让敌人拾起武器时不会像玩家一样可以一直连续开火, 那样太变态了, 为了限制敌人发射频率, 我们直接把武器属性抽成两份配置, 当玩家拾起武器时使用的是玩家配置, 当敌人拾起的时候就或读取属性较弱的ai配置了

这里玩家武器属性的Id建议和ActivityBase.xlsx表中的Id的最后的一串数字对应

Ai使用的武器属性有个潜规则, 就是玩家属性id+_ai, 注意不要写错, 比如玩家使用的武器id为0001, 那么Ai的武器id就是0001_ai

玩家使用的武器属性必须填写Activity这一列

其他字段

image-20240416000723735

Bullet: 射出的子弹, 填子弹ActivityBase.xlsx表中的Id

Shell: 抛出的弹壳, 填子弹ActivityBase.xlsx表中的Id, 没有弹壳可以不填, 注意, 本文档没有介绍如何创建弹壳, 但本质流程和子弹相同, 并且弹壳没有额外逻辑, 所以制作弹壳比制作子弹简单, 这里自己摸索一下即可, 弹壳预制体路径: res://prefab/shell/

ShootSound: 射击播放的音效, 这个填Sound.xlsxId, 也就是音效表的数据Id, 本文档没有介绍音效表, 该表比较简单, 可以自己查看配置项

ShootSound字段后面还有几个音效相关的属性, 例如换弹音效, 上膛音效等, 这里都不做赘述了

最后需要注意一下这个字段, 用于Ai武器的一些额外配置选项AiAttackAttr, 值为AiAttackAttr.xlsxId

image-20240416001828298

AiAttackAttr.xlsx表中有以下字段

image-20240416002232817

如果以上所以配置都填写完成后, 那么就可以进行最后一步导出表数据到游戏中了

第四步导出表数据

非常简单, 在Godot编辑器中点击工具, 导出Excel表按钮即可

image-20240416003121335

但是注意, wps在打开excel表时会占进程, 导致导出表失败, 所以在导出表前一定要先关闭所有打开的excel表!

如果导表最终弹出以下弹窗说明导表成功

image-20240416003453585

Tips: Godot工程中的导表攻击并不是编译好的二进制版本程序, 而是源代码, 第一次调用导表时会调用本机的dotnet命令编译导表工具, 次步骤请确保安装了.net8dotnet命令可以正常使用