辅助功能
本节课将制作两个辅助功能,“复位”和“跳关”,这里对功能做一个简单介绍:
复位:能够让玩家操控的角色在被卡住或者穿模的情况下,快速回到上一个检查点位置
跳关:输入关卡序号即可跳转到指定关卡,方便我们对关卡进行测试
1.制作HelperUI
这两个辅助功能主要是通过UI来让玩家进行操控的,所以我们需要先制作UI。
创建HelperUI
①点击工程内容下的“UI”
②点击“新建UI”
③将UI的名称修改为“HelperUI”
拼UI并导出脚本
①拖入一个文本按钮控件,命名为mRest_btn,代表复位按钮
①拖入一个文本按钮控件,命名为mJump_btn,代表跳关按钮
①拖入一个输入框控件,命名为mJump_input,代表跳关输入框
②点击“导出所有脚本”
2.编写HelperUI脚本
创建HelperUI脚本
①选择“UI”文件夹
②点击"新建脚本"
③将脚本的名字修改为HelperUI
创建好之后,在HelperUI脚本里编写内容如下:
该脚本继承了HelperUI_Generate,所以脚本就能够控制HelperUI上的控件,在这里分别给复位按钮以及跳关按钮添加了点击事件,但是还没有编写具体的事件逻辑。
ts
import HelperUI_Generate from "../ui-generate/HelperUI_generate";
export class HelperUI extends HelperUI_Generate{
protected onAwake(): void {
// 复位功能
this.mRest_btn.onPressed.add(()=>{
})
// 跳关功能
this.mJump_btn.onPressed.add(()=>{
})
}
}
import HelperUI_Generate from "../ui-generate/HelperUI_generate";
export class HelperUI extends HelperUI_Generate{
protected onAwake(): void {
// 复位功能
this.mRest_btn.onPressed.add(()=>{
})
// 跳关功能
this.mJump_btn.onPressed.add(()=>{
})
}
}
有了HelperUI脚本后,我们就需要在游戏一开始通过UIService将HelperUI显示出来。
在GameStart脚本中添加显示HelperUI的逻辑
ts
import { LevelManager } from "./LevelManager";
import { HelperUI } from "./UI/HelperUI";
@Component
export default class GameStart extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected async onStart(): Promise<void> {
if(SystemUtil.isClient()){
LevelManager.instance.init()
UIService.show(HelperUI);
}
}
}
import { LevelManager } from "./LevelManager";
import { HelperUI } from "./UI/HelperUI";
@Component
export default class GameStart extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected async onStart(): Promise<void> {
if(SystemUtil.isClient()){
LevelManager.instance.init()
UIService.show(HelperUI);
}
}
}
3.编写跳关函数
复位是返回到上一关,跳关是传送到指定关,所以这两个功能实际上只需要一个函数就能完成。
在LevelManager脚本中添加跳关函数:
本次添加有如下几个要点:
①添加了一个代表上一个检查点序号的成员变量lastPointNumber
②在角色进入检查点的时候,更新lastPointNumber
③编写jumpToPoint函数,该函数通过接收一个数字,然后根据数字去checkPointMap中获取检查点脚本,从而得到检查点,并将角色的位置设置到检查点位置从而完成了跳关功能。
④jumpToPoint函数默认使用lastPointNumber,即不传入参数,函数会默认跳到上一关。
ts
import CheckPointTrigger from "./CheckPointTrigger"
import GameUI from "./UI/GameUI"
/**
* 关卡管理器
*/
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 checkPointMap: Map<number, CheckPointTrigger> = new Map()
/**上一个检查点的序号 */
public lastPointNumber: number = 0
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()
this.lastPointNumber = checkPointTrigger.pointNumber
})
setTimeout(() => {
UIService.show(GameUI, this.checkPointMap.size, 0)
}, 2000);
}
/**让角色死亡 */
public charDeath(char: Character) {
// 开启布娃娃属性
char.ragdollEnabled = true
// 播放特效
EffectService.playAtPosition("27421", char.worldTransform.position)
// 播放音效
SoundService.playSound("120841")
setTimeout(() => {
// 让角色复活
this.charReborn(char)
}, 3000);
if (char == Player.localPlayer.character) {
Event.dispatchToLocal("Death")
}
}
/**让角色复活 */
public charReborn(char: Character) {
if (char == Player.localPlayer.character) {
// 将角色的位置改变到复活点
char.worldTransform.position = this._rebornPosition.clone()
}
// 关闭布娃娃属性
char.ragdollEnabled = false
}
/**
* 跳转到指定关卡
* @param pointNumber 关卡号
*/
public jumpToPoint(pointNumber: number = this.lastPointNumber) {
// 实现跳转
let checkPoint = this.checkPointMap.get(pointNumber)
if (checkPoint) {
Player.localPlayer.character.worldTransform.position = checkPoint.gameObject.worldTransform.position.clone()
}
}
}
import CheckPointTrigger from "./CheckPointTrigger"
import GameUI from "./UI/GameUI"
/**
* 关卡管理器
*/
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 checkPointMap: Map<number, CheckPointTrigger> = new Map()
/**上一个检查点的序号 */
public lastPointNumber: number = 0
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()
this.lastPointNumber = checkPointTrigger.pointNumber
})
setTimeout(() => {
UIService.show(GameUI, this.checkPointMap.size, 0)
}, 2000);
}
/**让角色死亡 */
public charDeath(char: Character) {
// 开启布娃娃属性
char.ragdollEnabled = true
// 播放特效
EffectService.playAtPosition("27421", char.worldTransform.position)
// 播放音效
SoundService.playSound("120841")
setTimeout(() => {
// 让角色复活
this.charReborn(char)
}, 3000);
if (char == Player.localPlayer.character) {
Event.dispatchToLocal("Death")
}
}
/**让角色复活 */
public charReborn(char: Character) {
if (char == Player.localPlayer.character) {
// 将角色的位置改变到复活点
char.worldTransform.position = this._rebornPosition.clone()
}
// 关闭布娃娃属性
char.ragdollEnabled = false
}
/**
* 跳转到指定关卡
* @param pointNumber 关卡号
*/
public jumpToPoint(pointNumber: number = this.lastPointNumber) {
// 实现跳转
let checkPoint = this.checkPointMap.get(pointNumber)
if (checkPoint) {
Player.localPlayer.character.worldTransform.position = checkPoint.gameObject.worldTransform.position.clone()
}
}
}
4.完善HelperUI脚本逻辑
有了跳关功能,我们就需要给HelperUI上的按钮添加执行跳关功能的逻辑
编写HelperUI脚本逻辑如下:
ts
import { LevelManager } from "../LevelManager";
import HelperUI_Generate from "../ui-generate/HelperUI_generate";
export class HelperUI extends HelperUI_Generate{
protected onAwake(): void {
// 复位功能
this.mRest_btn.onPressed.add(()=>{
LevelManager.instance.jumpToPoint()
})
// 跳关功能
this.mJump_btn.onPressed.add(()=>{
LevelManager.instance.jumpToPoint( Number(this.mJump_input.text))
})
}
}
import { LevelManager } from "../LevelManager";
import HelperUI_Generate from "../ui-generate/HelperUI_generate";
export class HelperUI extends HelperUI_Generate{
protected onAwake(): void {
// 复位功能
this.mRest_btn.onPressed.add(()=>{
LevelManager.instance.jumpToPoint()
})
// 跳关功能
this.mJump_btn.onPressed.add(()=>{
LevelManager.instance.jumpToPoint( Number(this.mJump_input.text))
})
}
}