📚 游戏道具扩展

在《沙盘引擎》世界框架中,游戏道具是极为重要的存在,任何角色可手持的物品都属于游戏道具范畴

无论何种类型的游戏玩法,角色手中的物品通常都能起到很大作用。

有些只是显示作用、有些可能有实际使用功能,也可能搭配【Prop背包系统(抽象功能)】进行扩展操作。

此系统的扩展性很高,几乎可以实现绝大多数【游戏物品、武器、道具】相关需求。

📒 游戏道具简介

在沙盘引擎世界中,所有的【游戏道具\物品】全部基于抽象的概念,实际上并没有任何默认作用它们只是看起来像XXX的一个模型,通过API方式放到了角色手上,开发者可根据实际游戏玩法需要,自行通过【自定义游戏道具+代码编写道具功能】设定它们应该有何实际操作。

想要将一个普通模型注册为游戏道具,需要开发者找到LocalMod\Store\Data\Prop目录==,新建或修改有关【游戏道具】的Json配置文件,这其中可能包括==ID、模型、Flag、叠加数量、伤害、延迟时间、动画组等数值设定,这将直接影响到游戏道具的实际展现形式

注意:动物等特殊类型角色不会有任何道具拾取功能及效果,道具功能主要用于人形角色(包括僵尸)

📒 配置文件规范

想要进行游戏道具的扩展维护,必须对文件使用特定的命名规范,否则引擎可能无法识别配置文件。

命名规范:GroupID_Name.json

例如:10000_Base.json(自定义ID从10000开始)

注意,自定义游戏道具的配置文件默认是以Group组.json的形式存在,也就是说,单个json文件内允许由多个配置项(数组)组合而成

因此,如果游戏玩法相对简单(或没有分类需求),那么可以只自定义一个json文件即可,不建议给每个道具都单独分配一个json。

举例:游戏只有少数20个道具,并且基本没有什么分类需求,那么可以只建立一个如10000_GameItems.json,只在此文件内配置全部道具即可。

举例2:例如《我的世界》游戏,道具有方块、食物、工具等等很多内容,那么为了规范分类考虑,可以分别建立10000_Cube.json | 10001_Food.json | 10002_Tool.json多个文件,并将不同的物品配置编写在指定的分类json下。

*引擎API可能会额外提供一些根据物品分类筛选列表的功能,所以对于物品较多的游戏,分类编写物品可能是有必要的**。*

📒 道具Json配置示例

物品的组成是非常抽象且具有扩展性的,一个物品由多个不同属性组合而成,最终实现的效果、属性、动作、声音也都不相同。

根据Key值顾名思义,不同的属性在不同特性(Flags)下可能有不同含义,对于部分基础属性(例如Pos\Scale\Flags\Speed...等属性),可以考虑省略部分配置(忽略则使用引擎提供的默认值)。

例如:ID固然是不能省略的,但Speed默认值是1.0,所以如果没有Speed需求,即使不填写也不会出错。

注意:自定义道具与其他自定义操作一样,有关ID部分必须从10000开始。

