一、打开之前的测试项目。先将服务端代码编译一下,在 bin/Debug/目录下会发现有一个Common.dill。我们相应导入到前端使用。直接拖拽到相应地方

UI相应布局属于前端操作,这里就不做介绍了。详细查看视频:https://www.bilibili.com/video/av35109390/?p=70
二、代码处理:跟后端一样,前端发起请求的地方也会随着项目变大而变多,所以也得单独区分出每个请求独自管理。
Request.cs 请求基类 LoginRequest.cs 登录请求逻辑 RegiesterRequest.cs 注册请求连接 LoginPanel.cs 登录面挂载脚本 ReginsterPanel.cs 注册脚本挂载脚

三、调整PhotonManager.cs 管理类
(1)、添加字典,管理所以请求
private Dictionary<OperationCode,Request> ResquesDict = new Dictionary<OperationCode, Request>();
(2)、分配peer
public static PhotonPeer Peer
{
get { return peer; }
}
(3)、添加两个函数,管理请求
public void AddRequest(Request rest)
{
ResquesDict.Add(rest.OpCode,rest);
}
public void RemoveRequest(Request rest)
{
ResquesDict.Remove(rest.OpCode);
}
(4)、修改OnOperationResponse() 函数,实现接收服务端返回数据的分发
/// <summary>
/// 客户端请求后,服务端响应,返回数据
/// </summary>
/// <param name="operationResponse"></param>
public void OnOperationResponse(OperationResponse operationResponse)
{
//服务端返回的code
OperationCode opCode = (OperationCode)operationResponse.OperationCode;
Request request = null;
//根据code查找相应请求
bool tmp = ResquesDict.TryGetValue(opCode, out request);
if (tmp)
{
//如果存在,分发给相应OnOperationResponse去处理自己的接收数据逻辑
request.OnOperationResponse(operationResponse);
}
else
{
Debug.Log("没找到响应处理对象");
}
}
(5)、完整代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection.Emit;
using Common;
using UnityEngine;
using ExitGames.Client.Photon;
public class PhotonManager : MonoBehaviour,IPhotonPeerListener
{
//单例模式,保证只有一个链接服务器
public static PhotonManager Instance;
private static PhotonPeer peer;
private bool connected;
private Dictionary<OperationCode,Request> ResquesDict = new Dictionary<OperationCode, Request>();
public static PhotonPeer Peer
{
get { return peer; }
}
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this.gameObject);
}else if (Instance != this)
{
Destroy(this.gameObject);
return;
}
}
// Start is called before the first frame update
void Start()
{
Debug.Log("111------开始连接----");
peer = new PhotonPeer(this, ConnectionProtocol.Udp);
peer.Connect("127.0.0.1:5055","MyGame1");
connected = false;
}
// Update is called once per frame
void Update()
{
Debug.Log("update------" + connected);
peer.Service();
}
private void OnDestroy()
{
if (peer != null && peer.PeerState == PeerStateValue.Connected)
{
peer.Disconnect();
}
}
public void DebugReturn(DebugLevel level, string message)
{
}
/// <summary>
/// 客户端请求后,服务端响应,返回数据
/// </summary>
/// <param name="operationResponse"></param>
public void OnOperationResponse(OperationResponse operationResponse)
{
//服务端返回的code
OperationCode opCode = (OperationCode)operationResponse.OperationCode;
Request request = null;
//根据code查找相应请求
bool tmp = ResquesDict.TryGetValue(opCode, out request);
if (tmp)
{
//如果存在,分发给相应OnOperationResponse去处理自己的接收数据逻辑
request.OnOperationResponse(operationResponse);
}
else
{
Debug.Log("没找到响应处理对象");
}
}
/// <summary>
/// 连接状态发生改变时
/// </summary>
/// <param name="statusCode"></param>
public void OnStatusChanged(StatusCode statusCode)
{
Debug.Log("serStatus-----" + statusCode.ToString());
switch (statusCode)
{
case StatusCode.Connect:
connected = true;
break;
default:
connected = false;
break;
}
}
/// <summary>
/// 服务端直接给客户端数据时,不需要向服务器请求
/// </summary>
/// <param name="eventData"></param>
public void OnEvent(EventData eventData)
{
switch (eventData.Code)
{
case 1:
break;
case 2:
break;
default:
break;
}
}
public void AddRequest(Request rest)
{
ResquesDict.Add(rest.OpCode,rest);
}
public void RemoveRequest(Request rest)
{
ResquesDict.Remove(rest.OpCode);
}
}
四、请求类
(1)、Request.cs 基类

using System;
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
public abstract class Request: MonoBehaviour
{
//定义请求code
public OperationCode OpCode;
public abstract void DefaultRequest(); //发送请求
public abstract void OnOperationResponse(OperationResponse operationResponse); //接收返回的数据
public virtual void Start()
{
//从管理类中添加该请求
PhotonManager.Instance.AddRequest(this);
}
public void OnDestroy()
{
//从管理类中移除该请求
PhotonManager.Instance.RemoveRequest(this);
}
}
(2)、登陆类 LoginRequest.cs

