unity3d 玩家再生逻辑Unity多人游戏

3phpmpom  于 2023-01-13  发布在  其他
关注(0)|答案(2)|浏览(159)

我正在通过Unity多人游戏系统学习多人游戏实现。所以我遇到了这个为初学者编写的非常好的教程:Introduction to a Simple Multiplayer Example
从这个教程,我不能理解这个页面的内容:Death and Respawning
通过这段代码,在教程中他们正在谈论我们的球员将重生(球员将在0位置转换和健康将是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,所以所有设备本地球员将移动到产卵位置和健康得到充分.根据本教程-〉只有自己的球员产卵位置和健康得到更新.
所以为什么这件事发生,我不能理解?实际上RPC得到调用所有客户端,然后所有客户端应该要求移动在开始的位置,并获得充分的健康。请给予我一些解释在这方面。

bvjxkvbb

bvjxkvbb1#

正如您在此图像中所看到的,您需要考虑网络系统不是一个“共享”房间,它们实际上是在您自己的房间中复制其他人的所有内容。x1c 0d1x了解了这一点,现在您可以理解,如果您从Player 1发送Rpc,则该Rpc将在您的Player 1上执行,而Player 1- Copy将在Player 2的房间中执行。
因为您可以在文档中看到,[ClientRpc]属性:
是一个属性,可以放在NetworkBehaviour类的方法上,以允许从服务器在客户端上调用这些方法。
由于参与者1的房间是主机(服务器+客户端),参与者2是客户端,因此它将在两个房间上执行,但在第一个房间上评估。

Edit:这意味着,例如,当玩家1死亡时,它将调用RPC函数,并且(因为这是一个RPC)他在房间2上的副本(Player 1-Copy)也将执行相同的操作。

k4emjkb1

k4emjkb12#

据我所知,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();
}

希望这对你有帮助,干杯👍

相关问题