[
    {
		"ID": 10000,
		"Model": 5163,
		"Pos": {"x": 0, "y": 0, "z": -0.2},
		"Angle": {"x": 0, "y": 0, "z": 0},
		"Scale": {"x": 1.5, "y": 1.5, "z": 1.5},
		"Color": {"r": 255, "g": 255, "b": 0},
		"Flags": 132, //(128+4 == 枪类+连续发射)
		"Multiple": 1,
		"Damage": 10,
		"DamageRange": 1,
		"DamageShake": 1.0,
		"Distance": 35,
		"Direction": 1,
		"PreloadTime": 0.75,
		"Speed": 1.0,
		"MoveSpeedMultiplier": 1.0,
		"Audios": { //声音类(可空0)
			"Idle": 0,
			"Focus": 0,
			"Action": 0
		},
		"Animations": { //动作类(可空0)
			"Idle": 2,
			"Focus": 15,
			"Action": 15
		}
	},
    { //示例:可省略的简单写法
        "ID": 10001,
        "Model": 5163,
        "Damage": 10, //甚至也可以省略
    }
]
属性Key 说明 默认Value
ID 道具ID 自定义道具ID必须从10000开始
Model 物品展示(拿在手中)的模型ID,基于模型管理机制 -
Pos 模型本地坐标偏移(可空,默认中心) Vector(0, 0, 0)
Angle 模型本地角度偏移(可空,默认无旋转) Vector(0, 0, 0)
Scale 模型本地缩放偏移(可空,默认1Vector(0, 0, 0)
Color 颜色属性(并非修改模型颜色,主要用于弹道、投掷弹道等颜色) Color(255, 255, 255)
FocusPoint 道具焦点坐标(本地)
主要用于表示道具的核心\触发位置,目前仅用于展示攻击拖尾的坐标
Vector(0, 0, 0)
TrailColor 行为时拖尾颜色 Color(255, 255, 255)
Flags Flag特性类型,这将直接改变此物体的关键属性、效果、方式
(此属性支持位操作,可叠加Flag效果,详情参考下方表格)
0
Multiple 背包系统槽内可叠加数量(1=不可叠加,通常有特性的物品都不应该叠加)
(注意:这是一个抽象概念,应搭配Prop | Character.Prop相关API使用,主要用于支持背包交互系统的模组,否则可忽略此属性)
1
Damage 常规攻击力,可能根据Flags不同有不同的效果
(例如:枪械的攻击力、投掷物伤害等,默认情况下是普通攻击挥动伤害)
10
DamageRange 产生攻击的检测范围(范围内的实体对象都会被攻击)
枪械Flag:弹道宽度、伤害检测范围
投掷物Flag:投掷弹道宽度
≈1.0
DamageShake 目前版本主要用于Flag相关效果
枪械Flag:后坐力、射击偏移
投掷物Flag:投掷时速度、力量
枪械Flag:≈1.0
投掷物:≈0.5
Distance 距离属性,目前主要用于类似枪械射程等。
普通物品如果不为0,则表示物品声音范围(引擎默认值24)
24
Direction 手持物品方向修正类型(详情见下方表格) 0
Enum 通用枚举\数值\索引属性 0
PreloadTime 物品刚切换时冷却CD时间,期间无法进行当前物品的使用操作 0.75
Speed 物品每次Action时的动画速度,直接影响Action时间间隔(例如:枪械射速)
(简单来说,此属性控制物品整体Action速度,相当于物品的“攻击速度”)
1.0
MoveSpeedMultiplier 手持物品时影响角色的移动速度(倍数) 1.0
Audios[] Idle:拿出物品时的声音
Focus:焦点(HasFocus)时声音
Action:行为(HasAction)时声音
0
Animations[] Idle:站立、闲置时动作
Focus:焦点(HasFocus)时动作
Action:行为(HasAction)时动作
(详情见下方【自定义动作列表】)
0
特性Flag 说明
0 默认(Normal)
1 不可攻击(Unavailable)
2 盾牌抵挡效果(Shield)
目前版本实际应用:Focus状态下受到攻击,只会减少其40%的伤害
4 连续使用效果(Continue),否则是单次触发
8 散射范围,目前主要用于表示散弹类枪械
如果希望常规物品提升攻击范围,请修改DamageRange属性
16 多连发模式(Burst)
优先级更高,否则默认继承单发(Normal)或连续模式(Continue)
64 行为时生成Effect,效果类型与Enum有关
128 预制类型:枪械类
256 预制类型:投掷类(扔出XXX、投掷光线、弓、RPG、手榴弹等)
512 投掷后爆炸效果(必须同时搭配256使用)
1024 投掷后产生伤害(必须同时搭配256使用),伤害值与Damage有关
2048 投掷后产生烟雾(必须同时搭配256使用)
4096 投掷后产生闪光(必须同时搭配256使用)
8192 投掷后产生燃烧组(必须同时搭配256使用)
Direction 说明
0(默认) 手肘正前方向(因动作不同,可能并不是角色的正前方)
1 角色正前方
2 闲置时手持方向[0],行为时正前方[1]
3 闲置时正前方[1],行为时手持方向[0]

📒 自定义动作列表

注意:此处内容仅用于【自定义道具——Animations】相关使用。

道具手持动作是专门的动作池ID,无法与【角色自定义动作ID】相同使用。

道具动作主要支持Idle|Focus|Action三个状态(闲置、焦点、行为),具体动作ID参考《世界资源实例汇总——道具绑定动作》

在以上三个状态之中,焦点(Focus)是可省略的动作,如果不填写Focus则默认设为-1,且与Idle状态同步。

📒 使用道具及扩展

当通过上述操作成功注册\绑定道具后,开发者可能希望在游戏内使用新的道具,或者给不同的道具实现不同的功能,请参考此部分操作。

  1. 编写World脚本代码,建立相关角色,并使用chara.SetProp()功能【给予】角色一个道具到背包
  2. 进入游戏内测试,如果没有报错的情况下,角色应该已经成功手持(指定)新道具(确保chara.PropSlot正确)
  3. 此时可能发现道具因模型尺寸、位置不同,导致拿在手里的样式等不太正确,这需要根据上方的Json示例调整几次,直到满意为止
  4. 如果希望给道具绑定一些功能(例如:手持XXX,触发Action行为时做些什么,或者能否触发的前提条件),参考《OnCharacterPropActionBefore及OnCharacterPropAction》

📒 实际使用示例

根据上述介绍内容,这里以“如何自定义一个枪类武器”来解释。

[
    { //示例:枪械武器
		"ID": 10000, //道具ID
		"Model": 5163, //绑定模型ID
		"Pos": {"x": 0, "y": 0, "z": -0.2}, //这里可能因为模型规范不同,调整到一个合适的本地坐标偏移
		"Scale": {"x": 1.5, "y": 1.5, "z": 1.5}, //同样因为模型规范不同,调整合适的尺寸缩放
		"Flags": 132, //Flag类型(128+4 == 枪类+连续发射),只有这样“道具”才有了枪的属性和功能
		"Multiple": 1, //背包内槽内叠加数量(1=不可叠加,通常有特性的物品都不应该叠加)
		"Damage": 10, //枪的子弹伤害
		"DamageRange": 1, //子弹伤害检测范围,通常不建议过大
		"DamageShake": 1.0, //射击的后坐力偏移(如果为0则没有后坐力)
		"Distance": 35, //枪的射程,通常不建议过大
		"Direction": 1, //手持物品方向类型,不同的武器根据需要设定
		"PreloadTime": 0.75, //切换到物品时的冷却时间
		"Speed": 1.0, //物品每次Action时的动画速度,这里则表示射速
		"Audios": { //声音类(可空0)
			"Idle": 0, //拿出物品时声音
			"Focus": 0, //焦点时声音
			"Action": 0 //行为时声音
		},
		"Animations": { //动作类(可空0)
			"Idle": 2, //站立时动作
			"Focus": 15, //焦点时动作
			"Action": 15 //行为时动作
		}
	}
]

在设定好道具的Json配置内容后,开发者便可以继续在World脚本相关Action事件实现对应的逻辑。

function OnCharacterPropActionBefore(character, prop)
{
    //如果【被请求使用】的PropID为10000
	if(prop.ID == 10000)
	{
        //如果Data自定义属性不包括Bullet或者<=0,则表示没设置子弹或子弹不足
		if(prop.Data.Bullet == null || prop.Data.Bullet <= 0)
		{
            //返回0表示阻止使用(子弹不足)
			return 0;
		}
	}
 
    //默认返回1(可省略填写)
	return 1;
}
 
function OnCharacterPropAction(character, prop)
{
    //如果【正在使用】的PropID为10000
	if(prop.ID == 10000)
	{
        if(prop.Data.Bullet == null) prop.Data.Bullet = 100; //初始化,这里只是示例,实际上应该统一初始化编写
		if(prop.Data.Bullet > 0)
		{
			prop.Data.Bullet --;
		}
	}
}

补充:对于一些运行时动态调整属性(例如:Damage\Speed...等)修改需求,可参考《World/Prop》文档实现。

📒 总结

针对游戏道具扩展部分的内容,经过沙盘引擎开发组的自我评估,几乎很多扩展功能都可以通过上述内容实现,具体取决于开发者如何合理控制Json以及API的行为事件交互