Search Unity

Third Party PUN 2 - RPC only works when moving

Discussion in 'Multiplayer' started by Nightm4reProds, Jul 30, 2019.

  1. Nightm4reProds

    Nightm4reProds

    Joined:
    Oct 11, 2017
    Posts:
    7
    I'm trying to make a top-down shooting game. But the other's clients won't Instatiate the bullet through RPC unless the "sender" of the RPC is moving, but it'll RECEIVE the RPC. Here's a example. (You can see he "prints" the message, but the bullet wont instatiate or "be saw")
     
    Last edited: Jul 30, 2019
  2. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    There's little anyone can do to help unless you post your code (in code tags).
     
  3. Nightm4reProds

    Nightm4reProds

    Joined:
    Oct 11, 2017
    Posts:
    7
    Sure. Sorry about that.


    Player movement code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Photon.Pun;
    5. using System;
    6. using UnityEngine.UI;
    7.  
    8. public class Player : Photon.Pun.MonoBehaviourPun
    9. {
    10.  
    11.     public bool Active;
    12.     public bool PlayerOn = false;
    13.  
    14.     private float baseSpeed;
    15.     public float buffSpeed;
    16.     private Rigidbody playerBodyRb;
    17.     public GameObject playerBody;
    18.  
    19.     public double health;
    20.     public double armor;
    21.  
    22.     powerUps myPowerUps;
    23.  
    24.     public float borderThickness;
    25.     public float distance;
    26.  
    27.  
    28.     public bool isRunning;
    29.     public bool isAttacking;
    30.     Animator anim;
    31.  
    32.     public Text velocidad;
    33.  
    34.     public List<Debuff> debuffs = new List<Debuff>();
    35.  
    36.  
    37.     private void Awake()
    38.     {
    39.         if (photonView.IsMine)
    40.         {
    41.             PlayerOn = true;
    42.         }
    43.  
    44.     }
    45.  
    46.     // Start is called before the first frame update
    47.     void Start()
    48.     {
    49.  
    50.         //Player Variables
    51.         baseSpeed = 10f;
    52.         buffSpeed = 0f;
    53.  
    54.         health = 100;
    55.         armor = 0;
    56.         playerBodyRb = playerBody.GetComponent<Rigidbody>();
    57.  
    58.         myPowerUps = gameObject.GetComponent<powerUps>();
    59.         anim = GetComponentInChildren<Animator>();
    60.  
    61.     }
    62.  
    63.     // Update is called once per frame
    64.     void Update()
    65.     {
    66.  
    67.         if (PlayerOn)
    68.         {
    69.             //CameraControl();
    70.             GetInput();
    71.             RotateToMouse();
    72.             HandleDebuffs();
    73.         }
    74.     }
    75.  
    76.     private void RotateToMouse()
    77.     {
    78.         Plane playerPlane = new Plane(Vector3.up, playerBody.transform.position);
    79.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    80.         float hitDist = 0.0f;
    81.  
    82.         if (playerPlane.Raycast(ray, out hitDist))
    83.         {
    84.             Vector3 targetPoint = ray.GetPoint(hitDist);
    85.             Quaternion targetRotation = Quaternion.LookRotation(targetPoint - playerBody.transform.position);
    86.             targetRotation.x = 0;
    87.             targetRotation.z = 0;
    88.             playerBody.transform.rotation = Quaternion.Slerp(playerBody.transform.rotation, targetRotation, 7f * Time.deltaTime);
    89.  
    90.         }
    91.     }
    92.  
    93.     public void GetInput()
    94.     {
    95.         Vector3 movement = new Vector3(0, 0, 0);
    96.  
    97.         //Adelante pulsar
    98.         if (Input.GetKey(KeyCode.W))
    99.         {
    100.  
    101.             movement = movement + new Vector3(0, 0, 1);
    102.             anim.SetBool("walking", true);
    103.  
    104.         }
    105.  
    106.         //Adelante soltar
    107.         if (Input.GetKeyUp(KeyCode.W))
    108.         {
    109.             anim.SetBool("walking", false);
    110.         }
    111.  
    112.         //Derecha pulsar
    113.         if (Input.GetKey(KeyCode.D))
    114.         {
    115.             movement = movement + new Vector3(1, 0, 0);
    116.             anim.SetBool("walking", true);
    117.         }
    118.  
    119.         //Derecha soltar
    120.         if (Input.GetKeyUp(KeyCode.D))
    121.         {
    122.             anim.SetBool("walking", false);
    123.         }
    124.  
    125.         //Izquierda pulsar
    126.         if (Input.GetKey(KeyCode.A))
    127.         {
    128.             movement = movement + new Vector3(-1, 0, 0);
    129.             anim.SetBool("walking", true);
    130.         }
    131.  
    132.         if (Input.GetKeyUp(KeyCode.A))
    133.         {
    134.             anim.SetBool("walking", false);
    135.         }
    136.  
    137.         //Atras pulsar
    138.         if (Input.GetKey(KeyCode.S))
    139.         {
    140.             movement = movement + new Vector3(0, 0, -1);
    141.             anim.SetBool("walking", true);
    142.         }
    143.  
    144.         //Atras soltar
    145.         if (Input.GetKeyUp(KeyCode.S))
    146.         {
    147.             anim.SetBool("walking", false);
    148.         }
    149.  
    150.         if (Input.GetMouseButton(0))
    151.         {
    152.  
    153.             anim.SetBool("attacking", true);
    154.         }
    155.         else if (!isPlaying(anim, "Attacking") && !anim.IsInTransition(0) && anim.GetBool("attacking"))
    156.         {
    157.  
    158.             anim.SetBool("attacking", false);
    159.  
    160.         }
    161.  
    162.         playerBodyRb.MovePosition(playerBody.transform.position + (movement * Time.deltaTime * (baseSpeed + (buffSpeed))));
    163.  
    164.         if (Input.GetKey(KeyCode.M))
    165.         {
    166.             Debug.Log("ANAÑADIENDO DEBUFF - M");
    167.  
    168.             AddDebuff(new SlowDebuff(this));
    169.             Debug.Log(this.GetType());
    170.             Debug.Log("AÑADIDO SLOW");
    171.             Debug.Log("El numero de objetos en debuffs es " + debuffs.Count);
    172.             debuffs.ForEach(delegate (Debuff debuff)
    173.             {
    174.                 Debug.Log(debuff.toString());
    175.             });
    176.         }
    177.  
    178.         //velocidad.text = "+ "+buffSpeed+" +";
    179.  
    180.  
    181.         if (Input.GetKey(KeyCode.N))
    182.         {
    183.             GameObject clonflecha = PhotonNetwork.Instantiate("flecha", playerBody.transform.position, playerBody.transform.rotation);
    184.             clonflecha.GetComponent<Proyectil>().creador = gameObject;
    185.             clonflecha.GetComponent<Proyectil>().velocidad = clonflecha.GetComponent<Proyectil>().velocidad;
    186.         }
    187.  
    188.     }
    189.  
    190.     public void getDmg(float dmg)
    191.     {
    192.         this.health -= dmg;
    193.     }
    194.  
    195.     public void setSpeed(float setspeed)
    196.     {
    197.         this.buffSpeed = setspeed;
    198.     }
    199.  
    200.     public void addSpeed(float addspeed)
    201.     {
    202.  
    203.         this.buffSpeed = buffSpeed + addspeed;
    204.  
    205.  
    206.     }
    207.  
    208.     public void substractSpeed(float subsSpeed)
    209.     {
    210.         Debug.Log("Reduciendo velocidad en " + subsSpeed);
    211.         this.buffSpeed = buffSpeed - subsSpeed;
    212.     }
    213.  
    214.     public void setHealth(float setHealth)
    215.     {
    216.         health = setHealth;
    217.     }
    218.  
    219.     public void addHealth(float addHealth)
    220.     {
    221.         health = health + addHealth;
    222.     }
    223.  
    224.     public void setArmor(float setArmor)
    225.     {
    226.         armor = setArmor;
    227.     }
    228.  
    229.     public void addArmor(float addArmor)
    230.     {
    231.         armor = armor + addArmor;
    232.     }
    233.  
    234.     public void addAttackSpeed(float addAttackSpeed)
    235.     {
    236.         myPowerUps.attackSpeedTim = myPowerUps.attackSpeedTim - addAttackSpeed;
    237.     }
    238.  
    239.     public void setAttackSpeed(float setAttackSpeed)
    240.     {
    241.         myPowerUps.attackSpeedTim = setAttackSpeed;
    242.     }
    243.  
    244.     public void addAutoHeal(float addAutoHeal)
    245.     {
    246.  
    247.     }
    248.  
    249.     public void setAutoHeal(float setAutoHeal)
    250.     {
    251.  
    252.     }
    253.  
    254.  
    255.  
    256.     bool isPlaying(Animator anim, string stateName)
    257.     {
    258.         if (anim.GetCurrentAnimatorStateInfo(0).IsName(stateName) &&
    259.                 anim.GetCurrentAnimatorStateInfo(0).normalizedTime < 1f)
    260.             return true;
    261.         else
    262.             return false;
    263.     }
    264.  
    265.  
    266.     public void AddDebuff(Debuff debuff)
    267.     {
    268.         Debug.Log("Entrando");
    269.         Debug.Log("1 " + debuff.GetType().ToString());
    270.         bool exist = false;
    271.  
    272.         foreach (Debuff item in debuffs)
    273.         {
    274.             Debug.Log("2 " + item.GetType().ToString());
    275.             if (item.GetType() == debuff.GetType())
    276.             {
    277.                 Debug.Log("Ya existe");
    278.                 exist = true;
    279.             }
    280.         }
    281.  
    282.  
    283.         if (!exist)
    284.         {
    285.             debuffs.Add(debuff);
    286.             Debug.Log("Añadiendo Debuff");
    287.             Debug.Log(debuffs.Count);
    288.         }
    289.  
    290.     }
    291.  
    292.  
    293.  
    294.  
    295.     private void HandleDebuffs()
    296.     {
    297.         if(debuffs.Count != 0)
    298.         {
    299.             int i = 0;
    300.             foreach(Debuff debuff in debuffs)
    301.             {
    302.                 i++;
    303.                 Debug.Log("There's " +i);
    304.                  
    305.             }
    306.         }
    307.  
    308.         foreach (Debuff debuff in debuffs)
    309.         {
    310.             Debug.Log("-------------- HandleDebuffs FOREACH -----------");
    311.             debuff.Update();
    312.         }
    313.     }
    314.  
    315.  
    316.  
    317.  
    318.     //public void CameraControl()
    319.     //{
    320.  
    321.     //    if (Input.GetKeyDown(KeyCode.Space))
    322.     //    {
    323.     //            centered = !centered;
    324.     //    }
    325.  
    326.     //    Vector3 camPos = cam.position;
    327.  
    328.     //    if (!centered)
    329.     //    {
    330.  
    331.     //        if (Input.mousePosition.x >= Screen.width - borderThickness)
    332.     //        {
    333.     //            camPos.x = cam.position.x + (normalSpeed / 50);
    334.     //            cam.position = camPos;
    335.     //        }
    336.  
    337.     //        if (Input.mousePosition.x <= borderThickness)
    338.     //        {
    339.     //            camPos.x = cam.position.x - (normalSpeed / 50);
    340.     //            cam.position = camPos;
    341.     //        }
    342.  
    343.     //        if (Input.mousePosition.y >= Screen.height - borderThickness)
    344.     //        {
    345.  
    346.     //            camPos.z = cam.position.z + (normalSpeed / 50);
    347.     //            cam.position = camPos;
    348.     //        }
    349.  
    350.     //        if (Input.mousePosition.y <= borderThickness)
    351.     //        {
    352.     //            camPos.z = cam.position.z - (normalSpeed / 50);
    353.     //            cam.position = camPos;
    354.     //        }
    355.     //    }
    356.  
    357.     //    if (centered)
    358.     //    {
    359.     //        Vector3 targetPos = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y + distance, gameObject.transform.position.z - 6);
    360.     //        cam.position = targetPos;
    361.     //    }
    362.  
    363.     //}
    364.  
    365.  
    366.  
    367.     //public void Attacking()
    368.     //{
    369.  
    370.     //    StartCoroutine(AttackRoutine());
    371.     //}
    372.  
    373.     //IEnumerator AttackRoutine()
    374.     //{
    375.  
    376.     //    Debug.Log("Antes coroutine");
    377.     //    yield return new WaitForSeconds(1);
    378.     //}
    379.  
    380. }
    381.  
    382.  
    Player powerUps code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Photon.Pun;
    5. using System;
    6. using UnityEngine.UI;
    7.  
    8. public class powerUps : Photon.Pun.MonoBehaviourPun
    9. {
    10.     public bool bow;
    11.     public bool speed;
    12.     public bool autoheal;
    13.     public bool trees;
    14.     public bool attackSpeed;
    15.  
    16.  
    17.     public float timerBow;
    18.     public float attackSpeedTim;
    19.  
    20.     public GameObject flecha;
    21.     public GameObject projectileSpawner;
    22.     public float proyectilSpeed;
    23.  
    24.     public float autohealTimer;
    25.     public float autohealDelay;
    26.     public float autohealAmount;
    27.  
    28.     public Text log;
    29.  
    30.     Player player;
    31.  
    32.     GameObject PlayerBody;
    33.  
    34.  
    35.     // Start is called before the first frame update
    36.     void Start()
    37.     {
    38.         bow = false;
    39.         speed = false;
    40.         autoheal = false;
    41.         trees = false;
    42.         attackSpeed = false;
    43.         proyectilSpeed = 1f;
    44.         attackSpeedTim = 1.5f;
    45.         autohealDelay = 5;
    46.         autohealAmount = 2;
    47.  
    48.         player = gameObject.GetComponent<Player>();
    49.         PlayerBody = player.playerBody;
    50. }
    51.  
    52.     // Update is called once per frame
    53.     void Update()
    54.     {
    55.         //BOW
    56.         if (player.PlayerOn)
    57.         {
    58.             if (bow)
    59.             {
    60.                 if (timerBow < attackSpeedTim)
    61.                 {
    62.                     timerBow += Time.deltaTime;
    63.  
    64.                 }
    65.                 else
    66.                 {
    67.  
    68.                     if (Input.GetMouseButton(0))
    69.                     {
    70.                         if (timerBow >= attackSpeedTim)
    71.                         {
    72.  
    73.                             AtacarBow();
    74.  
    75.                         }
    76.                     }
    77.                 }
    78.             }
    79.  
    80.             if (autoheal)
    81.             {
    82.  
    83.                 if (autohealTimer <= autohealDelay)
    84.                 {
    85.                     autohealTimer += Time.deltaTime;
    86.                 }
    87.                 else
    88.                 {
    89.                     if (player.health <= 100)
    90.                     {
    91.                         player.addHealth(autohealAmount);
    92.                         autohealTimer = 0;
    93.                     }
    94.                 }
    95.  
    96.             }
    97.  
    98.             if (Input.GetKeyDown(KeyCode.H))
    99.             {
    100.                 player.addHealth(-90);
    101.             }
    102.         }
    103.  
    104.      
    105.  
    106.  
    107.  
    108.  
    109.     }
    110.  
    111.  
    112.  
    113.     void AtacarBow()
    114.     {
    115.         Quaternion rotation = PlayerBody.transform.rotation;
    116.         this.GetComponent<PhotonView>().RPC("spawnShot", RpcTarget.AllBuffered, flecha.name, projectileSpawner.transform.position, rotation);
    117.  
    118.  
    119.         timerBow = 0;
    120.     }
    121.  
    122.     public float getProyectilSpeed()
    123.     {
    124.         return proyectilSpeed;
    125.     }
    126.  
    127.     public void setProyectilSpeed()
    128.     {
    129.  
    130.     }
    131.  
    132.     [PunRPC]
    133.     void spawnShot(String name, Vector3 position, Quaternion rotation)
    134.     {
    135.         GameObject clonflecha = PhotonNetwork.Instantiate(flecha.name, projectileSpawner.transform.position, rotation, 0);
    136.         clonflecha.GetComponent<Proyectil>().creador = gameObject;
    137.         clonflecha.GetComponent<Proyectil>().velocidad = clonflecha.GetComponent<Proyectil>().velocidad + proyectilSpeed;
    138.         log.text += "\nRECIBIDO";
    139.         PlayerBody.transform.position = new Vector3(70, 18, 70);
    140.     }
    141.  
    142. }
     
  4. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,735
    Is it possible that there is collision code running on the remote client missile/player scripts that is causing the missiles to be destroyed as soon as they are instantiated by the RPC, possibly because of a collision between the missile and the player object?
     
  5. Nightm4reProds

    Nightm4reProds

    Joined:
    Oct 11, 2017
    Posts:
    7
    To be honest, I dont know if that was the problem but I solved it accidentally I think. I'll post the codes now so you can see the differences and to help who has the same problem as me.

    Bullet script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class Proyectil : MonoBehaviour {
    7.  
    8.     public float velocidad = 15f;
    9.     public float dmg = 30f;
    10.     public GameObject creador;
    11.     Collider me, creator;
    12.  
    13.     Text log;
    14.  
    15.     // Use this for initialization
    16.  
    17.     private void Awake()
    18.     {
    19.        
    20.        
    21.     }
    22.  
    23.     void Start () {
    24.         me = gameObject.GetComponent<Collider>();
    25.         creator = creador.GetComponentInChildren<Collider>();
    26.         IgnoraCollision();
    27.  
    28.         log = GameObject.FindGameObjectWithTag("text").GetComponent<Text>();
    29.     }
    30.    
    31.     // Update is called once per frame
    32.     void Update () {
    33.  
    34.  
    35.        
    36.         gameObject.transform.Translate(Vector3.forward * velocidad * Time.deltaTime);
    37.  
    38.  
    39.     }
    40.  
    41.     private void OnCollisionEnter(Collision collision)
    42.     {
    43.         log.text+= "\n COLISION";
    44.         if (collision.gameObject != creador)
    45.         {
    46.             if (collision.gameObject.CompareTag("Player"))
    47.             {
    48.                 collision.gameObject.GetComponentInParent<Player>().getDmg(dmg);
    49.                 Debug.Log("AETIOAETAEIOTRAETNRAENTROEAN");
    50.                 ApplyDebuff(collision.gameObject.GetComponentInParent<Player>());
    51.             }
    52.             Destroy(gameObject);
    53.         }
    54.  
    55.     }
    56.  
    57.     private void IgnoraCollision()
    58.     {
    59.         Physics.IgnoreCollision(me, creator, true);
    60.  
    61.     }
    62.  
    63.     private void ApplyDebuff(Player player)
    64.     {
    65.         Debug.Log("Entrando ApplyDebuff proyectil");
    66.         player.AddDebuff(new SlowDebuff(player));
    67.     }
    68.  
    69.  
    70. }
    PowerUp script
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Photon.Pun;
    5. using System;
    6. using UnityEngine.UI;
    7.  
    8. public class powerUps : Photon.Pun.MonoBehaviourPun
    9. {
    10.     public bool bow;
    11.     public bool speed;
    12.     public bool autoheal;
    13.     public bool trees;
    14.     public bool attackSpeed;
    15.  
    16.  
    17.     public float timerBow;
    18.     public float attackSpeedTim;
    19.  
    20.     public GameObject flecha;
    21.     public GameObject projectileSpawner;
    22.     public float proyectilSpeed;
    23.  
    24.     public float autohealTimer;
    25.     public float autohealDelay;
    26.     public float autohealAmount;
    27.  
    28.     public Text log;
    29.  
    30.     Player player;
    31.  
    32.     GameObject PlayerBody;
    33.  
    34.  
    35.     // Start is called before the first frame update
    36.     void Start()
    37.     {
    38.         bow = false;
    39.         speed = false;
    40.         autoheal = false;
    41.         trees = false;
    42.         attackSpeed = false;
    43.         proyectilSpeed = 1f;
    44.         attackSpeedTim = 1.5f;
    45.         autohealDelay = 5;
    46.         autohealAmount = 2;
    47.  
    48.         player = gameObject.GetComponent<Player>();
    49.         PlayerBody = player.playerBody;
    50.  
    51.         log = GameObject.FindGameObjectWithTag("text").GetComponent<Text>();
    52.     }
    53.  
    54.     // Update is called once per frame
    55.     void Update()
    56.     {
    57.         //BOW
    58.         if (player.PlayerOn)
    59.         {
    60.             if (bow)
    61.             {
    62.                 if (timerBow < attackSpeedTim)
    63.                 {
    64.                     timerBow += Time.deltaTime;
    65.  
    66.                 }
    67.                 else
    68.                 {
    69.  
    70.                     if (Input.GetMouseButton(0))
    71.                     {
    72.                         if (timerBow >= attackSpeedTim)
    73.                         {
    74.  
    75.                             AtacarBow();
    76.  
    77.                         }
    78.                     }
    79.                 }
    80.             }
    81.  
    82.             if (autoheal)
    83.             {
    84.  
    85.                 if (autohealTimer <= autohealDelay)
    86.                 {
    87.                     autohealTimer += Time.deltaTime;
    88.                 }
    89.                 else
    90.                 {
    91.                     if (player.health <= 100)
    92.                     {
    93.                         player.addHealth(autohealAmount);
    94.                         autohealTimer = 0;
    95.                     }
    96.                 }
    97.  
    98.             }
    99.  
    100.             if (Input.GetKeyDown(KeyCode.H))
    101.             {
    102.                 player.addHealth(-90);
    103.             }
    104.         }
    105.  
    106.        
    107.  
    108.  
    109.  
    110.  
    111.     }
    112.  
    113.    
    114.  
    115.     void AtacarBow()
    116.     {
    117.         Quaternion rotation = PlayerBody.transform.rotation;
    118.         //this.GetComponent<PhotonView>().RPC("spawnShot", RpcTarget.AllBuffered, flecha.name, projectileSpawner.transform.position, rotation);
    119.         spawnShotv2(projectileSpawner.transform.position, rotation);
    120.  
    121.         timerBow = 0;
    122.     }
    123.  
    124.     public float getProyectilSpeed()
    125.     {
    126.         return proyectilSpeed;
    127.     }
    128.  
    129.     public void setProyectilSpeed()
    130.     {
    131.  
    132.     }
    133.  
    134.     //[PunRPC]
    135.     //void spawnShot(String name, Vector3 position, Quaternion rotation)
    136.     //{
    137.     //    GameObject clonflecha = PhotonNetwork.Instantiate(flecha.name, projectileSpawner.transform.position, rotation, 0);
    138.     //    clonflecha.GetComponent<Proyectil>().creador = gameObject;
    139.     //    clonflecha.GetComponent<Proyectil>().velocidad = clonflecha.GetComponent<Proyectil>().velocidad + proyectilSpeed;
    140.     //    log.text += "\nRECIBIDO";
    141.     //    PlayerBody.transform.position = new Vector3(70, 18, 70);
    142.     //}
    143.  
    144.     void spawnShotv2(Vector3 position, Quaternion rotation)
    145.     {
    146.         GameObject clonflecha = PhotonNetwork.Instantiate(flecha.name, projectileSpawner.transform.position, rotation, 0);
    147.         clonflecha.GetComponent<Proyectil>().creador = gameObject;
    148.         clonflecha.GetComponent<Proyectil>().velocidad = clonflecha.GetComponent<Proyectil>().velocidad + proyectilSpeed;
    149.         log.text += "\nRECIBIDO";
    150.         PlayerBody.transform.position = new Vector3(70, 18, 70);
    151.     }
    152.  
    153. }
    154.  
     
  6. Foestar

    Foestar

    Joined:
    Aug 12, 2013
    Posts:
    350
    I'm thinking that's exactly what was happening here. An RPC sent out to all clients will execute that on all clients immediately. That means the host and the clients are doing this at once. The host's instant, while latency may slow down the clients along with when the buffered package is received. But if they are all going off at the same time then they may be hitting each other or something. Instantiating your bullet in a single client could fix that, which it looks like you did in the second code.

    I haven't read through it all, but that's just a rough guess. Also, a good practice when using PUN 2 I personally feel is to utilize the "IsMine" or "IsMasterClient" features. These both can be very useful. You use both like so:

    Code (CSharp):
    1. //this one requires a photon view on the object
    2. //you are checking
    3. if (this.GetComponent<PhotonView>().IsMine){
    4.  
    5. }
    6.  
    7. //and
    8.  
    9. if (PhotonNetwork.IsMasterClient){
    10.  
    11. }