RPC - Null Reference Exception

Hi,

I'm new to this forum so if I mess any formatting up please do say. :smile:

Anyways, currently I'm using PUN 2.0 on Unity 2018.3.0f2 and I ran into a problem with an RPC call.

The gist of what I'm trying to do is I have a plane that can bomb cars using missiles, and I need to synchronize the missiles across all clients.
The way I've chosen to do this is to have the missile be unnetworked, to save some bandwidth. Instead, I use an RPC call to instantiate a unnetworked prefab of the missile on each client with the same target, speed, etc. In order to handle collision damage, the player that gets hit by it's own local missile will take that damage.

The problem is, whenever I hit the key "e", the missile doesn't launch and instead this error code is produced in the console:

Here's the error.
NullReferenceException: Object reference not set to an instance of an object
Photon.Pun.PhotonNetwork.ExecuteRpc (ExitGames.Client.Photon.Hashtable rpcData, Photon.Realtime.Player sender) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:502)
Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, Photon.Realtime.Player player, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:1060)
Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2723)
Photon.Pun.PhotonView.RPC (System.String methodName, Photon.Pun.RpcTarget target, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonView.cs:410)
WeaponManager.Update () at Assets/Scripts/WeaponManager.cs:92
The code at WeaponManager.cs:92 is my RPC call:
photonView.RPC("LaunchMissile", RpcTarget.All);
For context, here's WeaponManager.cs:92 with surrounding code:
if (Input.GetKeyDown("e"))
        {
            if (FindClosestTarget(GetVisibleGameObjects()) != null)
            {
                Debug.Log(GetVisibleGameObjects().Count);
                // Launch missile on all clients
                Debug.Log(photonView);
                photonView.RPC("LaunchMissile", RpcTarget.All);
                AudioSource.PlayClipAtPoint(missileLaunchSound, transform.position);
        }
    }
And.. the RPC method (also in WeaponManager.cs) is:
    [PunRPC]
    void LaunchMissile(PhotonMessageInfo info)
    {
        Debug.Log(" LAUNCHING!");
        // Create Missile
        GameObject _missile = Instantiate(missile, transform.position - new Vector3(0, 4), transform.rotation);
        _missile.GetComponent<Homing>().SetOwner(info.photonView);

        // Gather target and missile ids.
        //int targetViewID = FindClosestTarget(GetVisibleGameObjects()).GetComponent<PhotonView>().ViewID;
        GameObject target = FindClosestTarget(GetVisibleGameObjects());
        //int missileViewID = _missile.GetComponent<PhotonView>().ViewID;

        _missile.GetComponent<Homing>().Fire(target);
    }
In WeaponManager.cs, photonView is referenced in the start method:
photonView = GetComponentInParent<PhotonView>();
I've been trying to fix this for a couple days now, so any help is greatly appreciated!
:smile:

Best Answer

  • JohnTube
    JohnTube ✭✭✭✭✭
    Answer ✓
    Hi @howdyydwoh,

    I think we overlooked a simple thing all this time all of us.
    By design, the script that has the RPC methods needs to be attached to the exact same GameObject as the PhotonView not its parent nor its child.
    Sorry for the inconvenience.

Answers

  • Will_C
    Will_C
    edited May 2019
    Im not too sure, as i just woke up , and i havent had my coffee yet, but at a quick glance, the first thing that pops out at me is, ... you invoke the rpc here ...

    photonView.RPC("LaunchMissile", RpcTarget.All);

    there is no arguements passed through (or to) this method. But then here... where you declare your rpc method...

    void LaunchMissile(PhotonMessageInfo info)

    you have a PhotonMessageInfo parameter... try removing that parameter and see what happens. If you need to locate the exact object across all players, maybe send the ViewID across as a parameter.

    photonView.RPC("LaunchMissile", RpcTarget.All, _photonView.viewID);

    and then ...

    void LaunchMissile(int _viewID) {etc...}

    Actually, im sure that wont be the issue , as MessageInfo is an implied reliable parameter, from what i can see in the docs, so, it must have something to do with your Object management and script. Sorry i cant help more mate. Too new myself. :P
  • howdyydwoh
    edited May 2019
    Hey Will,

    Just woke up myself, I feel you. :#

    After removing the PhotonMessageInfo info argument, the method now looks like this:
        [PunRPC]
        void LaunchMissile()
        {
            Debug.Log(" LAUNCHING!");
            // Create Missile
            GameObject _missile = Instantiate(missile, transform.position - new Vector3(0, 4), transform.rotation);
            //_missile.GetComponent<Homing>().SetOwner(info.photonView);
    
            // Gather target and missile ids.
            //int targetViewID = FindClosestTarget(GetVisibleGameObjects()).GetComponent<PhotonView>().ViewID;
            GameObject target = FindClosestTarget(GetVisibleGameObjects());
            //int missileViewID = _missile.GetComponent<PhotonView>().ViewID;
    
            _missile.GetComponent<Homing>().Fire(target);
        }
    
    Unfortunately, the error persists:
    NullReferenceException: Object reference not set to an instance of an object
    Photon.Pun.PhotonNetwork.ExecuteRpc (ExitGames.Client.Photon.Hashtable rpcData, Photon.Realtime.Player sender) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:502)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, Photon.Realtime.Player player, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:1060)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2723)
    Photon.Pun.PhotonView.RPC (System.String methodName, Photon.Pun.RpcTarget target, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonView.cs:410)
    WeaponManager.Update () (at Assets/Scripts/WeaponManager.cs:92)
    
    Also, I think that PhotonMessageInfo is automatically included in the remote call, as told by the API reference.
    The last parameter of a RPC method can be of type PhotonMessageInfo, which will provide the context for each call. You don't set the PhotonMessageInfo in the call.

    Anyways, including PhotonMessageInfo or removing PhotonMessageInfo in the remote method both render the same error, so I'm perplexed.

    Thanks for your help nevertheless! :)

    Anyone else have any suggestions?
  • Update -

    With some trial and error I think I deciphered the error text.

    When I invoke the RPC with the correct method name:
    photonView.RPC("LaunchMissile", RpcTarget.All);
    I get this error:
    NullReferenceException: Object reference not set to an instance of an object
    Photon.Pun.PhotonNetwork.ExecuteRpc (ExitGames.Client.Photon.Hashtable rpcData, Photon.Realtime.Player sender) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:502)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, Photon.Realtime.Player player, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:1060)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2723)
    Photon.Pun.PhotonView.RPC (System.String methodName, Photon.Pun.RpcTarget target, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonView.cs:410)
    WeaponManager.Update () (at Assets/Scripts/WeaponManager.cs:92)
    And, when I invoke the RPC with a random non-existent method name, say "oogabooga"
    photonView.RPC("oogabooga", RpcTarget.All);
    I get the exact same error code:
    NullReferenceException: Object reference not set to an instance of an object
    Photon.Pun.PhotonNetwork.ExecuteRpc (ExitGames.Client.Photon.Hashtable rpcData, Photon.Realtime.Player sender) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:502)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, Photon.Realtime.Player player, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetworkPart.cs:1060)
    Photon.Pun.PhotonNetwork.RPC (Photon.Pun.PhotonView view, System.String methodName, Photon.Pun.RpcTarget target, System.Boolean encrypt, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonNetwork.cs:2723)
    Photon.Pun.PhotonView.RPC (System.String methodName, Photon.Pun.RpcTarget target, System.Object[] parameters) (at Assets/Photon/PhotonUnityNetworking/Code/PhotonView.cs:410)
    WeaponManager.Update () (at Assets/Scripts/WeaponManager.cs:92)
    This leads me to believe that somehow the LaunchMissile method:
        [PunRPC]
        void LaunchMissile()
        {
            Debug.Log(" LAUNCHING!");
            // Create Missile
            GameObject _missile = Instantiate(missile, transform.position - new Vector3(0, 4), transform.rotation);
            // Get Target
            GameObject target = FindClosestTarget(GetVisibleGameObjects());
            // Fire with Target
            _missile.GetComponent<Homing>().Fire(target);
        }
    is not being recognized by PUN. Anyways, that's my best guess.

    It's also worth noting that this code is in WeaponManager.cs. WeaponManager.cs is placed on "Gun" gameobject which is under a parent game object- the plane. The plane is the object that has the Photon View component.
    So in order for WeaponManager.cs to get the Photon View component in order to invoke the LaunchMissile method, I referenced Photon View in WeaponManager.cs:62:
    photonView = GetComponentInParent<PhotonView>();
    Anyways, it's all a mess and I don't understand why PUN isn't recognizing my remote method.

    Any suggestions or comments are appreciated! :smile:
  • JohnTube
    JohnTube ✭✭✭✭✭
    Hi @howdyydwoh,

    Thank you for choosing Photon!

    Is this related?
  • howdyydwoh
    edited May 2019
    Hey @JohnTube,

    Yes, that's exactly what's happening, except, I'm putting in a valid method name in the rpc invocation code:
    photonView.RPC("LaunchMissile", RpcTarget.All);
    It's as if PUN is treating the method "LaunchMissile" as if it weren't there.

    Thanks for the response.
  • If you use PUN 2.0, please update to v2.12. Do this first.

    Next: Check if the PhotonServerSettings inspector shows the RPCs and if yours is listed there.
    PUN 2 requires you to register components, that get RPC callbacks. Make sure this happened.

    If none helps: Please debug the line that has the NullRef exception to figure out which value is null. Either you attach the debugger and reproduce the issue (then VS will break and show you all values) or you Debug.Log() each value individually (to see which one is null).

    Then we can help.
  • howdyydwoh
    edited May 2019
    Hey @Tobias,

    Thanks for the response.

    I've updated PUN to the latest version. According to the release history i'm at Version 4.1.2.14 (6. May 2019 - rev5088), error persists.

    The PhotonServerSettings does show the LaunchMissile RPC.

    As for "registering components that get RPC callbacks", i'm not quite sure what you mean by that.

    The Nullref exception is from the line PhotonNetworkPart.cs:506:

    for (int index = 0; index < argumentsTypes.Length; index++)

    Here's the context of that line:
                // Error handling
                if (receivers != 1)
                {
                    string argsString = string.Empty;
                    for (int index = 0; index < argumentsTypes.Length; index++)
                    {
                        Type ty = argumentsTypes[index];
                        if (argsString != string.Empty)
                        {
                            argsString += ", ";
                        }
    
                        if (ty == null)
                        {
                            argsString += "null";
                        }
                        else
                        {
                            argsString += ty.Name;
                        }
                    }
    And here's the debug code generated from PhotonNetworkPart.cs:506:
    
    		netViewID	7002	System.Int32
    		otherSidePrefix	0	System.Int32
    		inMethodName	"LaunchMissile"	System.String
    		arguments	null	System.Object[]
    +		photonNetview	"View 7002 on AircraftJet(Clone) "	Photon.Pun.PhotonView
    		argumentsTypes	null	System.Type[]
    		receivers	0	System.Int32
    		foundMethods	0	System.Int32
    		argsString	""	System.String
    		index	0	System.Int32
    +		rpcData	"(System.Byte)0=(System.Int32)7002, (System.Byte)2=(System.Int32)2067285223, (System.Byte)5=(System.Byte)4"	ExitGames.Client.Photon.Hashtable
    +		sender	"7 {}"	Photon.Realtime.Player
    
    So weird. PhotonServerSettings shows LaunchMissile as a valid RPC, but according to that debug code, foundMethods = 0.

    So confused.
  • Hi howdyydwoh, i had the exact same problem today, and it was caused by my method being private like yours, while i was trying to call the RPC from an inherited class. Try putting the method "LaunchMissile" public to see if that was the problem.
  • howdyydwoh
    edited June 2019
    Hi @Mati36,

    Thanks for your response.

    I changed my LaunchMissile method from
        [PunRPC]
        void LaunchMissile()
    to this:
        [PunRPC]
        public void LaunchMissile()
    Unfortunately, the error persists. Thanks for your suggestion nevertheless!

    If anyone else has any ideas, they're welcome to pitch in. Frankly, i'm at a loss. :neutral:
  • I have this same issue .. if you fix it lmk what you did!
  • @LucaBrasi sure thing, i'll make sure to dm you if I get the answer to this problem.
  • Please implement the RPC method "LaunchMissile" in a minimal sample class that reproduces the issue. Then send / paste the complete class.
  • howdyydwoh
    edited June 2019
    Hey @Tobias,

    To reproduce this issue on Unity 2018.3.0f2,

    1. Create a 3D Sphere in the resources folder.
    2. Add a Photon View component set as a fixed owner and unreliable on change on the 3D sphere.
    3. Add a Empty GameObject as a child under the 3D Sphere.
    4. Add WeaponManagerSample.cs as a component of the empty gameobject.

    WeaponManagerSample.cs:
    using Photon.Pun;
    using UnityEngine;
    
    public class WeaponManagerSample : MonoBehaviour
    {
    
        private PhotonView photonView;
    
        private void Start()
        {
            photonView = GetComponentInParent<PhotonView>();
        }
    
        // Update is called once per frame
        void Update()
        {
            if (Input.GetKeyDown("e") && photonView != null)
            {
                photonView.RPC("LaunchMissile", RpcTarget.All);
            }
        }
    
        [PunRPC]
        public void LaunchMissile()
        {
            Debug.Log("LAUNCHING!");
        }
    
    }
    5. Connect to a server, join a lobby, PhotonNetwork.Instantiate the 3D Sphere and try to press the "e" key.
    A null reference exception should pop up in the error log.
  • Thanks for those steps. I will give it a go asap but it still may be a day or two. Busy times at the moment but I'm on it.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Answer ✓
    Hi @howdyydwoh,

    I think we overlooked a simple thing all this time all of us.
    By design, the script that has the RPC methods needs to be attached to the exact same GameObject as the PhotonView not its parent nor its child.
    Sorry for the inconvenience.
  • Hey @JohnTube,

    Thanks! I swapped my WeaponManger script to the main gameobject with the photon view in it, and it worked!

    @Tobias,
    Even though I fixed my scenario, I still feel that being able to use remote methods which are children of the photonview gameobject should be a feature. Hopefully you could add that as one of the suggested features?

    Nevertheless, thanks everyone for helping me out! :smiley:
  • Good to read we could fix your case.

    Yes, being able to target child objects could be useful, I guess. It's more flexible for sure.
    I am shying away from enabling this, as it may be costly to traverse complex hierarchies at runtime instead of setting them up beforehand.
    But .. with an option to enable/disable this feature, it won't hurt.
  • happyrobot
    edited August 2019
    Ooh, this was helpful. My RPC functions that existed on childs of photontransformview were not working. Thanks for this thread

    Indeed, traversing heirachies at runtime seems ill-advised, however, a more helpful error than Null Ref Exception might be handy =)
  • jTeE
    jTeE
    edited March 2020
    Hiya, what does this mean for a gun script, containing Shoot(), while the photonview is attached to the player, where i have put RPCs for trigger hold an released?

    The gun is parented to an empty attached to the cam.

    I am new to this and think I have run into the same issue as above, but am not sure how to resolve, and the more i think about it the less sure i am on how to continue!

    edit : sorry answer - call shoot in player, weapon as a scriptable object for data to be used in the shoot function,