VRCPlayerApi GetPosition and GetRotation can throw due to a null ref if checked shortly after the player leaves the world.
complete
FairlySadPanda
This one is hard to test, but has been seen a lot during Slaughter House development:
Storing a player's VRCPlayerApi object within a UdonBehaviour, then calling GetPosition or GetRotation shortly after the player has left the world, will throw due to a null pointer.
What's odd is that the VRCPlayerApi object is not null, and properties on the object are not set to null (such as display name). It looks like GetPosition and GetRotation are just unsafe calls during cleanup of a disconnected player.
The correct behaviour here should be to return the default values for Vector3/Quaternion if the player is in the process of being removed, rather than throwing due to a null pointer.
Log In
Tupper - VRChat Head of Community
complete
Momo the Monster
in progress
Momo the Monster
interested
Our approach to this is a new static method - IsValid(object o). You can pass any object into this method and it will return True or False. For VRCPlayerApi, we're specifically checking to see if the player is still in the room. For all other objects, it will work the same as a null check for now, but can be extended in the future to check for special cases like this.
Μerlin
Momo the Monster: It might make sense to make the
IsValid
method do a UnityEngine.Object
equality when used on UnityEngine.Object
types in addition to the VRCPlayerApi
handling. It's not apparent in the graph what the difference is between object equality and unity engine object equality so people are liable to choose the wrong one. However, this needs to be resolved first for it to be useful: https://vrchat.canny.io/vrchat-udon-closed-alpha-bugs/p/null-check-on-gameobject-will-throw-exception-if-the-gameobj-is-destroyedMomo the Monster
Μerlin: This is what I've got currently working for the IsValid method:
public static bool IsValid(object obj)
{
if (obj == null) return false;
if (obj is MonoBehaviour objMB && objMB == null) return false;
if (obj is IValidChecker objIV) return objIV.IsValid();
return true;
}
VRCPlayerApi implementes IValidChecker to ensure that Player is not null AND they are in the room. Tested for Players and existing GameObjects, I'll try it against a Destroyed GameObject as well.
Μerlin
Momo the Monster: MonoBehaviour does not capture basic Unity builtin component types like MeshRenderer and such, it's only user defined types for the most part. It also doesn't capture asset types which may be destroyed at runtime such as RenderTexture.