[开发者心得] [单脚本]怪物编辑器 | 可视化配置生成怪物

[复制链接]
846 |3
森林鹿 发表于 2023-12-20 11:13:51 | 显示全部楼层 |阅读模式

本帖最后由 森林鹿 于 2024-1-25 17:00 编辑

重磅出炉!做怪物再也不用从0开始啦,只需要在可视化界面中配置一下就可以直接在游戏内生成! 点击下载 MyClearMobs.ts

1.02版本更新: 1.增加了静态模型怪物 2.对一些配置做了优化 3.增加了接口“设置怪物攻击目标”

使用教程

导入

先将单脚本下载下来,然后导入编辑器内 screenshot-20231220-103238.png 将脚本放进对象管理器中即可生效 image.png

如何使用

开启游戏后只需要通过可视化操作就可以配置怪物的属性 image.png 参数解释: 是否为角色/高级角色:这里角色对应着高级人形和基础人形,如果都设置为0,则模型处可以填写静态模型的GUID。 族群:多个怪物可以共享一个族群,从而实现不同怪物处于同一族群的最大数量限制。 额外用户数据:主要用来处理一些没有写到的参数,可以在此处填写Json的String值,然后通过API调用将String可以转换成可读的Json对象,从而实现扩展的效果,例如怪物的经验值、掉落物等。

配置完怪物属性后只需要将当前配置导出为JSON image.png 将JSON填入怪物数据库中,刚才配置的怪物就会生效啦 image.png

扩展使用

目前只有生成怪物的功能,如果需要打怪扣血等功能,需要自行去扩展使用。欢迎大家前往教程查看扩展用法:https://forum.ark.online/forum.php?mod=viewthread&tid=2318

方法

方法名称 调用端 描述 参数 返回类型
setEnemyTargetPlayerId 服务端 设置怪物目标玩家(即便设置生效了,也要玩家符合怪物的距离判定才会正常执行。) enemyGoGuid- 怪物对象的全局唯一标识符,targetPlayerId- 目标玩家ID。 boolean- 指示成功或失败。
tryHurtEnemy 服务端/客户端 尝试对怪物造成伤害。调用怪物组件的 onHit 方法。 go- 对象,attacker- 攻击者,damage- 伤害。 boolean- 指示成功或失败。
tryGetEnemyCom 服务端/客户端 从对象获取怪物组件(拓展用)。 go- 物体。 EnemyEntityComnull- 怪物组件或空。
getCfgAsync 服务端/客户端 异步获取怪物配置。 cfgId- 配置ID。 Promise- 怪物配置的 Promise。
createMob 服务端/客户端 根据提供的配置信息创建一组怪物。如果在客户端调用,会向服务器派发事件。 cfgJson- 配置信息。

事件

事件名称 调用端 描述 参数
onHitPlayer_server 服务端 当怪物攻击玩家时触发。 EnemyEntityCom- 怪物实体(拓展用),playerId- 被攻击的玩家id,damage- 怪物伤害
onBorn 服务端 当怪物出生时触发。 EnemyEntityCom- 怪物实体(拓展用)
onTakeDamage 服务端/同步距离内客户端 当怪物受到伤害时触发。处理客户端同步表现和服务端逻辑修改。 EnemyEntityCom- 怪物实体(拓展用),attackerPlayerId- 攻击的玩家id,damage- 伤害。
onDie 服务端 当怪物死亡时触发。 EnemyEntityCom- 怪物实体(拓展用),killerId- 杀死怪物的玩家id
更多图片 小图 大图
组图打开中,请稍候......
回复

使用道具 举报

天启 发表于 2024-1-17 21:26:55 | 显示全部楼层
本帖最后由 天启 于 2024-1-17 21:29 编辑

这个事件怎么调用呀?
MyClearMobs.onHitPlayer_server.add


image.png
这种会报错呀
回复

使用道具 举报

躲猫猫作者_思想的鱼 发表于 2024-1-30 10:28:39 | 显示全部楼层
createMob这个方法上面写的参数是cfgJson,而脚本的内容是:

/**
     *  创建怪物群
     * @param cfgId
     */
    public createMob(cfgId: number) {
        console.log("创建怪物群 : " + cfgId);
        const cfg = EnemyConfig.instance.getElement(cfgId);
        if (!this.allEnemyGroup.has(cfg.GroupId)) {
            this.allEnemyGroup.set(cfg.GroupId, new EnemyEntityGroup(cfg));
        }
        const group = this.allEnemyGroup.get(cfg.GroupId)
        group.addMob(cfgId)

    }

