在我的多人游戏中,我想要一个名为“Up Camera”的观众摄像机,当玩家死亡时会启用它。 当玩家死亡时它会被启用,但它会在全球范围内启用它,这意味着即使你没有死,你仍然会在你死后获得相机。 变量由弹丸传输,弹丸中包含发射子弹的人和与之相撞的人的 ID
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;
public class damageMenager : MonoBehaviour
{
public int hp;
public GameObject player;
public Image hpBar;
public PlayerSpawner playerSpawner;
public void Update()
{
if(this.gameObject == player)
{
hpBar.fillAmount = hp / 100f ;
}
}
private void Awake()
{
playerSpawner = FindObjectOfType<PlayerSpawner>();
}
public void takeDamage(int damage, GameObject otherPlayer, int shooterId)
{
if (otherPlayer.GetPhotonView() != null)
{
if (otherPlayer.GetPhotonView().ViewID != shooterId)
{
if (hp <= 0)
{
foreach (Transform tm in otherPlayer.transform)
{
if (tm.GetComponent<wheelController>() != null)
{
tm.GetComponent<wheelController>().enabled = false;
}
}
otherPlayer.transform.Find("Camera").gameObject.SetActive(false);
otherPlayer.transform.Find("CM FreeLook1").gameObject.SetActive(false);
otherPlayer.transform.Find("Canvas").gameObject.SetActive(false);
otherPlayer.GetComponent<tuttiPU>().enabled = false;
otherPlayer.GetComponent<mina>().enabled = false;
otherPlayer.GetComponent<Inpiedi>().enabled = false;
otherPlayer.GetComponent<cannoniDavanti>().enabled = false;
otherPlayer.GetComponent<localPlayerManager>().enabled = false;
otherPlayer.GetComponent<damageMenager>().enabled = false;
otherPlayer.transform.Find("Up Camera").gameObject.SetActive(true);
}
else
{
hp -= damage;
}
}
}
}
}
当我的玩家杀死某人时,摄像机会切换到应该为死去的玩家拍摄的摄像机。 我需要一个建议,只在生命为 < than 0
的玩家本地启用“向上摄像头”免责声明
如果没有所有详细信息,按照您的要求提供示例总是很困难。
我仍然会尝试在这里指出您的概念中通常存在的问题以及如何解决它 - 不过,此代码很可能无法作为复制和粘贴解决方案。我希望您理解这个概念,然后将其应用到您的项目中。
正如您所提到的,代码中的一个主要误解/误解是
otherPlayer
此时与网络完全无关。您正在与设备上的本地对象发生碰撞,并调用其上的某些方法,例如启用相机 => 这发生在您的本地设备上!
它也发生在所有其他客户端上的事实只是因为所有其他客户端也在本地执行相同的操作!
所以你更想做的 - 你提到这个
damageMenager
是你的播放器上的一个组件 - 只处理本地客户端上的 takeDamage
=> 它应该是其他客户端在你需要的时候发送给你的 RPC调用它。
那么这种伤害只能由你来处理,并且你只能激活你自己的本地相机。
因此,假设这个
takeDamge
是由实际击中你的玩家的东西(例如另一个玩家的子弹)调用的,它可能应该看起来像例如
// As this is on the player make it a MonoBehaviourPun so you have access to your PhotonView
// additionally in order to synchronize the HP field make it an IPunObservable and implement OnPhotonSerializeView (see below)
public class damageMenager : MonoBehaviourPun, IPunObservable
{
[Range(0, 100)]
public int hp = 100;
public Image hpBar;
[Tooltip("Add all your own components that should be disabled when you die")]
public List<Component> ThingsToDisableOnDeath;
[Tooltip("Add all your own GameObject's that should be deactivated when you die")]
public List<GameObject> ThingsToDeactivateOnDeath;
[Tooltip("Add all your own GameObject's that should be activated when you die")]
public List<GameObject> ThingsToActivateOnDeath;
private void Awake()
{
playerSpawner = FindObjectOfType<PlayerSpawner>();
hpBar.fillAmount = hp / 100f;
}
[PunRPC]
public void takeDamage(int damage)
{
// make sure only handled by local client
if(!phtonView.IsMine) return;
hp -= damage;
hpBar.fillAmount = hp / 100f;
if (hp <= 0)
{
// if you already reference those in ThingsToDisableOnDeath as well you can skip this
foreach (var wheel in GetComponentInChildren<wheelController>())
{
wheel.enabled = false;
}
foreach (var component in ThingsToDisableOnDeath)
{
component.enabled = false;
}
foreach (var obj in ThingsToDeactivateOnDeath)
{
component.SetActive(false);
}
foreach (var obj in ThingsToActivateOnDeath)
{
component.SetActive = true;
}
}
}
// And now to the synchronization of the HP field
public void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting) // basically means you are the local client
{
stream.SendNext(hp);
}
else // you are another client receiving the information
{
hp = (int)stream.ReceiveNext();
hpBar.fillAmount = hp / 100f;
}
}