PlatMsgManager

PlatMsgManager添加QQAuthorValidGetQQSession方法,用来调用安卓底层对应的方法,从而验证、刷新和获取QQ票据。然后添加几个用于QQ和微信登录和注销的const值,最后添加用于转换底层json消息的PlatformMsg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    //发送消息到平台底层
public const int PLATFORM_MSG_QQLOGIN = 1;//QQ登录
public const int PLATFORM_MSG_QQLOGOUT = 2;//QQ注销
public const int PLATFORM_MSG_WXLOGIN = 3;//WX注销
public const int PLATFORM_MSG_WXLOGOUT = 4;//WX注销


//从底层获取string
public const int UNITY_GET_STRING_QQAUTHORVALID = 1;//QQ票据是否有效
public const int UNITY_GET_STRING_QQREFRESHSESSION = 2;//QQ刷新票据

/// <summary>
/// QQ授权是否有效
/// </summary>
/// <returns>是否有效</returns>
public bool QQAuthorValid()
{
return System.Convert.ToBoolean(GetStringFromPlatform(UNITY_GET_STRING_QQAUTHORVALID));
}
/// <summary>
/// 刷新获取票据
/// </summary>
/// <returns>返回的用户QQ信息</returns>
public string GetQQSession()
{
string qqData = GetStringFromPlatform(UNITY_GET_STRING_QQREFRESHSESSION);
return qqData;
}

public class PlatformMsg
{
public string openid;
public string token;
public string unionid;
public string refreshtoken;
public string expires;
public string paytoken;
public string pf;
public string pfkey;
public string expirestime;
}

PhoneManager

在Assets——Scripts——Manager内新建PhoneManager,我们在这个类里维护登录状态,并且对接游戏内登录相关的UI。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using UnityEngine;
using Newtonsoft.Json;
public enum PlatformEnum
{
None,
QQ = 1,
WX = 2
}

public class PhoneManager : SingletonPattern<PhoneManager>
{
public bool IsLogin { get; set; } = false;
public PlatformEnum CurrentPlatform { get; set; } = PlatformEnum.None;
public System.Action<PlatformEnum> LoginSuccess;
public System.Action<PlatformEnum> LoginFailure;
public System.Action<PlatformEnum> LoginCancel;

/// <summary>
/// 登录回调
/// </summary>
/// <param name="data">数据</param>
/// <param name="plat">平台类型</param>
/// <param name="result">登录结果 0 == 成功,1 == 失败, 2 == 取消</param>
public void LoginCallback(string data, PlatformEnum plat, int result = 0)
{
switch (result)
{
case 0:
{
Debug.Log("票据获取:" + data);
var platMsg = JsonConvert.DeserializeObject<PlatformMsg>(data);
string openid = platMsg.openid;
string unionid = platMsg.unionid;
string token = platMsg.token;
IsLogin = true;
CurrentPlatform = plat;
if (LoginSuccess != null)
{
LoginSuccess.Invoke(plat);
}
PlayerPrefs.SetString("Login",plat.ToString());
PlayerPrefs.Save();
break;
}
case 1:
if (LoginFailure != null)
{
LoginFailure.Invoke(plat);
}
break;
case 2:
if (LoginCancel != null)
{
LoginCancel.Invoke(plat);
}
break;
}
}
/// <summary>
/// 登录
/// </summary>
/// <param name="platform">平台</param>
public void Login(PlatformEnum platform)
{
if(platform == PlatformEnum.QQ)
{
PlatMsgManager.Instance.SendUnityMessageToPlatform(PlatMsgManager.PLATFORM_MSG_QQLOGIN);
}
else if (platform == PlatformEnum.WX)
{
PlatMsgManager.Instance.SendUnityMessageToPlatform(PlatMsgManager.PLATFORM_MSG_WXLOGIN);
}
}
/// <summary>
/// 自动登录
/// </summary>
public void AutoLogin()
{
#if !UNITY_EDITOR
if (PlayerPrefs.HasKey("Login"))
{
PlatformEnum plat = (PlatformEnum)Enum.Parse(typeof(PlatformEnum),PlayerPrefs.GetString("Login"));
if (plat == PlatformEnum.QQ)
{
if (PlatMsgManager.Instance.QQAuthorValid())
{
string qqData = PlatMsgManager.Instance.GetQQSession();
LoginCallback(qqData, PlatformEnum.QQ);
}
}
else if (plat == PlatformEnum.WX)
{
if (PlatMsgManager.Instance.WXAuthorValid())
{
string wxData = PlatMsgManager.Instance.GetWXSession();
LoginCallback(wxData, PlatformEnum.WX);
}
}
}
else
{
if (PlatMsgManager.Instance.QQAuthorValid())
{
string qqData = PlatMsgManager.Instance.GetQQSession();
LoginCallback(qqData, PlatformEnum.QQ);
}
else if (PlatMsgManager.Instance.WXAuthorValid())
{
string wxData = PlatMsgManager.Instance.GetWXSession();
LoginCallback(wxData, PlatformEnum.WX);
}

}
#endif
}
public void Logout()
{
switch(CurrentPlatform)
{
case PlatformEnum.QQ:
PlatMsgManager.Instance.SendUnityMessageToPlatform(PlatMsgManager.PLATFORM_MSG_QQLOGOUT); break;
case PlatformEnum.WX:
PlatMsgManager.Instance.SendUnityMessageToPlatform(PlatMsgManager.PLATFORM_MSG_WXLOGOUT); break;
}
}
}