参考上面的内容,我感觉这里应该是传id。

MobsDefSelf.InitEnemyDatabaseJsonArr.forEach(e => {
            const id = EnemyConfig.instance.createElement(e);
            this.createMob(id);
        })



能不能加个接口,通过在别的脚本额外创建怪物。而不是通过初始化导入。

回复

使用道具 举报

使用了此脚本一月有余,目前反馈一下当前使用情况。


魔改内容:

1.通过excel配置怪物数据库。enemyDatabaseJsonArr = 怪物数据库。
表单表头如下:
Int
String
Int
String
String
Int
Int
Int
Int
Int
Int
Int
Int
Int
Int
Int
Int
Int
Int
String
Int
Int
Int
Int
Int
Int
String
id
Name

GroupId
backdes
GoGuid
type
ActiveDis
FindTargetDis
AttackTargetDis
SpawnPointX
SpawnPointY
SpawnPointZ
isChar
isV2
MoveSpeed
Hp
Level
Damage
Def
AttackGuid
DamageDelayTime
GroupSpawnMaxCount
GroupRebornTime
GroupRebornCount
ExtraUserDataGold
ExtraUserDataExp
ExtraUserDataWeapon
id
怪物索引
族群id
备注
模型
类型(1:普通2:经验)
活动范围
发现目标距离
攻击距离
出生点X
出生点Y
出生点
是否是角色(0/1)
是否高级角色(0/1)
移动速度
血量
等级
伤害
防御
攻击动画
伤害延迟(ms)
最大数量
复活时间(ms)
复活数量(最少1)
奖励金币
奖励经验
奖励武器

2.默认隐藏编辑器
编辑器默认隐藏,由创作者自由打开。
isShowEditor: boolean = false;

3.getTargetChar获取角色目标增加asyncReady()
let char = player.character;await char.asyncReady();调用时也需要增加await
let targetChar = await this.getTargetChar();

4.初始化设置。
由于我是引用了外部的怪物库,有极小概率拿不到。特意加了一个判定再次获取。这块还可以再次改进,可以200毫秒多次请求,直到拿到this.enemyDatabaseJsonArr
private initSetting() {        // console.log("enemyDatabaseJsonArr", this.enemyDatabaseJsonArr)        MobsDefSelf.EnemyDamageShowDis = this.enemyDamageShowDis;        MobsDefSelf.InitEnemyDatabaseJsonArr = this.enemyDatabaseJsonArr;        setTimeout(() => {            if (MobsDefSelf.InitEnemyDatabaseJsonArr.length === 0) {                MobsDefSelf.InitEnemyDatabaseJsonArr = this.enemyDatabaseJsonArr;            }        }, 200)    }
5.死亡逻辑动画注释
由于场景中的怪物较多,尽可能的减少动画一类,尤其是怪物死亡播放动画后,再次重生时,有时候会显示躺倒在地然后突然站在另一个位置。
// if (this.go instanceof Character) {        //     let dirAni = this.go.loadAnimation("189482");        //     this.go.complexMovementEnabled = false;        //     dirAni.play();        // }6.攻击逻辑做判断
禁止怪物对布娃娃的玩家进行攻击。
if(targetChar.ragdollEnabled) {            return;}
7.静态模型旋转角度调整
静态模型的正面没有对着玩家,进行了调整。+90.
this.com.repRotationZ = dir.toRotation().z + 90;

当前遇到的问题及困惑:
1.setInterval的延迟是不是太小了,增加了cpu的计算,浪费性能呢。
this.pid = PerTimer.setInterval(() => {            this.logic()        }, 1);2.静态模型,能不能移动。
3.如何保证大量怪物(500+)在同一个场景中,服务器的cpu不会太高。
4.怪物有个脱战区域,当追玩家追到一定的距离会自动回去。目前是会被玩家引怪引到很远的距离。
5.怪物在一定秒数内如果没有任何行动,是否可自行销毁。等待玩家再次进入才出现。(此问题是对3的一个建议)


建议:
1.将脚本中已废弃的方法替换掉
2.增加怪物模块的性能,保证大量怪物能够同屏,同场景。
3.目前我是准备通过怪物攻击玩家,增加一个怪物的攻击特效。主要是静态模型攻击,看不到任何效果就掉血 太突兀了。能不能由单脚本配置好这些攻击特效。
(当前的单脚本已经能够满足打怪的基本功能,最核心的需求就是大量的怪物。后续是有考虑通过切换场景来处理此问题。)


回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表