框架
using System;
using System.Collections.Generic;
using ExitGames.Client.Photon;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Random = UnityEngine.Random;
public class PunDemo : MonoBehaviourPunCallbacks
{
public GUISkin skin;
#region GUI Values
//状态滚动视图值
private Vector2 stateScrollViewValue;
//滚动视图值
private Vector2 scrollViewValue;
//状态更新日志
private string clientStateLog;
//房间名称
private string roomNameValue;
//房间最大人数
private string roomMaxPlayerValue;
//玩家名称
private string playerNameValue;
//想要加入的房间名称
private string roomName;
//是否有密码
private bool hasPassword = false;
//房间密码
private string roomPassword = "";
//待输入的房间密码
private string inputRoomPassword;
//密码错误
private bool errorPwd;
//玩家颜色
private string playerColorValue = "1,1,1";
//游戏是否开始
private bool gameStart;
#endregion
//上一次的客户端状态
private ClientState previousState = ClientState.Disconnected;
private void Start()
{
roomNameValue = "Room" + Random.Range(10, 100);
playerNameValue = "Player" + Random.Range(100, 1000);
roomMaxPlayerValue = "8";
}
private void Update()
{
//上次的状态跟当前状态进行对象,如果发生变化,记录变化
if (previousState != PhotonNetwork.NetworkClientState)
{
clientStateLog += PhotonNetwork.NetworkClientState + "\n";
}
//将当前状态设置为Previous,以便下一次比对
previousState = PhotonNetwork.NetworkClientState;
}
private void OnGUI()
{
GUI.skin = skin;
//设置标题风格
var styleState = new GUIStyleState();
styleState.textColor = Color.blue;
var style = new GUIStyle();
style.fontSize = 120;
style.normal = styleState;
//标题
GUILayout.Label("Client State Log", style);
//显示状态日志
stateScrollViewValue = GUILayout.BeginScrollView(stateScrollViewValue, GUILayout.Height(300));
GUILayout.Label(clientStateLog);
GUILayout.EndScrollView();
//状态
scrollViewValue = GUILayout.BeginScrollView(scrollViewValue);
switch (PhotonNetwork.NetworkClientState)
{
//初始状态
case ClientState.PeerCreated:
PeerCreateState();
break;
//连接到主服务器状态
case ClientState.ConnectedToMasterServer:
ConnectedToMasterServerState();
break;
//加入房间
case ClientState.Joined:
JoinedState();
break;
//加入大厅
case ClientState.JoinedLobby:
JoinedLobbyState();
break;
}
GUILayout.EndScrollView();
}
private void PeerCreateState()
{
if (GUILayout.Button("连接主服务器"))
{
//使用配置连接主服务器
PhotonNetwork.ConnectUsingSettings();
}
}
private void ConnectedToMasterServerState()
{
GUILayout.Label("房间名称:");
roomNameValue = GUILayout.TextField(roomNameValue);
GUILayout.Label("房间最大人数:");
roomMaxPlayerValue = GUILayout.TextField(roomMaxPlayerValue);
GUILayout.Label("玩家名称:");
playerNameValue = GUILayout.TextField(playerNameValue);
GUILayout.Label("想要加入的房间:");
roomName = GUILayout.TextField(roomName);
hasPassword = GUILayout.Toggle(hasPassword, "是否创建密码房间");
if (hasPassword)
{
roomPassword = GUILayout.PasswordField(roomPassword, '*');
}
if (GUILayout.Button("创建房间"))
{
//设置昵称
PhotonNetwork.LocalPlayer.NickName = playerNameValue;
//创建房间选项对象
RoomOptions options = new RoomOptions();
//设置房间最大人数
options.MaxPlayers = byte.Parse(roomMaxPlayerValue);
if (hasPassword)
{
options.CustomRoomProperties = new Hashtable
{
{"RoomPassword", roomPassword}
};
//将属性设置为大厅属性
options.CustomRoomPropertiesForLobby = new[] {"RoomPassword"};
}
//创建房间
PhotonNetwork.CreateRoom(roomNameValue, options);
}
if (GUILayout.Button("随机加入房间"))
{
//随机加入房间
PhotonNetwork.JoinRandomRoom();
}
if (GUILayout.Button("加入房间"))
{
//随机加入房间
PhotonNetwork.JoinRoom(roomName);
}
if (GUILayout.Button("随机加入游戏大厅"))
{
//加入大厅
PhotonNetwork.JoinLobby();
}
}
private void JoinedState()
{
int len = PhotonNetwork.PlayerList.Length;
GUILayout.Label("-----------------");
for (int i = 0; i < len; i++)
{
//获取当前玩家
Player player = PhotonNetwork.PlayerList[i];
GUIStyle localStyle = new GUIStyle();
localStyle.fontSize = 100;
if (player.IsLocal)
{
localStyle.normal.textColor = Color.red;
}
else
{
localStyle.normal.textColor = Color.green;
}
if (player.IsMasterClient)
{
GUILayout.Label("【房主】", localStyle);
}
//声明返回值
object getPlayerColor;
bool get = player.CustomProperties.TryGetValue("PlayerColor", out getPlayerColor);
Color color = Color.white;
if (get)
{
try
{
string colorStr = getPlayerColor.ToString();
string[] rgb = colorStr.Split(',');
color=new Color(float.Parse(rgb[0]),float.Parse(rgb[1]),float.Parse(rgb[2]));
}
catch (Exception e)
{
}
}
var colorStyle=new GUIStyle();
colorStyle.normal.textColor = color;
colorStyle.fontSize = 100;
GUILayout.Box("███████",colorStyle);
GUILayout.Label("序号:"+player.ActorNumber,localStyle);
GUILayout.Label("昵称:" + player.NickName,localStyle);
if (player.IsLocal)
{
GUILayout.Label("请设置玩家颜色",localStyle);
playerColorValue = GUILayout.TextField(playerColorValue);
if (GUILayout.Button("更改颜色"))
{
Hashtable hashtable=new Hashtable();
hashtable.Add("PlayerColor",playerColorValue);
//将玩家的颜色作为属性设置到玩家对象中
player.SetCustomProperties(hashtable);
}
}
if (i!=len-1)
{
GUILayout.Label("-----------------");
}
}
GUILayout.Label("-----------------");
//房主开始游戏
if (PhotonNetwork.LocalPlayer.IsMasterClient)
{
if (GUILayout.Button("开始游戏"))
{
Hashtable hashtable=new Hashtable();
hashtable.Add("GameStart",true);
//设置游戏开始的房间属性广播
PhotonNetwork.CurrentRoom.SetCustomProperties(hashtable);
}
}
if (GUILayout.Button("离开房间"))
{
//离开房间
PhotonNetwork.LeaveRoom();
}
}
private void JoinedLobbyState()
{
GUILayout.Label("-----------------");
for (int i = 0; i < roomInfos.Count; i++)
{
GUILayout.Label(roomInfos[i].Name + "\t" +
roomInfos[i].PlayerCount +
"/" + roomInfos[i].MaxPlayers);
//声明数值结果
object pwdValue;
//尝试获取结果
bool getValue = roomInfos[i].CustomProperties.TryGetValue("RoomPassword", out pwdValue);
if (getValue)
{
GUILayout.Label("请输入密码:");
inputRoomPassword = GUILayout.TextField(inputRoomPassword);
}
if (GUILayout.Button("加入房间"))
{
//如果没有密码
if (!getValue || inputRoomPassword == (string) pwdValue)
{
errorPwd = false;
//加入这个房间
PhotonNetwork.JoinRoom(roomInfos[i].Name);
}
else
{
errorPwd = true;
}
}
if (errorPwd)
{
GUIStyle style = new GUIStyle();
style.normal.textColor = Color.red;
style.fontSize = 100;
GUILayout.Label("密码输入错误,无法加入房间!", style);
}
if (i != roomInfos.Count - 1)
{
GUILayout.Label("-----------------");
}
}
GUILayout.Label("-----------------");
if (GUILayout.Button("离开大厅"))
{
//离开大厅
PhotonNetwork.LeaveLobby();
}
}
#region Pun Callbacks
private List<RoomInfo> roomInfos = new List<RoomInfo>();
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
for (int i = 0; i < roomList.Count; i++)
{
if (roomList[i].RemovedFromList)
{
roomInfos.Remove(roomList[i]);
}
else
{
roomInfos.Add(roomList[i]);
}
}
}
public override void OnLeftLobby()
{
roomInfos.Clear();
}
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
if (propertiesThatChanged.ContainsKey("GameStart"))
{
gameStart = true;
//生成玩家
PhotonNetwork.Instantiate("Prefabs/Player", new Vector3(Random.Range(-10f, 10),
1, Random.Range(-10f, 10)), Quaternion.identity);
}
}
#endregion
}
using Photon.Pun;
using UnityEngine;
public class PunCallbackbyClass : MonoBehaviourPunCallbacks
{
public override void OnConnectedToMaster()
{
Debug.Log("主服务器连接成功!");
}
public override void OnCreatedRoom()
{
Debug.Log("创建房间成功!");
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
Debug.Log($"房间创建失败【错误编码:{returnCode},错误描述:{message}】");
}
public override void OnJoinedRoom()
{
Debug.Log("加入房间成功!");
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
Debug.Log($"随机加入房间失败【错误编码:{returnCode},错误描述:{message}】");
}
public override void OnJoinedLobby()
{
Debug.Log("加入大厅成功!");
}
}
控制demo
using System;
using System.Collections;
using System.Collections.Generic;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
public class PlayerController : MonoBehaviourPunCallbacks
{
float h;
float v;
public float speed = 6;
public float turnSpeed = 15;
Transform camTransform;
Vector3 movement;
Vector3 camForward;
private Color currentPlayerColor;
private Animator _animator;
private void Start()
{
//获取当前对象的创建者
Player currentPlayer = photonView.Owner;
object playerColor;
//获取玩家属性,关于颜色
bool getColor = currentPlayer.CustomProperties.TryGetValue("PlayerColor", out playerColor);
if (getColor)
{
try
{
string[] color = playerColor.ToString().Split(',');
currentPlayerColor = new Color(
float.Parse(color[0]),
float.Parse(color[1]),
float.Parse(color[2]));
//变色
//GetComponent<MeshRenderer>().material.color = currentPlayerColor;
//transform.GetChild(0).GetComponent<MeshRenderer>().material.color = currentPlayerColor;
}
catch (Exception e)
{
}
}
if (!photonView.IsMine)
return;
//设置相机观察目标为当前玩家
CameraController.instance.target = transform;
camTransform = CameraController.instance.transform;
_animator = GetComponent<Animator>();
}
void Update()
{
Move();
}
void Move()
{
if(!photonView.IsMine)
return;
h = Input.GetAxis("Horizontal");
v = Input.GetAxis("Vertical");
//GetComponent<Rigidbody>().MovePosition(transform.position + camTransform.right * h + camForward * v);
transform.Translate(camTransform.right * h * speed * Time.deltaTime + camForward * v * speed * Time.deltaTime, Space.World);
if (h != 0 || v != 0)
{
Rotating(h, v);
}
float move=new Vector3(h,0,v).magnitude;
_animator.SetFloat("move",move);
if (Input.GetMouseButtonDown(0))
{
_animator.SetTrigger("attack");
}
}
private void OnCollisionStay(Collision other)
{
if (!photonView.IsMine)
{
return;
}
if (other.transform.CompareTag("Player"))
{
if (_animator.GetCurrentAnimatorStateInfo(0).IsName("Attack01"))
{
other.transform.GetComponent<Animator>().SetTrigger("gethit");
}
}
}
void Rotating(float hh, float vv)
{
if(!photonView.IsMine)
return;
camForward = Vector3.Cross(camTransform.right, Vector3.up);
Vector3 targetDir = camTransform.right * hh + camForward * vv;
Quaternion targetRotation = Quaternion.LookRotation(targetDir, Vector3.up);
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
}
}
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform target;
public float xSpeed = 200;
public float ySpeed = 200;
public float mSpeed = 10;
public float yMinLimit = -50;
public float yMaxLimit = 50;
public float distance = 10;
public float minDistance = 2;
public float maxDistance = 30;
public bool needDamping = true;
float damping = 5.0f;
public float x = 0.0f;
public float y = 0.0f;
public static CameraController instance;
private void Awake()
{
instance = this;
}
void Start()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
y = angles.x;
}
void LateUpdate()
{
if (target)
{
if (Input.GetMouseButton(1))
{
x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
y = ClampAngle(y, yMinLimit, yMaxLimit);
}
distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
Quaternion rotation = Quaternion.Euler(y, x, 0.0f);
Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * disVector + target.position;
//adjust the camera
if (needDamping)
{
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
}
else
{
transform.rotation = rotation;
transform.position = position;
}
}
}
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
}