PUN ☀️九、玩家网络实例化与昵称显示

简介: PUN ☀️九、玩家网络实例化与昵称显示

🟥 目标

1️⃣ 玩家网络实例化

即把玩家要操控的角色生成出来。GameManager里面Start时实例化角色。


2️⃣ 实现战斗数据不重置

原先只有两个人,再加入一个人,会切换到3人的场景。但原先的两个人当前战斗数据会被重置,这是不合理的。

我们来让之前的玩家数据不被重置。

a、PlayerManager 声明的静态字段LocalPlayerInstance 记录本地玩家实例化的。

Awake赋值,并在加载新场景时,不销毁当前角色。

b、但在重新加载新场景时,GameManager 脚本 Start时会再次实例化角色,于是一个玩家就有了两个角色。所以GameManager Start时根据判断 LocalPlayerInstance 是否为空,确定是否已经实例化了角色。


3️⃣ 位置重置

若从3人房切换到2人房,房间变小了。若切换后原先在地面上的角色悬空了,会出Bug。

所以增加判断:若切换后没踩在地板上,则位置回到出生位置(原点高空)。

方法:PlayerManager 脚本Start时增加加载完场景时的委托,增加的委托事件判断当前角色位置


4️⃣ 激光碰撞判断

解决当跳跃时触发激光,会造成自身减血的现象。

这是因为激光与自身角色控制器的触发器检测碰撞了,我们要检测激光不是接触的自身才行,避免自己碰撞掉血。解决办法:

  • 设置自身的Tag,触发检测Tag再决定是否减血。
  • PlayerManager脚本判断射线碰撞到的角色是否是自己,不是的话再减血(此处采用)
if (other.GetComponentInParent<PhotonView>().IsMine)
    return;
 
Health -= 0.1f;

现在我们可以测试看看,如果发现连接不上,就换成中国区Appid试试,我隔了一天申请通过了,现在你申请的应该也好了。


🟧 代码编写

🚩 PlayerManager

using UnityEngine;
using Photon.Pun;
 
public class PlayerManager : MonoBehaviourPunCallbacks, IPunObservable
{
    #region Parameters
 
    public GameObject beams;
 
    //记录本地玩家实例化
    public static GameObject LocalPlayerInstance;
 
    public float Health = 1f;
 
    //当用户开火时,为True
    bool IsFiring;
 
    #endregion
 
 
    #region Mono CallBacks
 
    void Awake()
    {
        beams.SetActive(false);
 
        if (PhotonNetwork.IsConnected == true && photonView.IsMine)
            LocalPlayerInstance = gameObject;
 
        DontDestroyOnLoad(gameObject);
    }
 
    void Start()
    {
        //当重新加载场景时,检测改脚本所赋值的角色是否踩在空中,若是,则回到出生点重新降落。
        UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoaded;
 
        if (PhotonNetwork.IsConnected && photonView.IsMine)
            GetComponent<Skode_CameraWork>().OnStartFollowing();
    }
 
    void Update()
    {
        if (Health <= 0f)
            GameManager.ins.Skode_LeaveRoom();
 
        if (PhotonNetwork.IsConnected == true && photonView.IsMine)
            ProcessInputs();
 
        if (IsFiring != beams.activeSelf)
            beams.SetActive(IsFiring);
    }
 
    void OnTriggerEnter(Collider other)
    {
        if (!photonView.IsMine && !other.CompareTag("beam"))
            return;
 
        Health -= 0.1f;
    }
 
    void OnTriggerStay(Collider other)
    {
        if (!photonView.IsMine && !other.CompareTag("beam"))
            return;
 
        //乘以增量时间,防止因为帧率FPS不同,扣血不同(举例:不乘,每帧执行一次扣血,卡的人比流畅的人扣血少)
        Health -= 0.1f * Time.deltaTime;
    }
 
    #endregion
 
 
    #region PUN CallBacks
 
