Last active
June 21, 2016 10:34
-
-
Save takashicompany/ca388c8be623dd7b8421bf89d53edac7 to your computer and use it in GitHub Desktop.
Unity Simple Photon Client and Sample.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @takashicompany | |
using System; | |
using System.Reflection; | |
using System.Collections.Generic; | |
using ExitGames.Client.Photon; | |
using ExitGames.Client.Photon.LoadBalancing; | |
/// <summary> | |
/// Photonの拡張クラス | |
/// </summary> | |
public static class PhotonExtension | |
{ | |
private static Dictionary<Type, List<FieldInfo>> _codes = new Dictionary<Type, List<FieldInfo>>(); | |
/// <summary> | |
/// byte型の値からParameterCode名を取得する | |
/// </summary> | |
/// <param name="code"></param> | |
/// <returns></returns> | |
public static string GetParameterCodeName(byte code) | |
{ | |
return GetCodeNames(typeof(ParameterCode), code); | |
} | |
/// <summary> | |
/// byte型の値からEventCode名を取得する | |
/// </summary> | |
/// <param name="code"></param> | |
/// <returns></returns> | |
public static string GetEventCodeName(byte code) | |
{ | |
return GetCodeNames(typeof(EventCode), code); | |
} | |
/// <summary> | |
/// byte型の値からOperationCode名を取得する | |
/// </summary> | |
/// <param name="code"></param> | |
/// <returns></returns> | |
public static string GetOperationCodeName(byte code) | |
{ | |
return GetCodeNames(typeof(OperationCode), code); | |
} | |
private static string GetCodeNames(Type type, byte code) | |
{ | |
if (!_codes.ContainsKey(type)) | |
{ | |
_codes.Add(type, GetFields(type)); | |
} | |
var list = _codes[type]; | |
if (list == null) return null; | |
string str = ""; | |
int count = 0; | |
for (int i = 0; i < list.Count; i++) | |
{ | |
var field = list[i]; | |
if ((byte)field.GetValue(field.Name) != code) continue; | |
str += count == 0 ? field.Name : " or " + field.Name; | |
count++; | |
} | |
return str; | |
} | |
private static List<FieldInfo> GetFields(Type type) | |
{ | |
var fields = type.GetFields(); | |
var list = new List<FieldInfo>(); | |
foreach (var field in fields) | |
{ | |
if (field.FieldType == typeof(byte)) | |
{ | |
list.Add(field); | |
} | |
} | |
return list; | |
} | |
/// <summary> | |
/// コード名を用いて文字列を生成 | |
/// </summary> | |
/// <param name="self"></param> | |
/// <returns></returns> | |
public static string ToStringUseCodeName(this EventData self) | |
{ | |
string str = string.Format("---EventData:{0} Parameters---", GetEventCodeName(self.Code)); | |
foreach (var p in self.Parameters) | |
{ | |
var pCode = GetParameterCodeName(p.Key); | |
str += string.Format("\n{0}:{1}", pCode, p.Value.ToString()); | |
} | |
str += "\n---end---"; | |
return str; | |
} | |
/// <summary> | |
/// コード名を用いて文字列を生成 | |
/// </summary> | |
/// <param name="self"></param> | |
/// <returns></returns> | |
public static string ToStringUseCodeName(this OperationResponse self) | |
{ | |
string str = string.Format("---OperationRequest:{0} Parameters---", GetOperationCodeName(self.OperationCode)); | |
foreach (var p in self.Parameters) | |
{ | |
var pCode = GetParameterCodeName(p.Key); | |
str += string.Format("\n{0}:{1}", pCode, p.Value.ToString()); | |
} | |
str += "\n---end---"; | |
return str; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @takashicompany | |
using UnityEngine; | |
using ExitGames.Client.Photon; | |
using ExitGames.Client.Photon.LoadBalancing; | |
public class PhotonSimpleSample : MonoBehaviour | |
{ | |
private SimpleClient _client; | |
void Awake() | |
{ | |
byte maxPlayer = 2; | |
// インスタンスを生成 | |
_client = new SimpleClient("App ID", maxPlayer); | |
// マスターサーバーに接続 | |
_client.ConnectToRegionMaster("jp"); | |
// リスナーを登録 | |
_client.onJoin += OnJoin; | |
_client.onLeave += OnLeave; | |
_client.onJoinOther += OnJoinOther; | |
_client.onLeaveOther += OnLeaveOther; | |
} | |
void Update() | |
{ | |
// 毎フレーム実行してください | |
_client.Service(); | |
} | |
void Match() | |
{ | |
// マッチング条件を設定 | |
var roomProperties = new ExitGames.Client.Photon.Hashtable(); | |
roomProperties["stage_id"] = 1; | |
_client.Match(roomProperties); | |
} | |
private void OnJoin(Room room) | |
{ | |
// 自分が部屋に入った時の処理 | |
} | |
private void OnLeave() | |
{ | |
// 部屋から出た時の処理 | |
} | |
private void OnJoinOther(int playerId) | |
{ | |
// 誰かが部屋に入ってきた時の処理 | |
} | |
private void OnLeaveOther(int playerId) | |
{ | |
// 誰かが部屋から出ていた時の処理 | |
} | |
private void OnEvent(EventData e) | |
{ | |
// 送られてきたイベントを処理 | |
// code e.g. 10=attack 20=defense 30=move | |
switch (e.Code) | |
{ | |
case 10: | |
// attack... | |
break; | |
case 20: | |
// defense... | |
break; | |
case 30: | |
// move... | |
break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @takashicompany | |
using System; | |
using System.Collections.Generic; | |
using ExitGames.Client.Photon; | |
using ExitGames.Client.Photon.LoadBalancing; | |
using PHashtable = ExitGames.Client.Photon.Hashtable; | |
/// <summary> | |
/// 簡易型のPhotonクライアント | |
/// 指定した条件のルームに入室/作成する | |
/// </summary> | |
public class SimpleClient : LoadBalancingClient | |
{ | |
/// <summary> | |
/// ルームからイベントを受信した時に実行される | |
/// </summary> | |
public event Action<EventData> onEvent; | |
/// <summary> | |
/// Operationのレスポンスを受信した際に呼ばれる | |
/// </summary> | |
public event Action<OperationResponse> onOperaionResponse; | |
/// <summary> | |
/// 部屋に入れた時に呼ばれる | |
/// </summary> | |
public event Action<Room> onJoin; | |
/// <summary> | |
/// 部屋から去った際に呼ばれる | |
/// </summary> | |
public event Action onLeave; | |
/// <summary> | |
/// 部屋に他のプレイヤーが入ってきた際に呼ばれる | |
/// </summary> | |
public event Action<int> onJoinOther; | |
/// <summary> | |
/// 部屋から他のプレイヤーが去った際に呼ばれる | |
/// </summary> | |
public event Action<int> onLeaveOther; | |
/// <summary> | |
/// マッチングに失敗した場合に呼ばれる | |
/// </summary> | |
public event Action onMatchFailure; | |
/// <summary> | |
/// クライアントの状態が変わった際に呼ばれる | |
/// </summary> | |
public event Action<ClientState> onStateChange; | |
/// <summary> | |
/// クライアントの部屋内での番号 | |
/// </summary> | |
/// <returns></returns> | |
public int actorNr { get; private set; } | |
/// <summary> | |
/// マッチング条件/ルーム設定 | |
/// </summary> | |
private PHashtable _roomProperties; | |
/// <summary> | |
/// 部屋の最大人数 | |
/// </summary> | |
private byte _maxPlayer = 2; | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
/// <param name="appId"></param> | |
/// <param name="gameStartPlayer"></param> | |
/// <param name="base("></param> | |
public SimpleClient( | |
string appId, | |
byte maxPlayer | |
) : base() | |
{ | |
this.AppId = appId; | |
_maxPlayer = maxPlayer; | |
this.OnStateChangeAction = OnStateChange; | |
} | |
/// <summary> | |
/// クライアントの状態が変わった際に呼ばれる | |
/// </summary> | |
/// <param name="state"></param> | |
protected virtual void OnStateChange(ClientState state) | |
{ | |
if (onStateChange != null) | |
{ | |
onStateChange(state); | |
} | |
} | |
/// <summary> | |
/// 条件を指定してマッチングする。 | |
/// 条件にあった部屋があればそこに入り、無ければ新しく部屋を作る。 | |
/// ロビーにいる時のみ実行可能 | |
/// 既にルームにいる場合は何もしない(誰かが入ってくるのを待つ) | |
/// </summary> | |
/// <param name="roomProperties"></param> | |
public void Match(PHashtable roomProperties) | |
{ | |
if (State == ClientState.Joined) | |
{ | |
return; | |
} | |
if (State != ClientState.JoinedLobby) | |
{ | |
OnMatchFailure(); | |
return; | |
} | |
_roomProperties = roomProperties; | |
JoinRandomRoom(); | |
} | |
/// <summary> | |
/// 適当な部屋を見つけて入ってみる | |
/// </summary> | |
protected void JoinRandomRoom() | |
{ | |
this.OpJoinRandomRoom(_roomProperties, 0); | |
} | |
/// <summary> | |
/// 適当な部屋が見つからなかった | |
/// </summary> | |
private void OnJoinRandomRoomFailure() | |
{ | |
CreateRoom(); | |
} | |
/// <summary> | |
/// 部屋を作る | |
/// </summary> | |
private void CreateRoom() | |
{ | |
var options = new RoomOptions() | |
{ | |
MaxPlayers = _maxPlayer, | |
CustomRoomProperties = _roomProperties | |
}; | |
var list = new List<string>(); | |
if (_roomProperties != null) | |
{ | |
foreach (var p in _roomProperties) | |
{ | |
list.Add(p.Key.ToString()); | |
} | |
} | |
// CustomRoomPropertiesForLobby で指定したキーがランダムマッチングに使われる | |
options.CustomRoomPropertiesForLobby = list.ToArray(); | |
this.OpCreateRoom(null, options, TypedLobby.Default); | |
} | |
/// <summary> | |
/// 何らかの理由でマッチングが失敗した時に呼ばれる | |
/// </summary> | |
private void OnMatchFailure() | |
{ | |
if (onMatchFailure != null) | |
{ | |
onMatchFailure(); | |
} | |
} | |
/// <summary> | |
/// 部屋に入った際に呼ばれる | |
/// </summary> | |
/// <param name="actorNr"></param> | |
private void OnJoin(int actorNr) | |
{ | |
this.actorNr = actorNr; | |
if (onJoin != null) | |
{ | |
onJoin(CurrentRoom); | |
} | |
} | |
/// <summary> | |
/// 部屋から出た際に呼ばれる | |
/// </summary> | |
/// <param name="actorNr"></param> | |
private void OnLeave() | |
{ | |
this.actorNr = -1; | |
if (onLeave != null) | |
{ | |
onLeave(); | |
} | |
} | |
/// <summary> | |
/// 他のプレイヤーが部屋に入ってきた際に呼ばれる | |
/// </summary> | |
/// <param name="actorNr"></param> | |
private void OnJoinOther(int actorNr) | |
{ | |
if (onJoinOther != null) | |
{ | |
onJoinOther(actorNr); | |
} | |
} | |
/// <summary> | |
/// プレイヤーが部屋から去った時に呼ばれる | |
/// </summary> | |
/// <param name="actorNr"></param> | |
private void OnLeaveOther(int actorNr) | |
{ | |
if (onLeaveOther != null) | |
{ | |
onLeaveOther(actorNr); | |
} | |
} | |
public override void OnOperationResponse(OperationResponse operationResponse) | |
{ | |
base.OnOperationResponse(operationResponse); | |
if (onOperaionResponse != null) | |
{ | |
onOperaionResponse(operationResponse); | |
} | |
// オペレーションの種別毎に処理を分ける | |
switch (operationResponse.OperationCode) | |
{ | |
// 部屋を作成した場合 | |
case (byte)OperationCode.CreateGame: | |
// 成功しなかった場合 | |
if (operationResponse.ReturnCode != 0) | |
{ | |
OnMatchFailure(); | |
} | |
else | |
{ | |
if (this.State == ClientState.Joined) | |
{ | |
var actorNr = (int)operationResponse.Parameters[ParameterCode.ActorNr]; | |
OnJoin(actorNr); | |
} | |
} | |
break; | |
case (byte)OperationCode.JoinRandomGame: | |
if (operationResponse.ReturnCode == ErrorCode.Ok) | |
{ | |
} | |
else if (operationResponse.ReturnCode == ErrorCode.NoRandomMatchFound) | |
{ | |
OnJoinRandomRoomFailure(); | |
} | |
else | |
{ | |
OnMatchFailure(); | |
} | |
break; | |
case (byte)OperationCode.JoinGame: | |
if (operationResponse.ReturnCode == ErrorCode.Ok) | |
{ | |
if (State == ClientState.Joined) | |
{ | |
var actorNr = (int)operationResponse.Parameters[ParameterCode.ActorNr]; | |
OnJoin(actorNr); | |
} | |
} | |
break; | |
case (byte)OperationCode.Leave: | |
if (operationResponse.ReturnCode == ErrorCode.Ok && State == ClientState.JoinedLobby) | |
{ | |
OnLeave(); | |
} | |
break; | |
} | |
} | |
public override void OnEvent(EventData e) | |
{ | |
base.OnEvent(e); | |
switch (e.Code) | |
{ | |
case EventCode.Join: | |
if (e.Parameters.ContainsKey(ParameterCode.ActorNr)) | |
{ | |
var actorNr = (int)e.Parameters[ParameterCode.ActorNr]; | |
if (actorNr != this.actorNr) | |
{ | |
OnJoinOther(actorNr); | |
} | |
} | |
break; | |
case EventCode.Leave: | |
if (e.Parameters.ContainsKey(ParameterCode.ActorNr)) | |
{ | |
var actorNr = (int)e.Parameters[ParameterCode.ActorNr]; | |
if (actorNr != this.actorNr) | |
{ | |
OnLeaveOther(actorNr); | |
} | |
} | |
break; | |
default: | |
if (onEvent != null) | |
{ | |
onEvent(e); | |
} | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment