Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by donnysobonny · Aug 09, 2013 at 12:26 AM · photonhashtable

Strange nullReferenceError when dealing with Hashtables and Photon

Hey guys,

This one is a real mind bender, and i've been struggling with this for the past few days.

To keep this short, I'm building the foundations of a multiplayer game using Photon within Unity. Photon allows you to apply custom properties to certain server objects (such as a player or a "room") by passing a hashtable to the SetCustomProperties() method, which seems like a very useful tool. However this problem is disallowing me the ability to use this.

So, in order to make things more rigid, i'm trying to use objects instead of hashtables, and i've created a simple class to easily convert the object to a hashtable, and convert the hashtable to the object. Here is the basic class that for setting and getting the custom room properties:

 using UnityEngine;
 using System.Collections;
 
 public class PhotonRoomInformation {
     
     public string type = ""; //this will either be "quick" or "custom"
     public string status = ""; //this will be either "game" or "lobby"
     public int maxPlayers = 0;
     public int numPlayers = 0;
     
     public PhotonRoomInformation()
     {
         this.type = "";
         this.status = "";
         this.maxPlayers = 0;
         this.numPlayers = 0;
     }
     
     //get hashatable from the manually set parameters
     public Hashtable getHashTable()
     {
         Hashtable ht = new Hashtable();
         ht.Add("type",type);
         ht.Add("status",status);
         ht.Add("maxPlayers",maxPlayers);
         ht.Add("numPlayers",numPlayers);
         
         return ht;
     }
     
     //set the properties from a passed hashtable
     public void setProperties(Hashtable ht)
     {
         this.type = (string)ht["type"];
         this.status = (string)ht["status"];
         this.maxPlayers = (int)ht["maxPlayers"];
         this.numPlayers = (int)ht["numPlayers"];
     }
 }

Now, using the getHashTable() method works fine. I have tested this thoroughly by seeing what the server recieves and sends back. Everything matches up.

However, when I try to use the setProperties() method, by passing the customProperties hashtable of the room to the method, I get a null reference error.

Here is the part of code where I am trying to perform this method:

     //when the rooms properties have updated, check that the room is full. If so, we're ready to load the game
     void OnPhotonCustomRoomPropertiesChanged()
     {
         PhotonRoomInformation pri = new PhotonRoomInformation();
         pri.setProperties(PhotonNetwork.room.customProperties);
         
         //if the status is in game, load the level
         if(pri.status == "game")
         {
             print ("loading level!");
             PhotonNetwork.LoadLevel(quickMatchScene);
         }
     }

Which gives me this exact error: NullReferenceException: Object reference not set to an instance of an object PhotonRoomInformation.setProperties (System.Collections.Hashtable ht) (at Assets/Standard Assets/Scripts/Utilities/PhotonRoomInformation.cs:36) quickmatchMenu.OnPhotonCustomRoomPropertiesChanged () (at Assets/Standard Assets/Scripts/Menus/quickmatchMenu.cs:186)

Line 36 of PhotonRoomInformation.cs (the class shown in this post) is this:

this.maxPlayers = (int)ht["maxPlayers"];

Line 186 of quickmatchMenu.cs is part of the extract shown above:

pri.setProperties(PhotonNetwork.room.customProperties);

Any help would be greatly appreciated.

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ArkaneX · Aug 09, 2013 at 12:49 AM 0
Share

It seems the Hashtable passed to setProperties method doesn't contain "maxPlayers" key. In this case ht["maxPlayers"] returns null and converting it to an int causes exception.

To check what keys are available in your Hashtable, please paste this script at the begin of your setProperties method:

 foreach(var key in ht.$$anonymous$$eys)
 {
     Debug.Log(key + ": " + ht[key]);
 }

and check Unity log for output.

avatar image donnysobonny ArkaneX · Aug 09, 2013 at 12:53 AM 0
Share

Hey buddy, yeah this is something I did initially, as I thought the same thing.

That being said, just to be sure I've done as you asked and none of the values were returned as null:

type: quick

numPlayers: 1

maxPlayers: 2

status: lobby

That's the copied and pasted printed values.

avatar image donnysobonny ArkaneX · Aug 09, 2013 at 01:14 AM 0
Share

Could you possibly delete this answer and post it as a comment to my question?