    public override void OnDisable()
    {
        base.OnDisable();
        UnityEngine.SceneManagement.SceneManager.sceneLoaded -= OnSceneLoaded;
    }
 
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if (stream.IsWriting)
        {
            // 我们拥有这个角色:把我们的数据发送给其他人
            stream.SendNext(IsFiring);
            stream.SendNext(Health);
        }
        else
        {
            // 网络角色,接收数据
            IsFiring = (bool)stream.ReceiveNext();
            Health = (float)stream.ReceiveNext();
        }
    }
 
    #endregion
 
 
    #region Private Methods
 
    void OnSceneLoaded(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode loadingMode)
    {
        CalledOnLevelWasLoaded(scene.buildIndex);
    }
 
    void CalledOnLevelWasLoaded(int level)
    {
        // 检查我们是否在竞技场外面,如果是这样,移动到竞技场中心的安全地带
        if (!Physics.Raycast(transform.position, -Vector3.up, 5f))
        {
            transform.position = new Vector3(0f, 5f, 0f);
        }
    }
 
    void ProcessInputs()
    {
        //鼠标左键
        if (Input.GetButtonDown("Fire1"))
            IsFiring = true;
 
        if (Input.GetButtonUp("Fire1"))
            IsFiring = false;
    }
 
    #endregion
}


🚩 GameManager

using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
 
public class GameManager : MonoBehaviourPunCallbacks
{
    public static GameManager ins;
 
    [Tooltip("用来代表玩家的预置体")]
    public GameObject playerPrefab;
 
 
    #region Mono CallBacks
 
    private void Awake()
    {
        ins = this;
    }
 
    private void Start()
    {
        //若本地玩家第一次进游戏场景,还未生成角色,则生成一个。
        //且这个角色通过使用PhotonNetwork.Instantiate进行同步
        if (PlayerManager.LocalPlayerInstance == null)
            PhotonNetwork.Instantiate(playerPrefab.name, new Vector3(0f, 5f, 0f), Quaternion.identity, 0);
    }
 
    #endregion
 
 
    #region Public Methods
 
    //离开服务器房间Btn
    public void Skode_LeaveRoom()
    {
        //不允许主客户端离开房间
        if (!PhotonNetwork.IsMasterClient)
            PhotonNetwork.LeaveRoom();
    }
 
    #endregion
 
 
    #region PUN Callbacks
 
    /// <summary>
    /// 本地玩家离开服务器房间时回调
    /// </summary>
    public override void OnLeftRoom()
    {
        // 加载大厅场景
        SceneManager.LoadScene(0);
    }
 
    /// <summary>
    /// 其他玩家连接房间时的回调(不是自己)
    /// </summary>
    public override void OnPlayerEnteredRoom(Player other)
    {
        print(other.NickName + "    加入房间");
 
        //根据当前玩家的人数,主客户端加载对应场景
        if (PhotonNetwork.IsMasterClient)
            LoadArena();
    }
 
    //当玩家离开房间或变得不活动时调用。
    public override void OnPlayerLeftRoom(Player other)
    {
        print(other.NickName + "    离开了房间");
 
        //根据当前玩家的人数,主客户端加载对应场景
        if (PhotonNetwork.IsMasterClient)
            LoadArena();
    }
 
    #endregion
 
 
    #region Private Methods
 
    void LoadArena()
    {
        //Photon分为主客户端、其他客户端。只有主客户端才可进行加载房间。
        //根据当前房间人数加载对应场景。该方法会使其他玩家会自动加入主客户端的房间
        PhotonNetwork.LoadLevel("Room for " + PhotonNetwork.CurrentRoom.PlayerCount);
    }
 
    #endregion
}


🟨 血条、昵称显示

1、创建UI

在人物下创建3D Slider血条,并且有文本框用于显示名字。

若是滑动条即使是满值也不到头,只需改下滑动条下Fill Area 的 Right值就好了。

2、代码赋值

将下代码挂到机器人身上,并赋值。

using UnityEngine;
using UnityEngine.UI;
 
public class PlayerUI : MonoBehaviour
{
    #region  Parameters
 
