Photon Pun

常波
2023-12-01
框架
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);
    }
}

 类似资料:

相关阅读

相关文章

相关问答