Why does OnTriggerEnter call on client and master
The whole answer can be found below.
Try Our
Documentation
Please check if you can find an answer in our extensive documentation on PUN.
Join Us
on Discord
Meet and talk to our staff and the entire Photon-Community via Discord.
Read More on
Stack Overflow
Find more information on Stack Overflow (for Circle members only).
Why does OnTriggerEnter call on client and master
Distul
2017-06-26 06:36:54
Whenever I pass over a trigger with the code below fires as though both the client and master are passing over the trigger.
private void OnTriggerEnter(Collider other)
{
PlayerTracker.Instance.ModifyHealth(PhotonNetwork.player, -10);
}
public void ModifyHealth(PhotonPlayer photonPlayer, int value)
{
PhotonView.RPC("RPC_ModifyHealth", PhotonTargets.MasterClient, photonPlayer, value);
}
The trigger does not have a photonview attached. I would expect it to call ModifyHealth on the client which travels into it, which then calls RPC_ModifyHealth on the master passing in client as the PhotonPlayer. This does happen, the trigger is called again passing in the master as PhotonPlayer, even though the master is no where near the trigger.
Comments
bumpity
[Deleted User]
2017-06-29 09:40:59
Hi @Distul,
in this case OnTriggerEnter is executed on each client and furthermore each client send the RPC to the MasterClient. According to the code snippet, this object has an attached PhotonView component, so you can add PhotonView.isMine condition at the beginning of the OnTriggerEnter function to avoid processing this callback on each client.
private void OnTriggerEnter(Collider other)
{
if (!PhotonView.isMine)
return;
// do stuff
}
@Christian_Simon wrote:
Hi @Distul,
in this case OnTriggerEnter is executed on each client and furthermore each client send the RPC to the MasterClient. According to the code snippet, this object has an attached PhotonView component, so you can add PhotonView.isMine condition at the beginning of the OnTriggerEnter function to avoid processing this callback on each client.
private void OnTriggerEnter(Collider other) { if (!PhotonView.isMine) return; // do stuff }
This would not work. All objects placed in scene prior to runtime are owned by server. Thus the photonview will always be owned by server regardless of who passes over it.
However, you sparked a realization in my head and I came up with the following which works.
private void OnTriggerEnter(Collider other)
{
PhotonView photonView = other.GetComponent();
if (photonView != null && photonView.isMine)
PlayerTracker.Instance.ModifyHealth(PhotonNetwork.player, -10);
}
You have to check if the photonview hit on 'other' isMine.
But since you want to of course remain authoritative, this would be the proper way of doing it.
private void OnTriggerEnter(Collider other)
{
if (!PhotonNetwork.isMasterClient)
return;
PhotonView photonView = other.GetComponent();
if (photonView != null)
PlayerTracker.Instance.ModifyHealth2(photonView.owner, -10);
}
Then, where as PlayerStats is a collection of each players PhotonPlayer and associated stats for that player.
public void ModifyHealth2(PhotonPlayer photonPlayer, int value)
{
int index = PlayerStats.FindIndex(x => x.PhotonPlayer == photonPlayer);
if (index != -1)
{
PlayerStats playerStats = PlayerStats[index];
playerStats.Health += value;
if (playerStats.Health <= 0)
PlayerNetwork.Instance.PlayerDied(photonPlayer);
}
}
Back to top