我正在使用Unity创建一个简单的2D多人游戏,我选择使用Firebase作为后端。尝试使用Firebase Cloud功能填充房间时,我遇到了一些问题。我计划如何工作如下:
以下是云功能:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
var room = [];
// ID for the room we are filling at the moment
var room_currentID;
// This functions triggers each time something is added or deleted to "Players Searching For Room"
exports.findRoom = functions.database
.ref('/Players Searching For Room/{pushId}')
.onWrite(event => {
// Check if data exists (if not, this was triggered by delete -> return)
if(!event.data.exists())
{
return;
}
// If this player already has a room, we want to return
if(event.data.val().inRoom != "none")
return;
// Store data under changed pushId (if player was added to waiting players then data is -> "size" : 4)
const data = event.data.val();
// Name of the player. We get this from the pushId of the item we pushed ("container" for data pushed).
var name = event.params.pushId;
// Size of the room the player wants to join
var size = data.size;
// With IF-statements check which room_size_n object array we want to loop through
console.log("Player called " + name + " is waiting for room that has maxium of " + size + " players")
// We can push the user to the room array since it can never be full
// (we clear the array before allowing next guy to join)
room.push(name);
// If this was the first guy
// we need to create new room
if(room.length == 1)
{
admin.database().ref('/Rooms').push({
onGoing: false // We need to set something, might aswell set something usefull
}).then(snapshot => {
// because this function is triggered by changes in firebase realtime database
// we can't return anything to the player. BUT we can inform player about the room
// he's been attached to by adding roomID to the playername in the "Players Searching For Room"
// then players device will handle removing
// Store ID of the room so that we can send it to later joiners in this room
room_currentID = snapshot.key;
data.inRoom = room_currentID;
return event.data.ref.set(data);
});
}
// If there already exists a suitable room with space on it
else if(room.length > 1)
{
// We can attach the stored roomID to the player so he knows which rooms onGoing flag to watch for.
data.inRoom = room_currentID;
// Attach roomID to the player and then check if room is full
// waiting roomID to attach to player before setting onGoing TRUE
// prevents other player to get a head start
event.data.ref.set(data).then(snapshot => {
// If roomId was attached to the player we can check the room size
if(room.length == size)
{
// ...and if the room became full we need to set onGoing to true
admin.database().ref('/Rooms/'+room_currentID).set({
onGoing: true
}).then(snapshot => {
room = [];
});
}
});
}
});
问题是,如果多个用户在短时间内点击Join Game-button
,则会导致系统混乱。在“玩家搜索房间”下添加玩家ID似乎每次都有效,但有时云功能从不将房间ID附加到玩家ID,有时云功能会创建比应有的更多的房间。我只是通过在每次单击时在“Players Searching For Room”下附加随机ID的按钮来测试这个。然后我快速点击该按钮10次。这应该为这10个随机ID附加5个不同的房间ID,并生成5个新房间。相反,它生成了7个房间,并且只为8个随机ID添加了房间ID,而不是10个。
问题是,我认为:
是否可以使用firebase来改变这一点,以便如果Rob在Abe的请求完成之前触发Cloud功能,Rob将在Abe完成时被搁置。当安倍晋三完成而不是罗伯的回合。唉,非常长的解释希望有人会读到这个:)
答案 0 :(得分:1)
在Google I / O 2017上,我发表了关于在后端仅使用Firebase构建多人游戏的演讲。云功能几乎实现了游戏的所有逻辑。它还具有简单的匹配功能,您可以扩展该方案以执行更复杂的操作。您可以观看演讲here,该项目的源代码即将推出。