Null reference exception for a variable that's not actually null
Null reference exception for a variable that's not actually null
Having an issue with running a custom Lua script through dialogue. It will run properly the first time with no errors, but when I change scenes then return to the original, I get a null error for a variable in the method. The issue is that if I look at the inspector, the variable is not null. I can also manually run the same method through a UI button and it will run fine with no errors. It only runs into the problem when it's run through dialogue system. Thanks.
Re: Null reference exception for a variable that's not actually null
Hi,
Can you share the error message? If so, please click on the error in the Console window and press Ctrl+C to copy it to the clipboard. Then paste it into a reply.
If the error happens after changing scenes, keep in mind that the Dialogue Manager GameObject survives scene changes by default. If something in the scene points to the Dialogue Manager GameObject, or if the Dialogue Manager GameObject points to something in the scene, this reference will be broken after changing scenes. This is because the Dialogue Manager GameObject will still have a reference to the old version in the previous instance of the scene. Similarly, if something in the scene points to the Dialogue Manager, then it will have a reference to the newly-loaded instance of the Dialogue Manager, but that newly-loaded instance will be destroyed when the original Dialogue Manager arrives in the scene.
In addition, if you've put your script with Lua.RegisterFunction() on the Dialogue Manager, don't use OnDisable to unregister it. (See CustomLuaTemplate.cs for an example of how to handle it.)
Can you share the error message? If so, please click on the error in the Console window and press Ctrl+C to copy it to the clipboard. Then paste it into a reply.
If the error happens after changing scenes, keep in mind that the Dialogue Manager GameObject survives scene changes by default. If something in the scene points to the Dialogue Manager GameObject, or if the Dialogue Manager GameObject points to something in the scene, this reference will be broken after changing scenes. This is because the Dialogue Manager GameObject will still have a reference to the old version in the previous instance of the scene. Similarly, if something in the scene points to the Dialogue Manager, then it will have a reference to the newly-loaded instance of the Dialogue Manager, but that newly-loaded instance will be destroyed when the original Dialogue Manager arrives in the scene.
In addition, if you've put your script with Lua.RegisterFunction() on the Dialogue Manager, don't use OnDisable to unregister it. (See CustomLuaTemplate.cs for an example of how to handle it.)
Re: Null reference exception for a variable that's not actually null
Hi, thanks for the quick reply. The QuestController.cs is our script that's mainly for spawning quest spawning but includes our Luas for DialogueSytem in the scene. Line 202 that's throwing the error here is just a debug printing the name of the gameobject that's causing the null error. The variable is being passed in just before the Lua is run, so it certainly hasn't been destroyed as the error says. Here's the message:
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Object.get_name () (at <028e4d71153d4ed5ac6bee0dfc08aa3b>:0)
QuestController.PositionForDialogue () (at Assets/Scripts/QuestController.cs:202)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
Language.Lua.LuaMethodFunction.InvokeMethod (Language.Lua.LuaValue[] args) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaValue/LuaMethodFunction.cs:35)
UnityEngine.Debug:LogException(Exception)
Language.Lua.LuaMethodFunction:InvokeMethod(LuaValue[]) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaValue/LuaMethodFunction.cs:40)
Language.Lua.FunctionCall:Evaluate(LuaValue, LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Expr/FunctionCall.cs:41)
Language.Lua.PrimaryExpr:Evaluate(LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Expr/PrimaryExpr.cs:15)
Language.Lua.ExprStmt:Execute(LuaTable, Boolean&) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/ExprStmt.cs:11)
Language.Lua.Chunk:Execute(Boolean&) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/Chunk.cs:42)
Language.Lua.Chunk:Execute() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/Chunk.cs:15)
Language.Lua.LuaInterpreter:Interpreter(String, LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaInterpreter.cs:38)
PixelCrushers.DialogueSystem.Lua:RunRaw(String, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Wrapper/Lua Interpreter/Lua.cs:223)
PixelCrushers.DialogueSystem.Lua:Run(String, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Wrapper/Lua Interpreter/Lua.cs:129)
PixelCrushers.DialogueSystem.ConversationModel:GetState(DialogueEntry, Boolean, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Model/Logic/Model/ConversationModel.cs:234)
PixelCrushers.DialogueSystem.ConversationModel:GetState(DialogueEntry) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Model/Logic/Model/ConversationModel.cs:304)
PixelCrushers.DialogueSystem.ConversationController:OnFinishedSubtitle(Object, EventArgs) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Controller/ConversationController.cs:270)
PixelCrushers.DialogueSystem.ConversationView:FinishSubtitle() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:418)
PixelCrushers.DialogueSystem.ConversationView:OnFinishedSubtitle() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:425)
PixelCrushers.DialogueSystem.Sequencer:FinishSequence() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:549)
PixelCrushers.DialogueSystem.Sequencer:Update() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:541)
There's another error just below it, but it seems to just be the several other Lua methods that run at the same time being tripped up because this one isn't working. In the meantime I'll go double check that there isn't any references to or from the Dialogue Manager that are getting lost.
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Object.get_name () (at <028e4d71153d4ed5ac6bee0dfc08aa3b>:0)
QuestController.PositionForDialogue () (at Assets/Scripts/QuestController.cs:202)
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <eae584ce26bc40229c1b1aa476bfa589>:0)
Language.Lua.LuaMethodFunction.InvokeMethod (Language.Lua.LuaValue[] args) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaValue/LuaMethodFunction.cs:35)
UnityEngine.Debug:LogException(Exception)
Language.Lua.LuaMethodFunction:InvokeMethod(LuaValue[]) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaValue/LuaMethodFunction.cs:40)
Language.Lua.FunctionCall:Evaluate(LuaValue, LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Expr/FunctionCall.cs:41)
Language.Lua.PrimaryExpr:Evaluate(LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Expr/PrimaryExpr.cs:15)
Language.Lua.ExprStmt:Execute(LuaTable, Boolean&) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/ExprStmt.cs:11)
Language.Lua.Chunk:Execute(Boolean&) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/Chunk.cs:42)
Language.Lua.Chunk:Execute() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/Chunk/Chunk.cs:15)
Language.Lua.LuaInterpreter:Interpreter(String, LuaTable) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Interpreter/LuaInterpreter.cs:38)
PixelCrushers.DialogueSystem.Lua:RunRaw(String, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Wrapper/Lua Interpreter/Lua.cs:223)
PixelCrushers.DialogueSystem.Lua:Run(String, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/Lua/Lua Wrapper/Lua Interpreter/Lua.cs:129)
PixelCrushers.DialogueSystem.ConversationModel:GetState(DialogueEntry, Boolean, Boolean, Boolean) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Model/Logic/Model/ConversationModel.cs:234)
PixelCrushers.DialogueSystem.ConversationModel:GetState(DialogueEntry) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Model/Logic/Model/ConversationModel.cs:304)
PixelCrushers.DialogueSystem.ConversationController:OnFinishedSubtitle(Object, EventArgs) (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Controller/ConversationController.cs:270)
PixelCrushers.DialogueSystem.ConversationView:FinishSubtitle() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:418)
PixelCrushers.DialogueSystem.ConversationView:OnFinishedSubtitle() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/View/View/ConversationView.cs:425)
PixelCrushers.DialogueSystem.Sequencer:FinishSequence() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:549)
PixelCrushers.DialogueSystem.Sequencer:Update() (at Assets/Plugins/Pixel Crushers/Dialogue System/Scripts/MVC/Sequencer/Sequencer.cs:541)
There's another error just below it, but it seems to just be the several other Lua methods that run at the same time being tripped up because this one isn't working. In the meantime I'll go double check that there isn't any references to or from the Dialogue Manager that are getting lost.
Re: Null reference exception for a variable that's not actually null
Hi,
In your code editor, use the debugger and set a breakpoint in the QuestController.PositionForDialogue() method at line QuestController.cs:202. Then play and reproduce the scenario. Mouse over the variable(s) to identify what's null. It's almost certainly a reference to a GameObject that was valid when the Lua function was registered but is no longer valid after the scene change because that GameObject was destroyed during the scene change.
Can you share what lines 201-203 are?
In your code editor, use the debugger and set a breakpoint in the QuestController.PositionForDialogue() method at line QuestController.cs:202. Then play and reproduce the scenario. Mouse over the variable(s) to identify what's null. It's almost certainly a reference to a GameObject that was valid when the Lua function was registered but is no longer valid after the scene change because that GameObject was destroyed during the scene change.
Can you share what lines 201-203 are?
Re: Null reference exception for a variable that's not actually null
The variable throwing the null error is just the dialogueNPC gameobject from line 202 which is just : Debug.Log("closest Dialogue NPC : " + dialogueNPC.name);
I threw in some more debugs here and there. On the script that passes in the variable, it will return that the dialogueNPC variable on the QuestController.cs script is not null. And if I run the PositionForDialogue() method from a UI button, it works just fine. I can also see in the inspector that it has a gameobject there. It will only show as null when it's run through the Lua as part of a conversation. So the code itself seems to be fine, but something with Lua or the DialogueSystem is having trouble.
I threw in some more debugs here and there. On the script that passes in the variable, it will return that the dialogueNPC variable on the QuestController.cs script is not null. And if I run the PositionForDialogue() method from a UI button, it works just fine. I can also see in the inspector that it has a gameobject there. It will only show as null when it's run through the Lua as part of a conversation. So the code itself seems to be fine, but something with Lua or the DialogueSystem is having trouble.
Re: Null reference exception for a variable that's not actually null
Hi,
There's nothing particularly special about the way Lua calls C# methods. It just has a table of C# delegates, and it calls them as regular C# delegates when requested. If dialogueNPC is null when the C# method is called, then it's null in C#.
How are you getting the value of dialogueNPC? I don't know what dialogueNPC represents. If you're calling the C# method in a conversation, would it be better to use the property DialogueManager.currentConversant? Note that currentConversant could also be null if the conversation hasn't associated a GameObject with the conversation's conversant. See Character GameObject Assignments for more info.
There's nothing particularly special about the way Lua calls C# methods. It just has a table of C# delegates, and it calls them as regular C# delegates when requested. If dialogueNPC is null when the C# method is called, then it's null in C#.
How are you getting the value of dialogueNPC? I don't know what dialogueNPC represents. If you're calling the C# method in a conversation, would it be better to use the property DialogueManager.currentConversant? Note that currentConversant could also be null if the conversation hasn't associated a GameObject with the conversation's conversant. See Character GameObject Assignments for more info.
Re: Null reference exception for a variable that's not actually null
Turned out the problem was more or less what you mentioned earlier, but with the QuestController being destroyed rather than the Dialogue Manager object being swapped to a new one. The Luas were being registered with the first level load, then when leaving the level, QuestController would be dumped with everything else. After loading back in, the Dialogue Manager was still trying to run the Luas from the destroyed QuestController. Which is why the error was saying the object was destroyed rather than just null. I assumed just registering them again was fine, but they needed to be unregistered then reregistered on level load, that seems to have solved everything. Thanks for the help and quick responses.