- Home /
Disabling SmoothMouseLook on pause (NullReferenceException)
I'm not very familiar with scripting, so forgive me if i say something stupid. I made a scene, and used free pause menu script from asset store. For camera controller, i used first person controller (default, nothing changed). In order to prevent MouseLook from rotating while game is paused, i used code i found (attached it to First Person Controller and Main Camera).
function Start () {
}
function Update () {
if (Input.GetKeyUp(KeyCode.Escape)) {
var mouseLook = GetComponent.<MouseLook>();
mouseLook.enabled = !mouseLook.enabled;
}
}
It may not the best solution, but it did the trick. But now i want to use SmoothMouseLook script (from unity wiki), and i ran into some problems. I replaced MouseLook script with smooth one, and script for disabling rotation no longer works. I get this error:
NullReferenceException: Object reference not set to an instance of an object
RotationLock.Update () (at Assets/_MY/SCRIPTS/RotationLock.js:8)
I figured out the script needs to be modified, in order to make it work with new script (SmoothMouseLook.cs) . But that was all i could do. I've tried to do it myself, but all my attempts result in errors. Can someone point me to right direction?
Also, the console error refers to a different script (RotationLock.js); so it's really hard to help you any further on why you get the NullReference. The line numbers (RotationLock.js:8) would give a good clue as to what exactly is going wrong.
RotationLock is script i posted above, and console points to this line:
mouseLook.enabled = !mouseLook.enabled;
It worked while original $$anonymous$$ouseLook script was in FPS controller.
That means your script can't find the $$anonymous$$ouselook component; is it still attached to your object? If you replaced it, the GetComponent() won't be able to find it. Therefore you get a nullreference when trying to change/read it's property
I figured it was because of that, but changing to Smooth$$anonymous$$ouseLook in GetComponent gives me huge error.
Assets/_$$anonymous$$Y/SCRIPTS/RotationLock.js(8,35): BCE0018: The name 'Smooth$$anonymous$$ouseLook' does not denote a valid type ('not found').
Just a note, there's no point using the generic version of GetComponent in a JS script. Do "GetComponent($$anonymous$$ouseLook)" ins$$anonymous$$d, which accomplishes the exact same thing and is slightly faster while being easier to type.
Answer by Michael Covert · Nov 07, 2012 at 01:09 AM
GetComponent.()
returns a component on the same object of the type MouseLook. It sounds like your old MouseLook script was called MouseLook, but the new one might be called SmoothMouseLook? (as a guess)
If that's the case, changing MouseLook to SmoothMouseLook there might solve your problem.
You're right about script names, but changing that doesn't work (that was obvious thing, i tried it first). If i change it to
var mouseLook = GetComponent.<Smooth$$anonymous$$ouseLook>();
It gives this error:
Assets/_$$anonymous$$Y/SCRIPTS/RotationLock.js(8,35): BCE0018: The name 'Smooth$$anonymous$$ouseLook' does not denote a valid type ('not found').
It looks like you're working in Javascript; the script in your link is in C#. Are you using both? I haven't done that before, but I believe there is something you need to do to access code in one language from the other.
If this is the case, there are other posts on answers here that might talk about what you need - I just searched for "referencing C# scripts from javascript" and it looks like there's a lot of hits with some more helpful information from some folks who know more about this than me.
Yeah, Unity treats executing java / c# in a different order; make sure you save the scripts correctly (javascript as .js and c# as .cs).
If that doesn't solve it:
http://docs.unity3d.com/Documentation/ScriptReference/index.Script_compilation_28Advanced29.html
Tells you more about the order in which unity deals with c# and Javascript and how to work around it.
Hoooray, i solved the problem !!! Like $$anonymous$$ichael said, referencing C# from JS was the case. And i placed Smooth$$anonymous$$ouseLook script in wrong folder, so that caused an error. After i moved it to same folder where original $$anonymous$$ouseLook script was (Standard Assets\Camera Scripts), it fixed the error. I've learned few things today, and most important is how unity deals with scripts. Big thanks to both of you guys, you helped me alot !
Answer by cygnusfear · Nov 06, 2012 at 10:59 PM
Update will always be fired even if your Timescale is zero. If you are pausing the game with Time.Timescale you could try and rewrite the SmoothMouseLook script to use FixedUpdate instead. FixedUpdate won't be fired when Time.Timescale is zero.
Game is paused with Time.timeScale , but you lost me after that :( I just want to disable/enable script (in this case Smooth$$anonymous$$ouseLook) with esc button, haven't thought that it requires modification...
Yeah, I realize I totally misunderstood your question (but hopefully someone will stumble upon this one day and have use for it)
Answer by cygnusfear · Nov 07, 2012 at 02:09 AM
Don't worry if you just started, it's not too hard!
It's all about telling a computer what to do, and computers are downright stupid, but they can do what you tell them perfectly. In your script, it says GetComponent; however as soon as your script can't find that component, the computer will tell you it has a 'null reference'. Which is its way to tell you 'that thing, I have no idea about it'. You need to make sure the computer finds the right component (in other words, script).
Because your new script is called SmoothMouseLook, you will need to find that component, so you need to change 'MouseLook' from the script that you've posted into:
GetComponent.<SmoothMouseLook>();
Because you're now using a different script, which has a different name.
Now if you put this script on an object that doesn't have SmoothMouseLook, you're once again going to get an error; it doesn't exist (on your object), so the computer can't find it. GetComponent only returns components that are on the same object.
What I would suggest is to try to follow some basic tutorials on programming, so you get an idea of what's going on in the scripts; actually it's super simple!
var mouseLook = GetComponent.<MouseLook>();
something (called) mouselook becomes the component mouselook
mouseLook.enabled = !mouseLook.enabled;
(mouselook) (it's) ('enabled' property) =( is set to) !(a negative version) (mouselook's) ('enabled' property)
so, if mouselook is true, it's now false. But you can't do that if you can't find mouselook's property enabled
I misunderstood your question at first, because I think the above will solve your problem; I'll try to explain a bit about Pausing / unpausing below and the abracadabra of time.timescale:
Pausing / unpausing a game is tricky, Unity gives you some tools but if you have no idea what you are doing it certainly is going to be a lot of trial and error. The best suggestion is to read a lot about what the scripts mean, try and look up things like Update() and FixedUpdate() to get a better idea of what's actually going on. (http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.Update.html)
The thing to understand about a game, is that it is basically a loop. Simplified: You start the game, the computer does something, finishes, draws something on the screen, then starts over, finishes, draws on the screen, etc.
Update() is called at the start of each loop; loops are executed as fast as the computer can (start, calculate, draw to screen, start over). This is pretty unpredictable, sometimes you can run on a totally slow pc which will make the loop take longer (you've probably heard of FPS as in, frames per second). For physics calculations, this is totally unacceptable because it would completely screw up a simulation; that's where we have FixedUpdate, which is run with the proper time inbetween updates to be consistent. So if your normal update 'too fast', it just doesn't run FixedUpdate for that 'frame'.
Time.TimeScale manipulates this 'speed of time'. Decrease the timescale, and you are basically increasing the delay between each FixedUpdate. If you put TimeScale to zero, you will stop executing FixedUpdate at all.
And that is what will Pause the game.
tl;dr read a lot, play around, try easy things first, learn to read the scripts, read a lot, use the unity reference to understand (http://docs.unity3d.com/Documentation/ScriptReference/index.html)
Thank you for this post, it really good for introducing a newbie to scripting. I have some Basic knowledge from C64, so i get some faint idea 'bout what's going on.