Skip to content
终点胜利

终点胜利

当玩家到达闯关小游戏的终点时,我们需要给出一些游戏反馈。本节课我们将学习使用动画、特效、音效来完成游戏中各个环节的反馈。

1.预览资源

下面给大家介绍动画、特效、音效这3个资源的预览方式。

预览动画

在美术资源中选中“动画”

点击动画资源右上角的放大镜图标

在弹出的窗口中,点击播放按钮即可预览动画

如果需要这个动画,就记录下它的AssetID

image-20230828190534560

预览特效

预览特效的方式和预览动画相似,也是需要点击资源右上角的放大镜来进行预览。

20230828-191154

预览音效

在美术资源中选中“音效”

点击音效资源右上角的放大镜图标

在弹出的窗口中,点击播放按钮即可预览音效

如果需要这个音效,就记录下它的 AssetID

image-20230829135555508

在这里列出本节课程中所用到的资源的 AssetID:

进入检查点触发的特效:【89097】

进入检查点触发的音效:【38193】

进入终点触发的特效:【142750】

进入终点触发的音效:【47425】

进入终点播放的动画:【14509】

死亡时播放的特效:【27421】

死亡时播放的音效:【120841】

提示

大家有可能通过上面提供的AssetID搜索不到对应的资源,那么有可能是因为资源被下架了,大家重新挑选一个自己喜欢的特效进行替换即可。

2.资源加载

这里的资源加载具有两个含义,分别是下载编辑器资源以及加载游戏资源

下载编辑器资源:

我们下载口袋方舟编辑器,是不会将资源库中的美术资源全部下载下来的,资源库的资源只有在我们需要使用的时候才会去进行下载。所以当我们第一次将资源拖动到场景上的时候,资源需要一个短暂的时间进行下载,下载过后再使用就不会卡顿了。

加载游戏资源:

我们的游戏在运行的时候也需要去加载各种美术资源,如果资源没有经过加载,那么使用代码去动态创建资源的时候,就会导致创建速度变慢

加载游戏资源的方式主要有3种:

方式一:将资源直接拖动到场景中。

方式二:将资源拖动到优先加载中。

方式三:使用AssetUtil.asyncDownloadAsset这个API来下载资源

下图展示了使用优先加载的方式来加载游戏资源

在搜索框输入资源的AssetID来进行资源查找

将找到的资源拖动到优先加载下

image-20230829143126618

3.终点&检查点 反馈

终点其实就是特殊的检查点,所以我们只需要在检查点脚本中添加反馈逻辑即可。

添加完反馈逻辑的CheckPointTrigger脚本内容如下:

该脚本有如下几个要点:

添加了对pointNumber的判断,当pointNumber为-1时,代表终点

通过loadAnimation进行动画播放

通过EffectService.playAtPosition进行特效播放

通过SoundService.playSound进行音效播放

ts
@Component
export default class CheckPointTrigger extends Script {

    @Property({ displayName: "序号" })
    public pointNumber: number = 0

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        let trigger = this.gameObject as Trigger
        trigger.onEnter.add((other: GameObject) => {
            // 进入的物体是否是角色
            if (other instanceof Character) {

                // 进入的角色 是否是 当前客户端角色
                if (other == Player.localPlayer.character) {
                    // 本地事件通信(派发)
                    Event.dispatchToLocal("CheckPoint", this)
                    // 播放特效 
                    EffectService.playAtPosition("89097", this.gameObject.worldTransform.position) 
                    // 播放音效 
                    SoundService.playSound("38193") 
                }

                // 如果关卡号为-1,代表终点 
                if (this.pointNumber == -1) { 
                    // 播放动作 
                    other.loadAnimation("14509").play() 
                    // 播放特效 
                    EffectService.playAtPosition("142750", this.gameObject.worldTransform.position) 
                    // 播放音效 
                    SoundService.playSound("47425") 
                } 
            }
        })
    }
}
@Component
export default class CheckPointTrigger extends Script {

