美文网首页Unity进阶技术
PhotonServer插件教程

PhotonServer插件教程

作者: 街头顽禽 | 来源:发表于2019-12-23 22:30 被阅读0次

    官方案例 Demo Boxes

    红色玩家.png 蓝色玩家.png
    知识点:
    1.服务器的连接
    2.服务器的连接的成功和失败的处理
    3.玩家盒子的同步,每个客户端有属于自己颜色的盒子
    4.服务器和客户端的一些常用的回调
    5.单击改变盒子颜色,双击销毁自己创建的盒子,双击销毁其他客户端创建的盒子无效
    6.GUI的工具栏,按钮,提示文本的绘制
    7.文本提示闪烁切换效果的实现
    8.俩种Sharder的模式
    
    DemoBoxes.png Sharder.png
    //----------------ClickInstantiate.cs--------------------//
    
    using UnityEngine;
    
    /// <summary>
    /// 点击平面实例化要同步的方块
    /// </summary>
    public class ClickInstantiate : MonoBehaviour
    {
        /// <summary>
        /// 要实例化的预制体
        /// </summary>
        public GameObject prefab;
    
        /// <summary>
        /// 标记平面的类型
        /// </summary>
        public int InstantiateType;
    
        /// <summary>
        /// 实例化方块的类型
        /// </summary>
        private string[] instantiateTypeNames = new string[] { "我的", "房主专属" };
    
        /// <summary>
        /// 是否显示GUI提示
        /// </summary>
        public bool IsShowGUI;
    
        private void OnGUI()
        {
            if (IsShowGUI)
            {
                //使用GUI显示一个工具栏
                GUILayout.BeginArea(new Rect(Screen.width - 180f, 0, 180f,50f));
                InstantiateType = GUILayout.Toolbar(InstantiateType, instantiateTypeNames);
                GUILayout.EndArea();
            }
        }
    
        /// <summary>
        /// 点击平面的方法
        /// 该方法是由 PhotomServer 的 UtilityScripts 的 InputToEvent和PointedAtGameObjectInfo通过SendMessage调用
        /// </summary>
        private void OnClick()
        {
            //玩家不在房间内,直接返回,不执行下面的代码
            if (!PhotonNetwork.inRoom)
            {     
                return;
            }
    
            switch (InstantiateType)
            {
                case 0:
                    //实例化预制体,所有客户端均可调用
                    PhotonNetwork.Instantiate(prefab.name, InputToEvent.inputHitPos + new Vector3(0, 5f, 0), Quaternion.identity, 0);
                    break;
                case 1:
                    //只有当前房主才能调用的方法,且只有房主才能销毁
                    PhotonNetwork.InstantiateSceneObject(prefab.name, InputToEvent.inputHitPos + new Vector3(0f, 5f, 0), Quaternion.identity, 0, null);
                    break;
                default:
                    break;
            }
        }
    }
    
    //-----------------知识点------------------//
    // GUIBeginArea(new Rect(Screen.width-180f,0,180f,50f));  开始绘制区域
    // int instantiateType = GUILayout.Toolbar(int selected,string[] names);  绘制一个工具栏
    // GUIEndArea();  结束绘制 
    
    // bool res = PhotonNetwork.inRoom 玩家是否在房间内  
    
    //------------------ColorPerPlayer.cs--------------------//
    
    using ExitGames.UtilityScripts;
    using UnityEngine;
    using Photon;
    
    /// <summary>
    /// PunBehaviour是一个定义了各种事件的回调,你都可以重写他们 给玩家的提示文本选择一种颜色
    /// </summary>
    public class ColorPerPlayer : PunBehaviour
    {
        /// <summary>
        /// 颜色的数组
        /// </summary>
        public Color[] colors = new Color[] { Color.red,Color.blue,Color.yellow,Color.green};
    
        /// <summary>
        /// 是否显示颜色的文本
        /// </summary>
        public bool ShowColorLabel;
    
        /// <summary>
        /// 颜色文本的区域
        /// </summary>
        public Rect ColorLabelArea = new Rect(0, 50, 100, 50);
    
    
        public Texture2D img;
        /// <summary>
        /// 默认的颜色
        /// </summary>
        public Color MyColor = Color.gray;
    
        /// <summary>
        /// 标识颜色
        /// </summary>
        public bool ColorPicked { get; set; }
    
        /// <summary>
        /// 是否已经初始化
        /// </summary>
        private bool isInitlized;
    
    
        public void Reset()
        {
            this.MyColor = Color.gray;
            this.ColorPicked = false;
        }
    
        private void OnEnable()
        {
            if(isInitlized==false)
            {
                Init();
            }
        }
    
        private void Start()
        {
            if(isInitlized==false)
            {
                Init();
            }
        }
    
        private void OnGUI()
        {
            //如果标识符为false,则不绘制GUI
            if(this.ColorPicked==false || this.ShowColorLabel==false)
            {
                return;
            }
    
            GUILayout.BeginArea(ColorLabelArea);
            GUILayout.BeginHorizontal();
    
            //绘制图片加文本提示 可以使用Texture2d类型的图片
            Color c = GUI.color;
            GUI.color = this.MyColor;
            GUILayout.Label(this.img);
            GUI.color = c;
    
            //绘制文字提示,提示是否是房主
            string playerNote = PhotonNetwork.isMasterClient ? "是你的颜色\n你是牛逼的房主" : "你是加入这个房间的成员";
            GUILayout.Label(playerNote);
            
            GUILayout.EndHorizontal();
            GUILayout.EndArea();
        }
    
        private void OnDisable()
        {
            PlayerRoomIndexing.instance.OnRoomIndexingChanged -= Refresh;
        }
    
        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            if(!isInitlized && PlayerRoomIndexing.instance != null)
            {
                PlayerRoomIndexing.instance.OnRoomIndexingChanged += Refresh;
                isInitlized = true;
            }
        }
    
        /// <summary>
        /// 刷新房间颜色标识的事件
        /// </summary>
        private void Refresh()
        {
            int _Index = PhotonNetwork.player.GetRoomIndex();
            if(_Index==-1)
            {
                this.Reset();
            }
            else
            {
                this.MyColor = colors[_Index];
                this.ColorPicked = true;
            }
        }
    
        /// <summary>
        /// 当玩家加入房间
        /// </summary>
        public override void OnJoinedRoom()
        {
            if(isInitlized==false)
            {
                Init();
            }
        }
    
        /// <summary>
        /// 当玩家离开房间
        /// </summary>
        public override void OnLeftRoom()
        {
            this.Reset();
        }
    }
    
    
    //---------------------知识点--------------------//
    // 继承自PunBehaviour,她又继承了Unity的MonoBehaviour,而且可以重写回调事件
    //建议管理的脚本继承自此类
    
    //绘制图片+文本的GUI提示
    // GUIBeginArea(Rect rect);
    // GUIBeginHorizontal();
    // GUI.color();
    // GUILayout.Label(Texture2d img);
    // GUILayout.Label(string text);
    // GUIEndHorizontal();
    // GUIEndArea();
    
    //ExitGames.UtilityScripts.PlayerRoomIndexing.instance.OnRoomIndexingChanged  客户端房间索引改变事件(每一个客户端都有一个不唯一的房间索引)
    
    //OnJoinedRoom();     玩家加入房间回调
    //OnLeftRoom();        玩家离开房间回调
    
    //---------------------ColorPerPlayerApply.cs-----------------------//
    
    using ExitGames.UtilityScripts;
    using Photon;
    using UnityEngine;
    
    /// <summary>
    /// 给玩家的物体选择一种颜色
    /// </summary>
    public class ColorPerPlayerApply : PunBehaviour
    {
        /// <summary>
        /// ColorPerPlayer脚本的引用
        /// </summary>
        public static ColorPerPlayer colorPerPlayerCache;
    
        /// <summary>
        /// 渲染组件
        /// </summary>
        private Renderer rendererComponent;
    
        /// <summary>
        /// 渲染组件
        /// </summary>
        private bool isInitlized;
    
        private void Awake()
        {
            rendererComponent = GetComponent<Renderer>();
    
            if(colorPerPlayerCache==null)
            {
                colorPerPlayerCache = FindObjectOfType<ColorPerPlayer>() as ColorPerPlayer;
            }
    
            if(colorPerPlayerCache==null)
            {
                enabled = false;
            }
    
            if(photonView.isSceneView)
            {
                enabled = false;
            }
        }
    
        private void OnEnable()
        {
            if(!isInitlized)
            {
                Init();
            }
        }
    
        private void Start()
        {
            if (!isInitlized)
            {
                Init();
            }
        }
    
        private void OnDestroy()
        {
            isInitlized = false;
            if(PlayerRoomIndexing.instance != null)
            {
                PlayerRoomIndexing.instance.OnRoomIndexingChanged -= ApplyColor;
            }
        }
    
        /// <summary>
        /// 当PhotonServer实例化的时候,调用此函数
        /// </summary>
        /// <param name="info"></param>
        public override void OnPhotonInstantiate(PhotonMessageInfo info)
        {
            this.ApplyColor();
        }
    
    
        /// <summary>
        /// 初始化,当房间索引改变的时候,也就是我们每创建一个玩家(房间),ID就要增加1
        /// 也就是有四个玩家,房间ID分别是 0 1 2 3
        /// </summary>
        private void Init()
        {
            if(isInitlized==false && PlayerRoomIndexing.instance!=null)
            {
                PlayerRoomIndexing.instance.OnRoomIndexingChanged += ApplyColor;
                isInitlized = true;
            }
        }
    
        /// <summary>
        /// 应用颜色
        /// </summary>
        public void ApplyColor()
        {
            if (photonView.owner == null)
            {
                return;
            }
    
            int _Index = photonView.owner.GetRoomIndex();
            Debug.Log("房间ID: " + _Index);
            if(_Index>=0 && _Index<=colorPerPlayerCache.colors.Length)
            {
                //这里我们只是定义了四种颜色,然后上面对房间索引ID做了一层限制
                rendererComponent.material.color = colorPerPlayerCache.colors[_Index];
            }
        }
    }
    
    
    //-------------------知识点-----------------//
    
    // OnPhotonInstantiate(PhotonMessageInfo info);   实例化Photon回调,可以用来做每个客户端的初始化
    
    // PhotonPlayer pp = photoView.owner;    得到客户端玩家的信息
    // photonView.onwer.GetRoomIndex();      得到当前客户端玩家的房间ID(每个客户端都是唯一的)
    
    //--------------------ConnectAndJoinRandom.cs----------------------//
    
    using UnityEngine;
    
    /// <summary>
    /// 连接和加入随机房间
    /// 
    /// </summary>
    public class ConnectAndJoinRandom : Photon.MonoBehaviour
    {
        /// <summary>
        /// 是否自动连接服务器
        /// </summary>
        public bool AutoConnect = true;
    
        /// <summary>
        /// 游戏版本号,可加可不加
        /// </summary>
        public byte Version = 1;
    
        /// <summary>
        /// 是否在Update函数里连接
        /// </summary>
        private bool ConnectInUpdate = true;
    
    
        public virtual void Start()
        {
            //设置自动加入大厅为false
            PhotonNetwork.autoJoinLobby = false;
        }
    
        public virtual void Update()
        {
            //如果服务器没有连接的情况下,就连接服务器
            //每一帧都要检测,然后只要断开就会自动重连
            if(ConnectInUpdate==true && AutoConnect==true && !PhotonNetwork.connected)
            {
                Debug.Log("开始连接到服务器");
                ConnectInUpdate = false;
    
                //连接服务器使用 PhotoNetwork.ConnectUsingSetting(string gameVersion) 进行连接
                //其实就是使用Resources文件夹下的那个.assets的文件
                PhotonNetwork.ConnectUsingSettings(Version + "." + SceneManagerHelper.ActiveSceneBuildIndex);
            }
        }
    
        /// <summary>
        /// 成功连接到服务器的回调 
        /// </summary>
        public virtual void OnConnectedToMaster()
        {
            Debug.Log("已连接到服务器,尝试加入一个随机房间");
            //加入一个随机的房间
            PhotonNetwork.JoinRandomRoom();
        }
    
        /// <summary>
        /// 加入大厅的回调
        /// </summary>
        public virtual void OnJoinedLobby()
        {
            Debug.Log("加入大厅功能,尝试加入玩家大厅");
            PhotonNetwork.JoinRandomRoom();
        }
    
        /// <summary>
        /// 加入随机房间失败的回调
        /// </summary>
        public virtual void OnPhotonRandomJoinFailed()
        {
            Debug.Log("加入房间失败,可能是没有房间,那我们自己创建一个房间");
    
            //因为加入随机房间的失败的原因只能是服务器没有房间
            //所以我们这里就直接创建一个房间
            PhotonNetwork.CreateRoom(null, new RoomOptions() { MaxPlayers = 4 }, null);
        }
    
        /// <summary>
        /// 连接服务器失败的回调
        /// </summary>
        /// <param name="cause"></param>
        public virtual void OnFailedToConnectToPhoton(DisconnectCause cause)
        {
            Debug.Log("连接服务器错误: " + cause);
        }
    
        /// <summary>
        /// 新玩家加入房间回调
        /// </summary>
        public void OnJoinedRoom()
        {
            Debug.Log("一个玩家加入了房间");
        }
    }
    
    
    //----------------------知识点---------------------//
    
    //该脚本继承自Photon.MonoBehaviour类 这个类什么都没有,适合作为扩展类,自己去写虚方法
    //而且这些虚方法要保证方法名正确才能够被调用
    //如果不进行较大的扩展,建议继承自PonBehaviour类
    
    // PhotonNetwork.autoJoinLobby = false;     //设置是否自动加入大厅
    
    // bool res = PhotonNetwork.connected       //判断服务器是否是连接状态
    
    // PhotonNetwork.ConnectUsingSettings(string gameVersion);    //使用Resources文件夹下的PhotonServerSettings文件连接服务器)
    // gameVersion参数可以不填写,也可以加上其他字符
    
    // OnConnectedToMaster();       成功连接到服务器回调
    
    // OnJoinedLobby();             成功加入大厅的回调
    
    // OnJoinedRoom();              新玩家加入房间回调
    
    // OnPhotonRandomJoinFailed();  加入随机房间失败回调
    
    // OnFailedToConnectToPhoton(DisconnectCause cause)   连接服务器失败的回调 DisconnectCause 是一个枚举类 我们直接Switch就行
    
    // PhotonNetwork.JoinRandomRoom();     随机加入一个房间
    
    // PhotonNetwork.CreateRoom(string roomName, RoomOptions roomOptions, TypedLobby typedLobby);    创建一个房间,typeLobby可为空
    
    //------------------DemoBoxesGUI.cs---------------------//
    
    //------------------此脚本实现了一个提示的轮滚的效果,我们可以运用在以后的项目中----------------//
    
    using System.Collections;
    using UnityEngine.UI;
    using UnityEngine;
    
    /// <summary>
    /// 游戏标题的切换的动画效果
    /// </summary>
    public class DemoBoxesGUI : MonoBehaviour
    {
        /// <summary>
        /// 是否隐藏此效果
        /// </summary>
        public bool HideUI;
    
        /// <summary>
        /// 文本提示UI的引用
        /// </summary>
        public Text TextTips;
    
        /// <summary>
        /// 当前提示的索引,默认为0
        /// </summary>
        private int tipsIndex;
    
        /// <summary>
        /// 我们要提示的文本内容
        /// </summary>
        private readonly string[] tips = new string[]
        {
    "随着空中的光影画面逐渐模糊,直至消散,也宣告了这段被封禁的记忆,已经尽数归入轩辕婉蓉的脑海中。",
    "她整张脸失去了血色,苍白得吓人,双手微微颤抖着,呆愣在原地。",
    "“妈的,这些畜生!”段七德为那群人所做之事感到无比震怒,大肆叫嚣“老子要盗空他们的宝库,以儆效尤!”",
    "“算本神尊一份!”二狗子当即喊道。",
    "“滚,没你份!”段七德怒瞪二狗子。",
    "“哎哟我擦尼玛,本神尊行侠仗义碍你什么事了?”二狗子强势硬怼。",
    "这一人一麒麟就在原地干瞪起眼来。",
    "徐缺懒得掺和,目光好奇的落在轩辕婉蓉身上,打量着她。",
    "从踏入这个记忆世界,遇到数万年前的这个轩辕婉蓉时,徐缺就感觉这女人比数万年后还要冷漠无情,但对她谈不上厌恶,当然也谈不上有好感。",
    "他也知道轩辕婉蓉的身世挺可怜的,父母死后连魂魄都被拘谨在天宫院后山,可一直不知道究竟具体发生了什么。",
    "如今亲眼目睹这段回忆,徐缺心里十分的别扭,也充满了愧疚。",
    "他突然想起来,当初仗着自己救出轩辕婉蓉的父母魂魄,于是在轩辕婉蓉面前开了她父母的玩笑,毕竟是皮惯了,贱惯了,不作一下不得劲。",
    "谁曾想那一个玩笑,轩辕婉蓉竟在那一瞬要对他下死手,完全就超脱了徐缺的底线。",
        };
    
    
        /// <summary>
        /// 每一个提示显示的时间
        /// </summary>
        private const float TimePerTip = 3.0f;
    
        /// <summary>
        /// 计时器
        /// </summary>
        private float TimeSinceLastTip;
    
        /// <summary>
        /// Alpha的渐变速度
        /// </summary>
        private const float FadeSpeedForTip = 0.05f;
    
    
        private void Update()
        {
            if (this.TextTips == null)
            {
                return;
            }
    
            //3s为间隔,累积时间
            this.TimeSinceLastTip += Time.deltaTime;
            if(this.TimeSinceLastTip > TimePerTip)
            {
                this.TimeSinceLastTip = 0;
                StartCoroutine(SwapTip());
            }
        }
    
        /// <summary>
        /// 改变提示文本的内容
        /// </summary>
        /// <returns></returns>
        private IEnumerator SwapTip()
        {
            //透明渐变为0
            float alpha = 1.0f;
            while (alpha > 0.0f)
            {
                alpha -= FadeSpeedForTip;
                this.TimeSinceLastTip = 0;
                this.TextTips.color = new Color(this.TextTips.color.r, this.TextTips.color.r, this.TextTips.color.r, alpha);
                yield return null;
            }
    
            //设置文本提示
            this.tipsIndex = (this.tipsIndex + 1) % tips.Length;
            this.TextTips.text = tips[tipsIndex];
    
            //透明度渐变为1
            while (alpha < 1.0f)
            {
                alpha += FadeSpeedForTip;
                this.TimeSinceLastTip = 0;
                this.TextTips.color = new Color(this.TextTips.color.r, this.TextTips.color.r, this.TextTips.color.r, alpha);
                yield return null;
            }
        }
    
        private void OnGUI()
        {
            if(HideUI==true)
            {
                return;
            }
    
            GUILayout.BeginArea(new Rect(0,0,300,Screen.height));
    
            GUILayout.FlexibleSpace();
            GUILayout.BeginHorizontal();
    
            if(!PhotonNetwork.connected)
            {
                if (GUILayout.Button("连接",GUILayout.Width(100)))
                {
                    PhotonNetwork.ConnectUsingSettings(null);
                }
            }
            else
            {
                if (GUILayout.Button("断开", GUILayout.Width(100)))
                {
                    PhotonNetwork.Disconnect();
                }
            }
    
            //绘制当前连接的状态
            //PhotonNetwork.connectionStateDetailed 表示的是当前客户端的连接状态 
            //会返回一个枚举类型 ClientState
            GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());
    
            GUILayout.EndHorizontal();
    
            GUILayout.EndArea();
        }
    }
    
    
    //----------------知识点----------------//
    
    // GUILayout.FiexibleSpace();                //四角对齐 
    
    // GUILayout.Button("buttoname",GUI.Width(float width));     绘制一个按钮,一般是结合上面的 if 语句进行使用
    
    // PhotonNetwork,connectionStateDatailed.ToString();         得到服务器的连接状态的详细信息
    
    //PhotonNetwork.Disconnect();       断开服务器连接
    
    //---------------------OnAwakePhysicsSetting.cs------------------------//
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 初始化物理设置
    /// RequireComponent 这个特性的功能是当前在给游戏物体添加这个脚本时,会自动添加组价PhotonView
    /// </summary>
    [RequireComponent(typeof(PhotonView))]
    public class OnAwakePhysicsSetting : Photon.MonoBehaviour
    {
        private void Awake()
        {
            //得到要同步的游戏物体身上的3d或2d刚体
            if(photonView.isMine==false)
            {
                //尝试得到一个3d刚体并设置动力学
                Rigidbody rigidbody = GetComponent<Rigidbody>();
                if(rigidbody!=null)
                {
                    rigidbody.isKinematic = true;
                }
                else
                {
                    //如果3D刚体为null,则尝试的得到2d的刚体并设置动力学
                    Rigidbody2D rigidbody2D = GetComponent<Rigidbody2D>();
                    if(rigidbody2D != null)
                    {
                        rigidbody2D.isKinematic = true;
                    }
                }
            }
        }
    }
    
    
    //---------------------知识点---------------------//
    //不管是继承自 Photon.MonoBehaviour 还是 PonBehaviour 都有一个photonView的属性
    
    // bool res = photonView.isMine;         确定当前客户端是否是自己
    
    //-------------------OnClickFlashRpc.cs---------------------//
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 点击方块的时候实现闪烁的效果
    /// 所有放在游戏物体的脚本都要继承子Photon.MonoBehaviour,他说UnityEngine.MonoBehaviour进一步的封装
    /// </summary>
    public class OnClickFlashRpc : Photon.MonoBehaviour
    {
        /// <summary>
        /// 当前方块的材质球
        /// </summary>
        private Material originMat;
    
        /// <summary>
        /// 初始的颜色,因为我们这里的效果是闪烁
        /// </summary>
        private Color originCol;
    
        /// <summary>
        /// 是否在闪烁
        /// </summary>
        private bool isFlashing;
    
    
        /// <summary>
        /// 这个方法同样和ClickInstantiate的方法一样,只不过点击的物体是方块
        /// 该方法是由 PhotomServer 的 UtilityScripts 的 InputToEvent和PointedAtGameObjectInfo通过SendMessage调用
        /// </summary>
        private void OnClick()
        {
            //目前此方法看来适用于协程
            photonView.RPC("Flash", PhotonTargets.All);
        }
    
        [PunRPC]
        private IEnumerator Flash()
        {
            //如果在闪烁,则返回
            if(isFlashing)
            {
                yield break;
            }
    
            isFlashing = true;
    
            //这边通过改变材质球的颜色实现一个闪烁的效果
            this.originMat = GetComponent<Renderer>().material;
            if(this.originMat.HasProperty("_Emission")==false)
            {
                Debug.Log("没有发现 _Emission 的属性,请检查材质球");
                yield break;
            }
    
            //设置材质球的颜色颜色
            this.originCol = this.originMat.GetColor("_Emission");
            this.originMat.SetColor("_Emission", Color.green);
    
            //通过插值运算回到之前的颜色
            for (float i = 0.0f; i < 1.0f; i+=0.08f)
            {
                Color lerpCol = Color.Lerp(Color.green, this.originCol, i);
                this.originMat.SetColor("_Emission", lerpCol);
                yield return null;
            }
    
            //完全校正材质球的颜色
            this.originMat.SetColor("_Emission",originCol);
    
            //标识符设置为false
            isFlashing = false;
        }
    }
    
    
    //---------------------知识点---------------------//
    // photonView.RPC("Flash", PhotonTargets.All);  目前看来是只适合执行一个协程
    
    // 要执行的协程必须带有   ******** [PunRPC] *********   这个特性 
    
    // Shrarder的类型是之前图片的VertextLit  可以运用到方块上,选择具体的贴图 ,她有一个 _Emission的属性可以修改颜色
    
    //----------------OnDoubleclickDestroy.cs-----------------//
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 双击销毁游戏物体
    /// </summary>
    public class OnDoubleclickDestroy : Photon.MonoBehaviour
    {
        private float timeOfLastClick;
        private float clickDeltaForDoubleClick = 0.2f;
    
        /// <summary>
        /// 此方法同之前的OnClick,同属于同一游戏物体,所以该游戏物体被点击都会调用
        /// </summary>
        private void OnClick()
        {
            //确保点击的方块是自己创建的
            if(photonView.isMine == false)
            {
                return;
            }
    
            //双击的一个方法,个人感觉很巧妙,我们可以运用到项目中
            if(Time.time - timeOfLastClick < clickDeltaForDoubleClick)
            {
                PhotonNetwork.Destroy(this.gameObject);
            }
            else
            {
                this.timeOfLastClick = Time.time;
            }
        }
    }
    
    //------------------知识点----------------//
    // 此脚本中有一个 双击检测点击的方法,我们可以运用到项目中
    

    相关文章

      网友评论

        本文标题:PhotonServer插件教程

        本文链接:https://www.haomeiwen.com/subject/nufznctx.html