using System.Collections.Generic;
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
public class LoginRequest : Request
{
//通过代码赋值,所有在UI界面上隐藏掉
[HideInInspector]
public string UserName;
[HideInInspector]
public string Password;
//获取UI面板
private LoginPanel loginPanel;
public override void Start()
{
//调用基类Start,将登陆请求添加到管理类中
base.Start();
loginPanel = GetComponent<LoginPanel>();
}
public override void DefaultRequest()
{
//登录请求发起
Dictionary<byte,object> data = new Dictionary<byte, object>();
data.Add((byte) ParameterCode.UserName,UserName);
data.Add((byte) ParameterCode.Password,Password);
//通过Peer发送请求给服务端
PhotonManager.Peer.OpCustom((byte)OpCode,data,true);
}
public override void OnOperationResponse(OperationResponse operationResponse)
{
//接收服务端的返回响应,将返回code给面板,由面板来处理接下来的逻辑(是提示错误还是跳转场景)
ReturnCode returnCode = (ReturnCode) operationResponse.ReturnCode;
loginPanel.OnLiginResponse(returnCode);
}
}
(3)、登陆面板脚本 LoginPannel.cs

using System;
using System.Collections;
using System.Collections.Generic;
using Common;
using UnityEngine;
using UnityEngine.UI;
public class LoginPanel : MonoBehaviour
{
//以下public参数通过UI拖拽进行赋值
#region Tags
//注册面板,用于点击注册时显示该面板
public GameObject registerPanel;
//控件
public InputField username;
public InputField password;
public Text hintmessage;
//登陆请求类
private LoginRequest loginRequest;
#endregion
private void Start()
{
//从面板中获取请求类(面板脚本和请求类都挂载到请求面板UI中)
loginRequest = GetComponent<LoginRequest>();
}
public void OnLoginButton()
{
//点击登陆按钮时,发送请求
hintmessage.text = "";
loginRequest.UserName = username.text;
loginRequest.Password = password.text;
//调用请求类中的发起请求
loginRequest.DefaultRequest();
}
public void OnRegisterButton()
{
//点击注册时,隐藏登陆UI,显示注册UI
gameObject.SetActive(false);
registerPanel.SetActive(true);
}
public void OnLiginResponse(ReturnCode returnCode)
{
//服务端响应返回数据时,请求类会将返回信息传递到该函数
Debug.Log("-----返回code" + returnCode);
if (returnCode == ReturnCode.Success)
{
//登录成功,调整下一个场景
Debug.Log("--登陆成功----");
}
else
{
hintmessage.text = "用户名或密码错误";
}
}
}
注册类和注册面板跟登陆相同逻辑
(4)、注册类 ReginesterRequest.cs

using System.Collections;
using System.Collections.Generic;
using Common;
using ExitGames.Client.Photon;
using UnityEngine;
public class RegiesterRequet : Request
{
[HideInInspector]
public string username;
[HideInInspector]
public string password;
private ReginsterPanel reginsterPanel;
public override void Start()
{
base.Start();
reginsterPanel = GetComponent<ReginsterPanel>();
}
public override void DefaultRequest()
{
//登录请求发起
Dictionary<byte,object> data = new Dictionary<byte, object>();
data.Add((byte) ParameterCode.UserName,username);
data.Add((byte) ParameterCode.Password,password);
PhotonManager.Peer.OpCustom((byte)OpCode,data,true);
}
public override void OnOperationResponse(OperationResponse operationResponse)
{
ReturnCode returnCode = (ReturnCode) operationResponse.ReturnCode;
reginsterPanel.OnReigsterResponse(returnCode);
}
}
(5)、注册面板 ReginsterPanel.cs

using System;
using System.Collections;
using System.Collections.Generic;
using Common;
using UnityEngine;
using UnityEngine.UI;
public class ReginsterPanel : MonoBehaviour
{
public GameObject loginPanel;
public InputField username;
public InputField password;
public Text hintmessage;
private RegiesterRequet regiesterRequet;
private void Start()
{
regiesterRequet = GetComponent<RegiesterRequet>();
}
public void OnRegisterButton()
{
hintmessage.text = "";
regiesterRequet.username = username.text;
regiesterRequet.password = password.text;
regiesterRequet.DefaultRequest();
}
public void OnBackBtn()
{
loginPanel.SetActive(true);
gameObject.SetActive(false);
}
public void OnReigsterResponse(ReturnCode returnCode)
{
if (returnCode == ReturnCode.Success)
{
hintmessage.text = "注册成功,请返回登录";
}
else
{
hintmessage.text = "用户名重复,请重新修改用户名";
}
}
}

前端UI和请求、响应逻辑基本完成。接下来进行服务端响应。
查看视频:https://www.bilibili.com/video/av35109390/?p=70
