本文节选自洪流学堂公众号技术专栏《大话Unity2019》,未经允许不可转载。
洪流学堂公众号回复专栏
,查看更多专栏文章。
洪流学堂,让你快人几步。你好,我是郑洪智。
小新:“有了用户登录后,我们总要拿来做点什么事情吧?”
大智:“有了用户登陆信息之后,就可以针对用户来存储他自己的信息了,比如说装备、个人数据、闯关信息等等。”
小新:“是不是类似本地的存档,只不过存到了服务器上?”
大智:“可以这么理解,今天我们来尝试下存储玩家的最高分,并且获取全服的排行榜。”
LeanCloud存储玩家分数
LeanCloud中存储数据的需要用到“对象”,文档在这里:https://leancloud.cn/docs/rest_api.html#hash735965996
如果你熟悉数据库的话,对象类似数据库中的一个表,但是这个对象没有固定的字段,不需要提前标注每个对象上有哪些 key,你你只需要随意设置键值对就可以,后端会保存它。
创建LeanCloud对象
要想使用LeanCloud的对象,可以先在LeanCloud网站的控制台创建对象,也可以不事先创建对象,而通过代码创建。
事先创建的话,可以设置权限:
写入LeanCloud对象
写入LeanCloud对象直接上代码喽:
using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Random = UnityEngine.Random;
// 上传分数的Score类,用于序列化成json
[Serializable]
public class Score
{
public int score;
}
// 用于解析登陆后的token,这个token用来代表已登录的用户
[Serializable]
public class LoginToken{
public string sessionToken;
}
public class LeanCloudUser : MonoBehaviour
{
public string AppId;
public string AppKey;
public InputField Username;
public InputField Password;
private string Token;
public void Reg()
{
var jsonObj = new RegJson()
{
username = Username.text,
password = Password.text
};
var json = JsonUtility.ToJson(jsonObj);
Debug.Log(json);
StartCoroutine(Request("/users", json));
}
public void Login()
{
var jsonObj = new RegJson()
{
username = Username.text,
password = Password.text
};
var json = JsonUtility.ToJson(jsonObj);
Debug.Log(json);
StartCoroutine(Request("/login", json, text =>
{
var obj = JsonUtility.FromJson<LoginToken>(text);
Token = obj.sessionToken;
UploadMyScore(Random.Range(1, 100));
}));
}
// 重构了请求的类,现在可以更好地适用各种请求
IEnumerator Request(string path, string json, Action<string> cb = null)
{
var url = "https://5jmvfx9e.api.lncld.net/1.1" + path;
var www = UnityWebRequest.Put(url, json);
www.method = "POST";
www.SetRequestHeader("X-LC-Id", AppId);
www.SetRequestHeader("X-LC-Key", AppKey);
www.SetRequestHeader("Content-Type", "application/json");
if (!string.IsNullOrEmpty(Token))
www.SetRequestHeader("X-LC-Session", Token);
yield return www.SendWebRequest();
if (www.isHttpError || www.isNetworkError)
{
Debug.LogError(www.error);
Debug.LogError(www.downloadHandler.text);
}
else
{
Debug.Log(www.downloadHandler.text);
if (cb != null) cb(www.downloadHandler.text);
}
}
// 上传分数的方法
private void UploadMyScore(int score)
{
var json = JsonUtility.ToJson(new Score(){
score = score
});
StartCoroutine(Request("/classes/Score", json));
}
}
上面的代码是基于昨天小新重构后的代码又进行了一次重构,现在可以更好地满足不同的请求了。
执行后,就可以在后台看到上传上去的分数了。
LeanCloud排行榜
现在我们有了分数了,怎么获取到排行榜的数据呢?这就需要用到LeanCloud中的对象查询。
文档在这:https://leancloud.cn/docs/rest_api.html#hash860317
排行榜的查询呢,会稍微有一些复杂, 因为我们需要根据玩家的分数进行倒序排列,并取出前10个。
由于取数据使用的HTTP方法是GET,所以需要对代码进行不小的重构,最后代码如下:
using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Random = UnityEngine.Random;
// 上传分数的Score类,用于序列化成json
[Serializable]
public class Score
{
public string username;
public string userId;
public int score;
}
// 用于解析登陆后的token,这个token用来代表已登录的用户
[Serializable]
public class UserInfo{
public string sessionToken;
public string username;
public string objectId;
}
public class LeanCloudUser : MonoBehaviour
{
public string AppId;
public string AppKey;
public InputField Username;
public InputField Password;
private UserInfo User;
public void Reg()
{
var jsonObj = new RegJson()
{
username = Username.text,
password = Password.text
};
var json = JsonUtility.ToJson(jsonObj);
Debug.Log(json);
StartCoroutine(Request("/users", "POST", json));
}
public void Login()
{
var jsonObj = new RegJson()
{
username = Username.text,
password = Password.text
};
var json = JsonUtility.ToJson(jsonObj);
Debug.Log(json);
StartCoroutine(Request("/login", "POST", json, text =>
{
var obj = JsonUtility.FromJson<UserInfo>(text);
User = obj;
UploadMyScore(Random.Range(1, 100));
}));
}
// 重构了请求的类,现在可以更好地适用各种请求
IEnumerator Request(string path, string method = "POST", string data = "", Action<string> cb = null)
{
var url = "https://5jmvfx9e.api.lncld.net/1.1" + path;
var downloadHandler = new DownloadHandlerBuffer();
UploadHandlerRaw uploadHandler = null;
if (!string.IsNullOrEmpty(data))
uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
var www = new UnityWebRequest(url, method, downloadHandler, uploadHandler);
www.SetRequestHeader("X-LC-Id", AppId);
www.SetRequestHeader("X-LC-Key", AppKey);
www.SetRequestHeader("Content-Type", "application/json");
yield return www.SendWebRequest();
if (www.isHttpError || www.isNetworkError)
{
Debug.LogError(www.error);
Debug.LogError(www.downloadHandler.text);
}
else
{
Debug.Log(www.downloadHandler.text);
if (cb != null) cb(www.downloadHandler.text);
}
}
// 上传分数的方法
private void UploadMyScore(int score)
{
var json = JsonUtility.ToJson(new Score(){
score = score,
username = User.username,
userId = User.objectId
});
StartCoroutine(Request("/classes/Score", "POST", json, _=>{
GetLeaderboard();
}));
}
public void GetLeaderboard(){
var path = "/classes/Score?";
path += "order=-score&limit=10";
StartCoroutine(Request(path, "GET"));
}
}
在这由于取出排行榜中的数据要用GET,终于我们没办法使用取巧的请求方式了,老老实实地改回来正常的请求方法。
总结
小新:“其实代码看下来,请求的方式都是类似的,比较重要的是先好好看懂LeanCloud的文档,然后构造相应的请求就可以了。”
大智:“没错,读文档的能力是很重要的,以后写出一份好文档的能力是更重要的。”
思考题
大智:“取到排行榜的数据以后,看看能不能显示到UI上面?”
小新:“好嘞!”
大智:“收获别忘了分享出来!也别忘了分享给你学Unity的朋友,也许能够帮到他。”
- 洪流学堂公众号回复
专栏
,查看更多专栏文章。
《大话Unity2019》,大智带小新学Unity2019的有趣经历,让你学Unity更简单。