[开发者心得] 如何制作一个血条。

[复制链接]
1365 |9
犯困嫌疑人 发表于 2023-5-12 10:48:49 | 显示全部楼层 |阅读模式
本帖最后由 犯困嫌疑人 于 2023-5-12 10:53 编辑

1.首先先随手搭建一个UI,这个UI包含了一个滑动条和一个文本
image.png
image.png
我们将它起名为UIHP。并导出UI。
image.png


2.新建一个脚本~叫做HPBar

image.png



import UIHP_Generate from "./ui-generate/UIHP_generate";

@Core.Class
export default class HPBar extends Core.Script {

    @Core.Property({ replicated: true, onChanged: "onHpChange" })
    public maxHp: number = 0;

    @Core.Property({ replicated: true, onChanged: "onHpChange" })
    public hp: number = 0;

    private _hpBarUI: UIHP_Generate;

    private _hpBarWidget: Gameplay.UIWidget;

    private _isInit = false;

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        if (SystemUtil.isClient()) {
            console.log("qwq")
            this.init();
        }
    }

    private async init() {
        this._hpBarUI = UI.UIManager.instance.create(UIHP_Generate);
        this._hpBarWidget = await Gameplay.GameObject.asyncSpawn<Gameplay.UIWidget>({ guid: "UIWidget", replicates: false });
        this._hpBarWidget.setTargetUIWidget(this._hpBarUI.uiWidgetBase);
        this._hpBarWidget.widgetSpace = Gameplay.WidgetSpaceMode.OverheadUI;
        let character = this.gameObject as Gameplay.CharacterBase;
        this._hpBarWidget.attachToGameObject(character.getHeadUIWidget())
        this._hpBarWidget.relativeLocation = Vector.up.multiply(-10);
        this._isInit = true;
        this.onHpChange();
    }

    private onHpChange() {
        if (!this._isInit) {
            return;
        }
        this._hpBarUI.mScollHP.percent = this.hp / this.maxHp;
        this._hpBarUI.mTextHPNum.text = `${this.hp}/${this.maxHp}`;
    }

    protected onDestroy(): void {
        this._hpBarUI?.destroy();
        this._hpBarWidget?.destroy();
    }
}




再新建一个脚本,叫做GameLauncher来测试这个脚本



import HPBar from "./HPBar"

@Core.Class
export default class GameLauncher extends Core.Script {
    private _hpbarMap: Map<number, HPBar> = new Map();


    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        if (SystemUtil.isServer()) {
            Events.addPlayerJoinedListener(async (player: Gameplay.Player) => {
                let hpbar = await Gameplay.Script.spawnScript(HPBar, true, player.character);
                hpbar.maxHp = 100;
                hpbar.hp = 80;
                this._hpbarMap.set(player.getPlayerID(), hpbar);
            })
            Events.addPlayerLeftListener((player: Gameplay.Player) => {
                if (this._hpbarMap.has(player.getPlayerID())) {
                    this._hpbarMap.get(player.getPlayerID()).destroy();
                    this._hpbarMap.delete(player.getPlayerID());
                }
            })
        }
    }
}

把GameLauncher拖入到场景中,我们就可以看到效果了。在实战中去服务器修改对应scripts的hp值和mhp就可以达到效果了。
image.png


image.png
回复

使用道具 举报

叽里咕噜小胡桃 发表于 2023-5-12 10:49:59 | 显示全部楼层
很棒!!最近刚好在准备做fps!! 正愁不知道怎么做血条!! 楼主6666
回复

使用道具 举报

alphaAE 发表于 2023-5-12 10:52:19 | 显示全部楼层
牛啊牛啊
回复

使用道具 举报

叽里咕噜小胡桃 发表于 2023-5-12 13:31:49 | 显示全部楼层
有个问题比较好奇,为什么在this._hpBarWidget = await Gameplay.GameObject.asyncSpawn<Gameplay.UIWidget>({ guid: "UIWidget", replicates: false });中,生成世界UI的replicates要选择false,世界UI不应该要同步给所有客户端吗?
回复

使用道具 举报

犯困嫌疑人楼主 发表于 2023-5-12 13:53:38 | 显示全部楼层
叽里咕噜小胡桃 发表于 2023-5-12 13:31
有个问题比较好奇,为什么在this._hpBarWidget = await Gameplay.GameObject.asyncSpawn({ guid: "UIWidget ...

这个脚本是双端的,UI在C端生成显示用。
回复

使用道具 举报

犯困嫌疑人楼主 发表于 2023-5-12 13:54:10 | 显示全部楼层
叽里咕噜小胡桃 发表于 2023-5-12 13:31
有个问题比较好奇,为什么在this._hpBarWidget = await Gameplay.GameObject.asyncSpawn({ guid: "UIWidget ...


    @Core.Property({ replicated: true, onChanged: "onHpChange" })

    public maxHp: number = 0;



    @Core.Property({ replicated: true, onChanged: "onHpChange" })

    public hp: number = 0;

这两个属性的replicated才是实质显示的数值。
回复

使用道具 举报

叽里咕噜小胡桃 发表于 2023-5-12 13:57:02 | 显示全部楼层
犯困嫌疑人 发表于 2023-5-12 13:54
@Core.Property({ replicated: true, onChanged: "onHpChange" })

    public maxHp: number = 0;

原来如此,谢谢老哥!
回复

使用道具 举报

kk 发表于 2023-5-12 15:45:26 | 显示全部楼层
大佬,666
回复

使用道具 举报

猪头BOOM 发表于 2023-5-26 16:02:53 | 显示全部楼层
大佬请问如果我想要血条挂载在obj上而不是角色身上应该怎么实现,试过把脚本生成在obj下,但是没有出现效果。
let obj = this.gameObject as Gameplay.GameObject;
        this._hpBarWidget.attachToGameObject(obj);
回复

使用道具 举报

化蛹为碟 发表于 2023-6-19 13:56:53 | 显示全部楼层
为什么this._hpBarWidget.setTargetUIWidget(this._hpBarUI.uiWidgetBase);这句话报错:
unhandledRejection,TypeError: Cannot read property 'get' of null,TypeError: Cannot read property 'get' of null
    at newConstructor.setTargetUIWidget (D:\MetaApp\Editor_Win64\WindowsNoEditor\MW\Content\JavaScript\MWUserBootstrap.js:26881:44)
    at Proxy.init (D:\MetaApp\Editor_Win64\MetaWorldSaved\Saved\MetaWorld\Projects\test2\dist\game.js:236:23)

回复

使用道具 举报

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