    @Property({ displayName: "序号" })
    public pointNumber: number = 0

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {

        let trigger = this.gameObject as Trigger
        trigger.onEnter.add((other: GameObject) => {
            // 进入的物体是否是角色
            if (other instanceof Character) {

                // 进入的角色 是否是 当前客户端角色
                if (other == Player.localPlayer.character) {
                    // 本地事件通信(派发)
                    Event.dispatchToLocal("CheckPoint", this)
                    // 播放特效 
                    EffectService.playAtPosition("89097", this.gameObject.worldTransform.position) 
                    // 播放音效 
                    SoundService.playSound("38193") 
                }

                // 如果关卡号为-1,代表终点 
                if (this.pointNumber == -1) { 
                    // 播放动作 
                    other.loadAnimation("14509").play() 
                    // 播放特效 
                    EffectService.playAtPosition("142750", this.gameObject.worldTransform.position) 
                    // 播放音效 
                    SoundService.playSound("47425") 
                } 
            }
        })
    }
}

4.死亡反馈

角色死亡的逻辑是编写在关卡管理器脚本中的,所以我们需要在关卡管理器中编写死亡反馈逻辑。

添加完反馈逻辑的 LevelManager脚本 内容如下:

ts
import CheckPointTrigger from "./CheckPointTrigger"

/**
 * 关卡管理器
 */
export class LevelManager{
    // 单例模式
    private static _instacne:LevelManager
    public static get instance():LevelManager{
        if(LevelManager._instacne==null){
            LevelManager._instacne = new LevelManager()
        }
        return LevelManager._instacne
    }

    /**死亡触发器 */
    private _deathTrigger:Trigger

    /**复活位置 */
    private _rebornPosition:Vector = new Vector(10,0,420)

    public async init(){
        this._deathTrigger =  await GameObject.asyncFindGameObjectById("299CDDA6") as Trigger
        this._deathTrigger.onEnter.add((other:GameObject)=>{
            // 当进入的物体是角色类型
            if(other instanceof Character){
                // 让角色死亡
                this.charDeath(other)
            }
        })


        Event.addLocalListener("CheckPoint",(checkPointTrigger:CheckPointTrigger)=>{
            this._rebornPosition = checkPointTrigger.gameObject.worldTransform.position.clone()
        })
    }

    /**让角色死亡 */
    public charDeath(char:Character){
        // 开启布娃娃属性
        char.ragdollEnabled = true
        // 播放特效 
        EffectService.playAtPosition("27421",char.worldTransform.position) 
        // 播放音效 
        SoundService.playSound("120841") 
        setTimeout(() => {
            // 让角色复活
            this.charReborn(char)
        }, 3000);
    }

    /**让角色复活 */
    public charReborn(char:Character){
        if(char == Player.localPlayer.character){
            // 将角色的位置改变到复活点
            char.worldTransform.position = this._rebornPosition.clone()
        }

        // 关闭布娃娃属性
        char.ragdollEnabled = false
    }
}
import CheckPointTrigger from "./CheckPointTrigger"

/**
 * 关卡管理器
 */
export class LevelManager{
    // 单例模式
    private static _instacne:LevelManager
    public static get instance():LevelManager{
        if(LevelManager._instacne==null){
            LevelManager._instacne = new LevelManager()
        }
        return LevelManager._instacne
    }

    /**死亡触发器 */
    private _deathTrigger:Trigger

    /**复活位置 */
    private _rebornPosition:Vector = new Vector(10,0,420)

    public async init(){
        this._deathTrigger =  await GameObject.asyncFindGameObjectById("299CDDA6") as Trigger
        this._deathTrigger.onEnter.add((other:GameObject)=>{
            // 当进入的物体是角色类型
            if(other instanceof Character){
                // 让角色死亡
                this.charDeath(other)
            }
        })


        Event.addLocalListener("CheckPoint",(checkPointTrigger:CheckPointTrigger)=>{
            this._rebornPosition = checkPointTrigger.gameObject.worldTransform.position.clone()
        })
    }

    /**让角色死亡 */
    public charDeath(char:Character){
        // 开启布娃娃属性
        char.ragdollEnabled = true
        // 播放特效 
        EffectService.playAtPosition("27421",char.worldTransform.position) 
        // 播放音效 
        SoundService.playSound("120841") 
        setTimeout(() => {
            // 让角色复活
            this.charReborn(char)
        }, 3000);
    }

    /**让角色复活 */
    public charReborn(char:Character){
        if(char == Player.localPlayer.character){
            // 将角色的位置改变到复活点
            char.worldTransform.position = this._rebornPosition.clone()
        }

        // 关闭布娃娃属性
        char.ragdollEnabled = false
    }
}