本帖最后由 啊啵呲嘚 于 2023-12-19 15:52 编辑
用编辑器自带的API:
Player.onPlayerDisconnect,当玩家掉线时执行绑定函数。该委托双端触发机制不同。在客户端只被本地玩家掉线事件触发,触发时机为掉线的瞬间。在服务端被任意玩家掉线事件触发,触发时机为5秒内未收到客户端玩家消息即为掉线。
当客户端切后台、看广告等OnPause操作时,该回调在服务器上也会被触发。
Player.onPlayerDisconnect.add((player: Player) => {
console.log('断开连接 [ userId ] >', player.userId)
})
如何自定义心跳检测:
心跳检测的原理是,客户端每隔一段时间向服务端发送消息,服务端在一个时间间隔里没有收到该客户端的消息时,视为该客户端已经断开连接。
@Component
export default class HeartRateCheck extends Script {
@Property({ displayName: "是否使用自定义检测时间" })
isCustom: boolean = false;
@Property({ displayName: "检测时间(ms)" })
checkTime: number = 1000;
@Property({ displayName: "断开时间(ms)" })
delayTime: number = 1500;
private _heartRate: Map<string, number> = new Map()
private _intervalId: number;
private _playerDisconnect: (player: Player) => void = (player: Player) => {
console.log('退出 [ userId ] >', player.userId)
HeartRateCheck.onHeartRateCheck.broadcast(player)
}
static readonly onHeartRateCheck: mw.MulticastDelegate<(player: Player) => void> = new mw.MulticastDelegate()
/** 当脚本被实例后,会在第一帧更新前调用此函数 */
protected onStart(): void {
if (this.isCustom) {
if (SystemUtil.isClient()) {
this._intervalId = setInterval(() => {
this.heartRateCheck(Player.localPlayer.userId)
}, this.checkTime)
}
} else if (SystemUtil.isServer()) {
Player.onPlayerDisconnect.add(this._playerDisconnect)
}
}
@RemoteFunction(Server)
heartRateCheck(userId: string) {
console.log('[ userId ] >', userId)
if (this._heartRate.has(userId)) {
const id = this._heartRate.get(userId)
clearTimeout(id)
}
this._heartRate.set(userId, setTimeout(() => {
console.log('退出 [ userId ] >', userId)
HeartRateCheck.onHeartRateCheck.broadcast(Player.getPlayer(userId))
}, this.delayTime))
}
/**
* 周期函数 每帧执行
* 此函数执行需要将this.useUpdate赋值为true
* @param dt 当前帧与上一帧的延迟 / 秒
*/
protected onUpdate(dt: number): void {
}
/** 脚本被销毁时最后一帧执行完调用此函数 */
protected onDestroy(): void {
if (SystemUtil.isServer()) {
if (this.isCustom) {
for (const [, id] of this._heartRate) {
clearTimeout(id)
}
this._heartRate.clear()
} else {
Player.onPlayerDisconnect.remove(this._playerDisconnect)
}
}
if (SystemUtil.isClient() && this.isCustom) {
if (this._intervalId) {
clearInterval(this._intervalId)
}
}
}
}
心跳检测预制体
HeartRateCheck.zip
(6.35 KB, 下载次数: 56)
|