Common Scripting Pitfalls
(Added note that Editor scripts have to go into Assets/Editor)
m (→My Editor script won't compile!)
|Line 49:||Line 49:|
== My Editor script won't compile! ==
== My Editor script won't compile! ==
If you get an error message like
If you get an error message like The type namespace name `UnityEditor` could not be found: Are you missing directive or an assembly reference?, you have saved the script in the wrong place. All scripts using the [http://unity3d.com/Documentation/ScriptReference/20_class_hierarchy.Editor_Classes.html UnityEditor namespace] must be placed in the Assets/Editor folder in your project folder.
Revision as of 08:25, 28 July 2006
SendMessage and BroadcastMessage
When sending messages, you may find that you sometimes receive the following error messages, even though you're already using SendMessageOptions.DontRequireReceiver to indicate that the message doesn't need to be implemented:
- SendMessage SomeCoolFunction has no receiver!
- BroadcastMessage SomeCoolFunction has no receiver!
This may be caused by lines of code such as the following:
It looks correct, but in fact, we're calling the wrong version of GameObject.SendMessage(). Instead of telling it that we don't require a receiver, we're actually sending the value SendMessageOptions.DontRequireReceiver to SomeCoolFunction() as its function parameter.
The correct form of this method call looks like this:
<csharp>someGameObject.SendMessage("SomeCoolFunction", null, SendMessageOptions.DontRequireReceiver);</csharp>
This time, we're calling the version of GameObject.SendMessage() which has three parameters, and the second parameter is set to 'null'. That means that 'null' is passed to SomeCoolFunction() and the SendMessageOptions.DontRequireReceiver option is correctly interpreted by SendMessage.
This is a common pitfall when writing code that is messaging objects that may not have a receiver.
Coroutines in C#
In C#, a coroutine must return a value of type IEnumerator, as mentioned in the documentation. However, if you return the similarly-named IEnumerable, the coroutine won't work, and it won't return an error either!
Floating point variables and methods
A common thing to do in scripting is to Lerp, or linearlly interpolate between two values. Unity has built in functions to lerp variables of type float, Vector3, Color, Material, and Quaternion, to name a few. The key thing to get sorted out is that all of the methods that operate on these different classes are within the class itself, except for float. To lerp a float, or to do other common operations dealing with floating point numbers, see the Mathf class. It contains Lerp, Min, Max, Abs, Sin, and all sorts of handy math functions. See the wiki's own Mathfx (short for Mathf eXtended) for even more handy math functions.
My script hangs/beachballs Unity!
The most likely cause of this is that your script enters some loop and does not give control back to the Unity engine at all. You probably are forgetting to put a yield statement in your loop. See the Unity documentation on coroutines and the yield statement.
Also if you hit a null reference exception, the first time it happens will take a while showing a beach ball, as the exception is also caught by Apple's crash reporter, which spends some time creating a stack trace of Unity. On slower machines this may give the impressions that Unity is hanging.
There are more possible causes of Unity hangs that should be elaborated on later.
My script changes have no effect when I hit play
When you save a script file, Unity starts compiling it. Depending on how many scripts you have in your project this can take a while. If you hit play before the compilation is done the code that is run is the last compiled version of your scripts.
You can see that Unity is compiling by looking at the spinning wheel at the right corner of the status bar.
Also note that some text editors (TextEdit) do not notify Unity that a file has changed. When using one of those editors, Unity will not start compiling until you switch back to Unity.
My scripts seem to be frame rate dependent!
If your script performs some incremental operation that should happen over a certain period of time, rather than a certain number of graphical updates, (This is most likely what you do not want!) you need to multiply your specific operation by Time.deltaTime.
For example, <csharp>transform.position += Vector3.up * 5f;</csharp> Should become: <csharp>transform.position += Vector3.up * 5f * Time.deltaTime;</csharp>
My Editor script won't compile!
If you get an error message like The type namespace name `UnityEditor` could not be found: Are you missing directive or an assembly reference?, you have saved the script in the wrong place. All scripts using the UnityEditor namespace must be placed in the Assets/Editor folder in your project folder.