    [Tooltip("显示玩家名字的UI文本")]
    public Text playerNameText;
 
    [Tooltip("健康值Slider")]
    public Slider playerHealthSlider;
 
    [Tooltip("用于获取生命值赋值给血条")]
    public PlayerManager target;
 
    #endregion
 
 
    #region Mono Callbacks
 
    void Start()
    {
        playerNameText.text = target.photonView.Owner.NickName;
    }
 
    void Update()
    {
        playerHealthSlider.value = target.Health;
    }
 
    #endregion
}

若现在还没把机器人放到 Resources里,现在就要放进去了。已经放进去的Apply一下。

将 Resources 里的机器人预制体赋值给GameManager,删掉面板的机器人。

各个场景的 GameManager都赋值一下,接下来要进行测试了。

还有,记得关闭离线模式哦


🟩 最终效果展示:

落头上了哈哈

好啦,本系列暂告一段落🧸


相关文章
|
10天前
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
48 17
|
21天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将介绍网络安全的重要性,分析常见的网络安全漏洞及其危害,探讨加密技术在保障网络安全中的作用,并强调提高安全意识的必要性。通过本文的学习,读者将了解网络安全的基本概念和应对策略,提升个人和组织的网络安全防护能力。
|
22天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
44 10
|
24天前
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,并提供一些实用的代码示例。通过阅读本文,您将了解到如何保护自己的网络安全,以及如何提高自己的信息安全意识。
48 10
|
24天前
|
存储 监控 安全
云计算与网络安全:云服务、网络安全、信息安全等技术领域的融合与挑战
本文将探讨云计算与网络安全之间的关系,以及它们在云服务、网络安全和信息安全等技术领域中的融合与挑战。我们将分析云计算的优势和风险,以及如何通过网络安全措施来保护数据和应用程序。我们还将讨论如何确保云服务的可用性和可靠性,以及如何处理网络攻击和数据泄露等问题。最后,我们将提供一些关于如何在云计算环境中实现网络安全的建议和最佳实践。
|
25天前
|
监控 安全 网络安全
网络安全与信息安全:漏洞、加密与意识的交织
在数字时代的浪潮中,网络安全与信息安全成为维护数据完整性、保密性和可用性的关键。本文深入探讨了网络安全中的漏洞概念、加密技术的应用以及提升安全意识的重要性。通过实际案例分析,揭示了网络攻击的常见模式和防御策略,强调了教育和技术并重的安全理念。旨在为读者提供一套全面的网络安全知识框架,从而在日益复杂的网络环境中保护个人和组织的资产安全。
|
22天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
在数字化时代,网络安全和信息安全已成为我们日常生活中不可或缺的一部分。本文将深入探讨网络安全漏洞、加密技术和安全意识等方面的问题,并提供一些实用的建议和解决方案。我们将通过分析网络攻击的常见形式,揭示网络安全的脆弱性,并介绍如何利用加密技术来保护数据。此外,我们还将强调提高个人和企业的安全意识的重要性,以应对日益复杂的网络威胁。无论你是普通用户还是IT专业人士,这篇文章都将为你提供有价值的见解和指导。
|
23天前
|
安全 算法 网络协议
网络安全与信息安全知识分享
本文深入探讨了网络安全漏洞、加密技术以及安全意识三个方面,旨在帮助读者更好地理解和应对网络安全威胁。通过分析常见的网络安全漏洞类型及其防范措施,详细介绍对称加密和非对称加密的原理和应用,并强调提高个人和企业安全意识的重要性,为构建更安全的网络环境提供指导。
35 2
|
23天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:漏洞、加密与意识的艺术
在数字世界的迷宫中,网络安全和信息安全是守护者之剑。本文将揭示网络漏洞的面纱,探索加密技术的奥秘,并强调安全意识的重要性。通过深入浅出的方式,我们将一起走进这个充满挑战和机遇的领域,了解如何保护我们的数字身份不受威胁,以及如何在这个不断变化的环境中保持警惕和适应。
38 1

热门文章

最新文章