繁体   English   中英

Player ReSpawn Logic Unity 多人游戏

[英]Player ReSpawn Logic Unity Multiplayer

我正在通过 Unity Multiplayer 系统学习多人游戏实现。 所以我遇到了为初学者编写的非常好的教程: Introduction to a Simple Multiplayer Example

从本教程中,我无法理解此页面内容: Death and Respawning

通过这段代码,他们在教程中谈论我们的玩家将重生(玩家将在 0 position 处转换并且生命值将为 100)并且玩家可以再次开始战斗。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class Health : NetworkBehaviour {

public const int maxHealth = 100;

[SyncVar(hook = "OnChangeHealth")]
public int currentHealth = maxHealth;

public RectTransform healthBar;

public void TakeDamage(int amount)
{
    if (!isServer)
        return;

    currentHealth -= amount;
    if (currentHealth <= 0)
    {
        currentHealth = maxHealth;

        // called on the Server, but invoked on the Clients
        RpcRespawn();
    }
}

void OnChangeHealth (int currentHealth )
{
    healthBar.sizeDelta = new Vector2(currentHealth , healthBar.sizeDelta.y);
}

[ClientRpc]
void RpcRespawn()
{
    if (isLocalPlayer)
    {
        // move back to zero location
        transform.position = Vector3.zero;
    }
}
}

根据我的想法 -> 所有客户端都在执行 ClientRPC,因此本地玩家的所有设备都将在出生点 position 处移动,并且健康状况会变满。 按照本教程 -> 只有自己的玩家出生点 position 和健康得到更新。

那么为什么会发生我无法理解的事情呢? 实际上,RPC 会调用所有客户端,然后所有客户端都应要求在开始时移动 position 并获得完全健康。 请给我一些解释。

正如您在该图像上看到的,您需要考虑网络系统不是“共享”房间,它们实际上是在您自己房间中复制其他系统的所有内容。 在此处输入图片说明 知道了这一点,现在您可以理解,如果从播放器1发送Rpc,则Rpc将在播放器1上执行,而播放器1将在播放器2的房间中复制。

正如您可以在文档上看到的那样,原因是[ClientRpc]属性:

是可以放在NetworkBehaviour类的方法上的属性,以允许从服务器在客户端上调用它们。

因此,由于玩家1房间是主机(服务器+客户端),而玩家2是客户端,则它将在2个房间的主机上执行,但在第一个房间进行评估。

编辑:这意味着,例如,当播放器1死亡时,它将调用RPC函数,并且(因为它是RPC)他在房间2上的副本(Player1-Copy)将执行相同的操作。

根据我的理解,respawnprefab 必须在 ServerRpc 上实例化,实际的重生逻辑(改变玩家的变换)应该在 ClientRpc 中给出。

private void Die()
{
    isDead = true;

    //Disable Components
    for (int i = 0; i < disableOnDeath.Length; i++)
    {
        disableOnDeath[i].enabled = false;
    }

    Collider _col = GetComponent<Collider>();
    if (_col != null)
    {
        _col.enabled = false;
    }

    Debug.Log(transform.name + " is Dead");

    //call respawn method
    StartCoroutine(Respawn(transform.name));
}

private IEnumerator Respawn(string _playerID)
{
    yield return new WaitForSeconds(GameManager.instance.matchSettings.respawnDelay);
    SpawningServerRpc(_playerID);
   
}

[ServerRpc(RequireOwnership = false)]
void SpawningServerRpc(string _playerID)
{
    Transform spawnedPointTransform = Instantiate(spawnPoint);
    spawnedPointTransform.GetComponent<NetworkObject>().Spawn(true);
    SpawnClientRpc(_playerID);   
}

[ClientRpc]
void SpawnClientRpc(string _playerID)
{
    Player _player = GameManager.GetPlayer(_playerID);
    Debug.Log("The player who dies is:" + _player.transform.name);
    _player.transform.position = spawnPoint.position;
    Debug.Log("I am Respawned" + _player.name + "Position:" + _player.transform.position);
    SetDefaults();
}

希望这对你有帮助。 干杯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM