在服务端创建炸弹
阅读本文大概需要 10 分钟
本节将会实现点击攻击按钮,释放一颗炸弹的功能。
在前几章我们制作了控制 UI,并使用导出脚本功能,将所有 UI 导出了对应的脚本文件。之后我们使用脚本添加了跳跃按钮与攻击按钮的点事件响应,本章节我们要给攻击按钮事件加上对应的逻辑。
打开 CtrlUI 脚本
,我们来添加一个释放炸弹的函数,要实现如下功能:
- 每秒只能释放一次炸弹,释放过后必须等待一秒才能再次释放,期间点击按钮不执行任何功能。
- 点击按钮后,如果判断可以释放炸弹,就像服务端发送一条消息,通知服务器在玩家位置释放一个炸弹。
typescript
import CtrlUI_Generate from "./ui-generate/CtrlUI_generate";
export default class CtrlUI extends CtrlUI_Generate {
//释放炸弹 cd,主要用来计时并控制 1 秒内允许释放一个炸弹
timer: number = 0;
/**
* 构造UI文件成功后,在合适的时机最先初始化一次
*/
protected onStart() {
//设置能否每帧触发onUpdate
this.canUpdate = false;
this.layer = UILayerMiddle;
this.mAttackBtn.onClicked.add(() => {
this.onClickAttackBtn();
});
this.mJumpBtn.onClicked.add(() => {
Player.asyncGetLocalPlayer().then((player) => {
// 让玩家进行跳跃
player.character.jump();
});
});
}
/**
* 使用炸弹
*/
private onClickAttackBtn() {
if (this.timer == 0) {
//重置倒计时为 1000 设置1秒的释放炸弹CD
this.timer = 1000;
//通知服务器玩家释放了炸弹
Event.dispatchToServer("Event_Bomb");
//开始倒计时
setTimeout(() => {
//倒计时到期后设置时间
this.timer = 0;
}, this.timer);
}
}
}
import CtrlUI_Generate from "./ui-generate/CtrlUI_generate";
export default class CtrlUI extends CtrlUI_Generate {
//释放炸弹 cd,主要用来计时并控制 1 秒内允许释放一个炸弹
timer: number = 0;
/**
* 构造UI文件成功后,在合适的时机最先初始化一次
*/
protected onStart() {
//设置能否每帧触发onUpdate
this.canUpdate = false;
this.layer = UILayerMiddle;
this.mAttackBtn.onClicked.add(() => {
this.onClickAttackBtn();
});
this.mJumpBtn.onClicked.add(() => {
Player.asyncGetLocalPlayer().then((player) => {
// 让玩家进行跳跃
player.character.jump();
});
});
}
/**
* 使用炸弹
*/
private onClickAttackBtn() {
if (this.timer == 0) {
//重置倒计时为 1000 设置1秒的释放炸弹CD
this.timer = 1000;
//通知服务器玩家释放了炸弹
Event.dispatchToServer("Event_Bomb");
//开始倒计时
setTimeout(() => {
//倒计时到期后设置时间
this.timer = 0;
}, this.timer);
}
}
}
上面这个脚本我们向服务器发送了一条消息 Event_Bomb
,服务端接收到之后在玩家位置实例化一个炸弹预制体。
预制体实例化
将预制体在场景中生成出来的过程叫做预制体的实例化。
打开之前编写的 GameStart
脚本,添加实例化炸弹预制体的方法:
typescript
import CtrlUI from "./CtrlUI";
import HPbarUI from "./HPbarUI";
@Component
export default class GameStart extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart(): void {
if (SystemUtil.isClient()) {
UIService.show(CtrlUI);
UIService.show(HPbarUI);
}
if (SystemUtil.isServer()) {
// player 参数为发送这个事件来的客户端玩家
Event.addClientListener("Event_Bomb", (player: Player) => {
// 下一行函数需要填入预制体 assetId ,请在工程内容中右键预制体 获取 工程内容ID
const bombObj = GameObject.spawn(填入预制体 AssetId);//替换 为项目中预制体资源id
// 将炸弹位置设置为玩家位置
bombObj.worldTransform.position = player.character.worldTransform.position;
});
}
}
}
import CtrlUI from "./CtrlUI";
import HPbarUI from "./HPbarUI";
@Component
export default class GameStart extends Script {
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart(): void {
if (SystemUtil.isClient()) {
UIService.show(CtrlUI);
UIService.show(HPbarUI);
}
if (SystemUtil.isServer()) {
// player 参数为发送这个事件来的客户端玩家
Event.addClientListener("Event_Bomb", (player: Player) => {
// 下一行函数需要填入预制体 assetId ,请在工程内容中右键预制体 获取 工程内容ID
const bombObj = GameObject.spawn(填入预制体 AssetId);//替换 为项目中预制体资源id
// 将炸弹位置设置为玩家位置
bombObj.worldTransform.position = player.character.worldTransform.position;
});
}
}
}
上述代码实现了以下功能:当服务端收到 Event_Bomb
事件时,会在发送该事件的玩家的角色位置实例化一个炸弹预制体。
在使用 GameObject.spawn
函数时,我们需要传入预制体的 ID,可以通过在工程内容中右键预制体 --> 复制工程内容 ID 来获取。
将复制到的 ID 填写到上述GameStart
代码中第十九行 GameObject.spawn
函数的括号中。然后保存代码运行即可查看效果了。