修改PlatformScript,在其中获得底层的消息后调用回调方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Update()
{
while (msgQueue.Count > 0)
{
PlatformMsg msg = msgQueue.Dequeue();
switch (msg.iMsgId)
{
case PLATFORM_MSG_QQLOGINCALLBACK:
PhoneManager.Instance.LoginCallback(msg.strParam1, PlatformEnum.QQ, msg.iParam1);//+++
break;
case PLATFORM_MSG_WXLOGINCALLBACK:
break;
default:
break;
}
}
}

登录界面

具体登录界面的设计略,主要是放了QQ、微信登录两个按钮和登出一个按钮。

我们看一下界面的逻辑,我们在Scripts——UGUI——Window中添加LoginWnd文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using UnityEngine;

public class LoginWnd : WindowBase
{
//private LoginPanel m_LoginPanel;
public override void OnAwake(object param1 = null, object param2 = null, object param3 = null)
{
//m_LoginPanel = GameObject.GetComponent<LoginPanel>();
#if UNITY_ANDROID || UNITY_IOS
PhoneManager.Instance.LoginSuccess += LoginSuccess;
PhoneManager.Instance.LoginFailure += LoginFailure;
PhoneManager.Instance.LoginCancel += LoginCancel;

if (!PhoneManager.Instance.IsLogin)//尝试自动登录
{
PhoneManager.Instance.AutoLogin();
}

//伪代码:登录按钮添加监听
//AddButtonClickListener(m_LoginPanel.m_QQLoginBtn,OnClickQQ);
//AddButtonClickListener(m_LoginPanel.m_WXLoginBtn,OnClickWX);
//AddButtonClickListener(m_LoginPanel.m_LogoutBtn,OnClickLogout);
#endif
}
public override void OnClose()
{
PhoneManager.Instance.LoginSuccess -= LoginSuccess;
PhoneManager.Instance.LoginFailure -= LoginFailure;
PhoneManager.Instance.LoginCancel -= LoginCancel;
}
void LoginSuccess(PlatformEnum platform)
{
if(platform == PlatformEnum.QQ)
{
Debug.Log("QQ登录成功");//游戏弹出窗口
//(伪代码)关闭各个平台的登录按钮
//(伪代码)显示登出按钮
}
else if(platform == PlatformEnum.WX)
{
Debug.Log("WX登录成功");//游戏弹出窗口
//(伪代码)关闭各个平台的登录按钮
//(伪代码)显示登出按钮
}
}
public void LoginFailure(PlatformEnum platform)
{
Debug.Log("登录失败");//游戏弹出窗口
}
void LoginCancel(PlatformEnum platform)
{
Debug.Log("取消登录");//游戏弹出窗口
}
void OnClickQQ()
{
PhoneManager.Instance.Login(PlatformEnum.QQ);
}
void OnClickWX()
{
PhoneManager.Instance.Login(PlatformEnum.WX);
}
void OnClickLogout()
{
PhoneManager.Instance.Logout();
//(伪代码)打开各个平台的登录按钮
//(伪代码)隐藏登出按钮
}
}

注意,我们这里在OnClickLogout使用伪代码进行登录按钮的还原,更推荐写在LoginCancel