Common Scripting Pitfalls

From Unify Community Wiki
Revision as of 05:53, 5 February 2007 by KeliHlodversson (Talk | contribs)

Jump to: navigation, search


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:

<csharp>someGameObject.SendMessage("SomeCoolFunction", SendMessageOptions.DontRequireReceiver);</csharp>

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 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, in C#: <csharp>transform.position += Vector3.up * 5f;</csharp> Should become: <csharp>transform.position += Vector3.up * 5f * Time.deltaTime;</csharp>

In JavaScript: <javascript>transform.position += Vector3.up * 5;</javascript> Should become: <javascript>transform.position += Vector3.up * 5 * Time.deltaTime;</javascript>

Since Time.deltaTime is usually a very small number, you will probably need to increase the number 5f (or just 5 in JavaScript) to something larger as well. Additionally, you should probably just make this a public variable in your script to take advantage of Unity's feature which allows you to modify variable values right in the Inspector!

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.

Help, I need a Loop Guru!

If you find you want to loop (i.e. for your co-routines) but are not sure about what type of loop, you've come to the right place! Here are a list of useful example loops;

The for loop

Basic "for" loop; start value, end value, update expression (operator i increases on each update): <javascript>function Update() { for (var i=0; i < someNumber; i++) { something something;



The for loop can also be used to iterate of the contents of collections (ie. lists and arrays) Basic "for" loop; start value, end value, update expression (operator i increases on each update): <javascript>function ToggleRenderers() {

       var aList = GetComponentsInChildren(Renderer);

for ( var r in aList ) { r.enabled= ! r.enabled;



The while loop

A 'while' loop in a co-routine ( <javascript>var target : Transform;

if (target)

  StartCoroutine("Lerp", 1.0);

function Lerp (time : float) {

 var pos = transform.position;
 var rot = transform.rotation;
 var originalTime = time;

  while (time > 0.0)
     time -= Time.deltaTime;
     transform.position = Vector3.Lerp(target.position, pos, time / originalTime);
     transform.rotation = Quaternion.Slerp(target.rotation, rot, time / originalTime);

} </javascript>

Personal tools