It is marking this post as answered when it clearly is not answered. $$anonymous$$any thanks.

avatar image ArkaneX · Aug 09, 2013 at 01:28 AM 0
Share

Of course - converted (there is an option to convert question to comment and comment to question, so no need to delete).

And returning to your issue. If you can debug this script, then this would be the best option, because you can quickly discover what's going on. If you can't debug, then maybe ins$$anonymous$$d of:

 this.maxPlayers = (int)ht["maxPlayers"];

you can temporarily use

 var tmp1 = ht["maxPlayers"];
 Debug.Log(tmp1);
 Debug.Log(tmp1.GetType());
 var tmp2 = (int)tmp1;
 Debug.Log(tmp2);
 this.maxPlayers = tmp2;

I'm curious what the output will be...

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by donnysobonny · Aug 09, 2013 at 03:00 AM

This was a rather peculiar one, however with the help of @ArkaneX I was able to locate the problem.

Ultimately, Photon comes with an Enum method: OnPhotonCustomRoomPropertiesChanged() which is called when the properties of the room that you are in have changed. I was initially using this method to check the status of the room.

After using the debug script that @ArkaneX posted above, I realised that it looked as if the OnPhotonCustomRoomPropertiesChanged method was being called before the property changes were actually available to read, then again once the property changes were available. Because of the null value when the method was being called initially, it was causing problems with my script.

To fix this, I am now checking if any of the values of the passed HashTable are null, if so, I try again a short period after.

I will let Photon know of this, as I cannot imagine that this is intentional.

Thanks again for the help.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ArkaneX · Aug 09, 2013 at 07:44 AM 0
Share

I'm glad you found the issue :)

avatar image
1

Answer by tobiass · Aug 09, 2013 at 09:53 AM

First of all, I didn't run your code just yet but you do more work than necessary: Use the built-in (or "well-known") properties RoomInfo.playerCount and .maxPlayers.

If you want to sync the loaded level, you can use PhotonNetwork.LoadLevel() if you set PhotonNetwork.automaticallySyncScene to true for your app. This uses properties as well but you don't have to re-do the work.

For me, it looks like properties should be available in OnPhotonCustomRoomPropertiesChanged(), as I cache them first. It depends a bit on your workflow though.

Example: You test with 2 clients. The first creates the room and when it's in the room, it sets the properties. Depending on your timing, the second client might join the room before after it's created but before the props are set. I will have to test if the first call to OnPhotonCustomRoomPropertiesChanged is always done when the room is entered (no matter if there are actual custom props set).

In all cases, if the props are not set on create (and thus potentially not yet set when you join), you need to check for null. But you don't have to check them periodically, as we always call either OnPhotonCustomRoomPropertiesChanged or OnPhotonPlayerPropertiesChanged respectively.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image donnysobonny · Aug 10, 2013 at 12:32 AM 0
Share

Hey @tobias,

As always, I much appreciated your help.

Yeah, since originally posting this i've made quite a few changes to the program$$anonymous$$g of it all. I honestly don't know why I didn't use the playerCount and maxPlayers properties of the Room class... I guess I had a momentary moment of madness!

Anyways, co$$anonymous$$g back to this problem, I'll be honest and say that since I did the work-around by checking if the hashtable is null and rerunning the function until I get a populated hashtable, i've not bothered to go back and change it. However yeah, it does always make the call to OnPhotonCustomRoomPropertiesChanged twice. So I guess for some reason the joining of a room is triggering the change of it's properties (which would make sense...), and would pretty much guarantee that the properties wont be available on the first call if they have just been set and I am just picking them up within the first OnPhotonCustomRoomPropertiesChanged, particularly considering we're using hashtables here. =p

I would hate to leave the code this way, i'm not really a fan of work-arounds. If you do manage to fix this in a later patch so that it only makes a call to the OnPhotonCustomRoomPropertiesChanged when custom properties have actually been changed, or passed within the CreateRoom() method, please do stick a reply in here to let me and others know.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

16 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Overload methods of Hashtable using System and Photon namespaces 1 Answer

Photon.Inatantiated() player prefab loses control 1 Answer

Messages in Multiplayer 0 Answers

Instantiate then access component(s) 2 Answers

Photon- block instantiating problem 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges