- Home /
How do I stop unnecessary nullreferencexceptions from printing?
I have a script for my zombie enemies that detects which body parts have been destroyed, produces an instantiate of that body part, and keeps from checking again. It was tedious to set up and calls each part by name but it works smoothly and without any lag or real problems and successfully changes the animation states to crawling, falling, etc. The issue becomes that the spawn points for these parts have to move with the bones so they are inside of them, and when the part is destroyed so is the spawn, which is good. However if say you blast off the right hand, and the hand shoots out, and then later blast off the right elbow or whatever bone part is next up the line since the spawn or connected bones for that arm is no longer there it throws a nullreferenceexception. I want that to be a null reference, and I'm glad it comes back as such or the code wouldn't work but I don't need to see it in my debug everytime. I've tried using else null; commands and cant seem to figure out how to get the darn thing to stop stating the obvious, which is if you dont have a right elbow then of course you wont have a right hand either so on and so forth. I suppose its not a problem with functionality it just creates a messy debug log.
This is an example of the full to partial right arm detection and body part creation portion of the AI script, others run to check if there is still hands/elbows to determine which model to instantiate. Is there something obviously wrong in how I've arranged it? I've only been using unity for a couple weeks so a lot of it is new to me and I'm sure its glaring me in the face.
if(rarm)
{
var rarmcheck = transform.Find("Armature/Root/Bone_001/MidSpine/Bone_003/Bone_003_R/RightElbow");
if(!rarmcheck)
{
rarm = false;
if(!rarm && !rhand && !relb)
{
var ras = Instantiate(ram,transform.Find("Armature/Root/Bone_001/MidSpine/Bone_003/Bone_003_R/raspawn").transform.position, Quaternion.identity);
ras.transform.Rotate(20, 10, 10);
ras.rigidbody.velocity = ras.transform.down * 2;
//only bicep
}
if(!rarm && !rhand && relb )
{
var raes = Instantiate(raem,transform.Find("Armature/Root/Bone_001/MidSpine/Bone_003/Bone_003_R/raspawn").transform.position, Quaternion.identity);
raes.transform.Rotate(20, 10, 10);
raes.rigidbody.velocity = raes.transform.down * 2;
//bicep elbow and hand
}
if(!rarm && rhand && relb)
{
var raehs = Instantiate(raehm,transform.Find("Armature/Root/Bone_001/MidSpine/Bone_003/Bone_003_R/raspawn").transform.position, Quaternion.identity);
raehs.transform.Rotate(20, 10, 10);
raehs.rigidbody.velocity = raehs.transform.down * 2;
//whole arm
}
}
Any help or suggestions would be much appreciated, and if it really is a non issue then that would be great to hear as well since it seems as such.
Answer by Armored13 · Jan 26, 2014 at 12:14 PM
Second result from googling "javascript ignore nullreferenceexception": Tell JavaScript To Ignore NullReferenceException?
As noted in some of the comments of that question, ignoring the exception isn't the best practice out there. Even if you have to rebuild parts, it would be safer and build better habits if you found the specific cause.
I read that post as well? I know the specific cause, by the time the script has realized that the body part is missing and updates its boolean value to false for specific piece not being there anymore its already started another check before it can update itself it seems. The other response states what I've already done, the rhand, relb, rarm and so forth should keep it from checking those objects since there's one for each part that exists but it doesnt. Is this an issue that moving the checks into lateupdate or fixedupdate might resolve?
I would start by cleaning up your if structure a bit. Your three '!rarm' are fluff and you can remove all of them. You could also turn the structure from a bunch of 'if' statements into an 'if/else' structure.
Does it throw exceptions during the if statement or during the instantiation of ras/raes/raehs?
@eklumt: No, any changes to the hierarchy are executed immediately. It might help to know the line where the null ref occurs. You should never ignore a exception. An exception forcefully interrupts the execution of a function at the point it occurs. Everything that comes after that point isn't executed.
You just check if "RightElbow" is there but in the end you access another gameobject which seems to be a sibling of the "RightElbow". Are you sure you don't destroy the attachpoint and keep the elbow?
Debugging is an interactive process. You have to figure out where the error happens in order to figure out why it happens to finally be able to prevent the error.
It only seems to do it during the next update during the next body check portion that happens after/before the instantiate. I guess I could group the !larm and other major groupings into one if statement prior to the individual check and instantiate but the individual checks should keep it from checking anyway so I must have something on backwards. Were I to convert this into an if/else setup what is typically set as the return function for else where it comes back null, can it just be left blank?
In this it will be fine as an if/elseif/elseif. No need here to add on a final else. It likely isn't going to be a noticeable change, just good practice and can be easier to tell how code is being executed.
Answer by aliakbo · Jan 26, 2014 at 12:13 PM
Check if objects exists before you use them.
if('object causing null reference')
'object causing null reference'.Use();
Answer by eklumt · Jan 26, 2014 at 01:57 PM
I figured it out! Its a combination of trying to check from grandchild to child, not having elseifs inside the main bodycheck groupings, and that when it does the individual checks for the hand etc, it should also check if there is an arm and an elbow, other wise its redundant and will come back null but only once because the other checks are working and it will still work because the spawns are destroyed anyway. Larm, or rarm, or lleg or rleg checks are always going to be fine because they are holding the other parts so the individual checks were really just running redundantly. Testing has shown this is the reason so thank you everyone for your help you've made this a lot easier.