Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Firebase Unity中更新分数,而不是替换/重新编写分数?_C#_Firebase_Unity3d_Firebase Realtime Database - Fatal编程技术网

C# 如何在Firebase Unity中更新分数,而不是替换/重新编写分数?

C# 如何在Firebase Unity中更新分数,而不是替换/重新编写分数?,c#,firebase,unity3d,firebase-realtime-database,C#,Firebase,Unity3d,Firebase Realtime Database,每当我重新打开游戏并再次开始得分时,它就会替换以前的数据。请帮帮我,告诉我哪里做错了 我正在使用Firebase实时数据库 下面是我的得分脚本: public static int cashValue; Text cash; void Start() { cash = GetComponent(); } void Update() { cash.text = "" + cashValue; } 这是我在Fireb

每当我重新打开游戏并再次开始得分时,它就会替换以前的数据。请帮帮我,告诉我哪里做错了

我正在使用Firebase实时数据库

下面是我的得分脚本:

public static int cashValue;

Text cash;

void Start()    
{    
  cash = GetComponent();    
}

void Update()    
{    
  cash.text = "" + cashValue;    
}
这是我在Firebase实时数据库中保存分数的地方:

private IEnumerator UpdateKills(int _kills)    
{    
  //Set the currently logged in user kills    
  var DBTask = DBreference.Child("users").Child(User.UserId).Child("kills").SetValueAsync(_kills);

  yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

  if (DBTask.Exception != null)    
  {    
    Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");    
  }    
  else    
  {    
    //Kills are now updated    
  }    
}
private IEnumerator LoadUserData()    
{    
  //Get the currently logged in user data    
  var DBTask = DBreference.Child("users").Child(User.UserId).GetValueAsync();

  yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

  if (DBTask.Exception != null)    
  {    
    Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");    
  }    
  else if (DBTask.Result.Value == null)    
  {    
    //No data exists yet    
    xpField.text = "0";    
    killsField.text = "0";    
    deathsField.text = "0";    
  }     
  else    
  {    
    //Data has been retrieved    
    DataSnapshot snapshot = DBTask.Result;    
    xpField.text = snapshot.Child("xp").Value.ToString();    
    killsField.text = snapshot.Child("kills").Value.ToString();    
    deathsField.text = snapshot.Child("deaths").Value.ToString();    
  }    
}
这是我从Firebase实时数据库检索数据的地方:

private IEnumerator UpdateKills(int _kills)    
{    
  //Set the currently logged in user kills    
  var DBTask = DBreference.Child("users").Child(User.UserId).Child("kills").SetValueAsync(_kills);

  yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

  if (DBTask.Exception != null)    
  {    
    Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");    
  }    
  else    
  {    
    //Kills are now updated    
  }    
}
private IEnumerator LoadUserData()    
{    
  //Get the currently logged in user data    
  var DBTask = DBreference.Child("users").Child(User.UserId).GetValueAsync();

  yield return new WaitUntil(predicate: () => DBTask.IsCompleted);

  if (DBTask.Exception != null)    
  {    
    Debug.LogWarning(message: $"Failed to register task with {DBTask.Exception}");    
  }    
  else if (DBTask.Result.Value == null)    
  {    
    //No data exists yet    
    xpField.text = "0";    
    killsField.text = "0";    
    deathsField.text = "0";    
  }     
  else    
  {    
    //Data has been retrieved    
    DataSnapshot snapshot = DBTask.Result;    
    xpField.text = snapshot.Child("xp").Value.ToString();    
    killsField.text = snapshot.Child("kills").Value.ToString();    
    deathsField.text = snapshot.Child("deaths").Value.ToString();    
  }    
}

它工作得很好,但唯一的问题是它会替换分数,而不是更新分数,或者从我离开的地方开始。流程应该是这样的:

int myData;
bool isMyDataLoaded = false;

void Start() {
   LoadMyData();
}

void LoadMyData() {
    StartCoroutine(IELoadMyData());
}

void SetMyData() {
    if(isMyDataLoaded) {
        // Set only if the data from database was retreived
        StartCoroutine(IESetMyData());
    }
}

IEnumerator IELoadMyData() {
    // Load your data from database here
    if(<fetch was successful>) {
        myData = <the result>;
        isMyDataLoaded = true; // Set data loaded as true
    }
}

IEnumerator IESetMyData() {
    // Update your data here
}
int-myData;
bool isMyDataLoaded=假;
void Start(){
LoadMyData();
}
void LoadMyData(){
start例程(IELoadMyData());
}
void SetMyData(){
如果(isMyDataLoaded){
//仅当从数据库检索数据时设置
start例程(IESetMyData());
}
}
IEnumerator IELoadMyData(){
//从这里加载数据库中的数据
if(){
myData=;
isMyDataLoaded=true;//将加载的数据设置为true
}
}
IEnumerator IESetMyData(){
//在此更新您的数据
}

现在,无论何时需要更新,都可以调用SetMyData。只有在本地游戏中首次成功获取数据时,才会在数据库中设置新数据。

需要注意的是,您可能会成为缓存的牺牲品。基本上,
GetValueAsync
通常会返回本地缓存的内容(除非禁用持久性——这可能不应该),并请求服务器进行更新
SetValueAsync
写入本地缓存并最终在后台同步

因此,要更新值,应始终使用事务。从

这需要重新修改逻辑,以便记录增量,而不是保存总杀死数。然后该事务将重复运行,直到成功为止(通常是一次,除非您的数据不同步,在这种情况下通常是两次)

为了获取数据,最好注册侦听器并直接从这些侦听器更新UI。通过这种方式,您可以始终与服务器保持同步,并且使用本地缓存足够智能,因此您不必担心总是阻塞网络访问(如果没有缓存,您将得到null)。此外,当事务中的本地缓存更新时,您将获得带有最新数据的ValueChanged事件


显然,并不是每一款游戏都能稳定地随机接收来自服务器的价值更新。但是,如果您可以在实时数据库中移动数据,使其更具反应性,那么您将充分利用其内置的本地缓存和同步逻辑。

在第一次杀戮更新之前,您必须从数据库中加载本地游戏中的数据。您能再解释一下吗?你的意思是我应该使用PlayerRefs吗?或者别的什么。。