10 Interview Questions for Unity3D

1 - What is a Coroutine?

A coroutine is like a function that has the ability to pause execution and return control to Unity but then to continue where it left off on the following frame. It is useful to make procedural animations or a sequence of events over time.

Source : https://docs.unity3d.com/Manual/Coroutines.html

2 - What is a shader?

Shaders are small scripts that contain the mathematical calculations and algorithms for calculating the colour of each pixel rendered, based on the lighting input and the Material configuration.

Source : https://docs.unity3d.com/Manual/Shaders.html

3 - What is the difference between the Start, Awake and OnEnable methods?

Start is called on the frame when a script is enabled just before any of the Update methods is called the first time. Awake is called when the script instance is being loaded. OnEnable is called when the object becomes enabled and active. Execution order is : Awake, OnEnable, Start.

Source : https://docs.unity3d.com/ScriptReference/MonoBehaviour.Start.html

Source : https://docs.unity3d.com/ScriptReference/MonoBehaviour.Awake.html

Source : https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnEnable.html

Source : http://answers.unity3d.com/questions/217941/onenable-awake-start-order.html

4 - In the mock-up below, pin down every elements to be cut into sprites to recreate a scene Into Unity. The goal is to optimize draw calls and memory usage.

  • The Sky can be cut as a one pixel wide sprite and be put on a Transform with a stretched X scale
  • The moutains can be cut as a single sprite
  • Only the largest palm tree should be cut as the others are just scaled down, rotated and mirrored duplicates
  • The circles for the sun and it's shadow can be created in Unity. Right-click in the project hierarchy, Create, Sprites, Circle. This creates a Vector shape so it can be scaled to any size without using too much memory. You can color the sprite using the Color property of the SpriteRenderer
  • Use the same technic as the sun to create a square that will fill most of the scene with a plain sand color.
  • Cut a sprite for the darker sand
  • For the frog Bubble, use the Sprite Editor to achieve the nine slice technic
  • The arrow at the bottom of the bubble is a single sprite
  • A single frog can be cut in white and gray and can be duplicated and colored differently using the Color property of the Sprite Renderer
  • The eyes, mouth and waterlily have to be cut as seperated sprites since they are not colored like the rest of the frog's body

Source for slicing a sprite : https://www.youtube.com/watch?v=WFQcc1GUe7U

5 - What can be modified in the code below to improve it?

  • Don't use GameObject.Find, especially not inside the update because it's slow
  • Limit the use of tags, search object by components instead when possible because maintaining tags can cause problems if a tag name changes
  • Instead of looking for objects every frame (it's slow), cache the list of EnnemyController inside the class and use a Delegate to know when an ennemy dies so this class can maintain the list of ennemies alive and call the Victory method when all ennemies are dead
void Update()
{
     GameObject[] objects = GameObject.FindGameObjectsWithTag("Ennemy");
     if (objects.Length == 0) Victory();
     else foreach (GameObject obj in objects) obj.GetComponent<EnnemyController>().DoAction();
}

6 - Describe a way to create a mini-map in the corner of a screen to display in real time the surroundings or the player.

Use a RenderTexture (Right-click in the project hierarchy, Create, Render Texture) to render a special, top down view, mini-map camera inside this texture. Bind this texture to a UI Image component. You can also add an icon over the head of you character that will be on a layer only rendered by the mini-map camera.

Source : https://docs.unity3d.com/ScriptReference/RenderTexture.html

7 - There is an instance of a prefab on the scene A and another instance of the same prefab on the scene B. We modify the "Speed" field of the prefab in the scene B to 385 and then we change the same field of the prefab in the scene A to 500 before hitting the Apply button on the prefab in the scene A. What's the value of the "Speed" field : on the prefab, on the prefab instance in the scene A and on the prefab isntance in the scene B?

Prefab : 500

Scene A prefab instance : 500

Scene B prefab instance : 385

Source : https://docs.unity3d.com/Manual/Prefabs.html

8 - A piece of code inside the Update method makes a UI panel slide in the scene using transform.Translate(1, 0, 0). On a first generation iPad, the panel takes 2 seconds to animate to the center of the screen while it only takes 1 second on an newer iPad. Why does this happen and how can we fix it?

Devices running on different specs can have different framerates. In this case, maybe the game is running at 30 fps on the older iPad and running at 60 fps on the newer one. Update is called once per frame so that's why the animation complete faster on the newer iPad. To make the translation move at a constant speed, multiply the translation values by Time.deltaTime which is the time since the last frame. Another option would be to execute the code inside the FixedUpdate method which always run at a fixed interval of time.

Source : https://docs.unity3d.com/ScriptReference/Time-deltaTime.html

Source : https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html

9 - In a 2D platformer game, the character is a GameObject moved by physics with a RigidBody2D and a BoxCollider2D. On the scene, there are coins made of a Sprite and a CircleCollider2D with the IsTrigger parameter activated. In the caracter script, we want to increment the score by one when the coin is collided. But, the code below is never reached when the character runs into a coin. Why?

OnTriggerEnter is a Unity method that works with 3D physics and RigidBody components. For 2D physics and RigidBody2D components, we use the OnTriggerEnter2D method.

Source : https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnTriggerEnter2D.html

void OnTriggerEnter(Collider collider)
{
     Score += 1;
}

10 - Give an example of things we could do inside another Thread beside the Unity main Thread.

You can do anything in other Threads except using Unity API methods themselves across different threads, as they are not thread-safe.

Source : http://answers.unity3d.com/questions/908054/unity-5-multithreading.html

Multi Touch Input Manager in Unity3D

In Unity3D, it's really easy to do something when the user clicks on an object. Just add a script to that object defining a method named OnMouseDown() and add your behaviour to it. However, if you want your game to support multi touch on mobile devices or other type of devices with a touch screen, Unity doesn't provide methods like OnMouseDown() but for touches. You have to manually loop through Input.touches and check their states which can quickly become a burden if you have different kind of objects with different behaviour.

That's why I made the MultiTouchInputManager class which manage the user's touch events and transfer them to the appropriate detected object under the user's touch. The object, which inherit from an abstract MultiTouchObject class can then easily implements the TouchDown, TouchPressed and TouchUp events to easily make custom behaviours like drag and drop.

The MultiTouchInputManager also works in pair with the MultiTouchCameraDrag script which allows panning and pinch-zooming of an orthographic camera. That, along with physic or non-physical dragable objects classes which inherit from MultiTouchObject, makes a great starter pack for any 2D multi touch enabled projects.

How to use the MultiTouchInputManager:

  1. Add the MultiTouchInputManager script component to the Camera object or on an empty object.
  2. Add objects on your scene with scripts that inherit from MultiTouchObject. The Sample project already includes the MultiTouchDraggableObject (non physic drag and drop) and the MultiTouchPhysic2DDraggableObject (drag and drop by physical forces). You can use them directly or inherit from them for custom drag and drop behaviours.
  3. Adjust touch priority field of your objects to establish which object will have priority if multiple objects are overlapping under the user's touch.

Sample project download link : MultiTouchInputManager

Objet Pooling in Unity3D

When you have lots of prefabs creation and destruction going on at runtime in Unity3D, things can get laggy. Or at least, it's inneficient! That's where a pooling system comes in handy. Object pooling means to recycle objects to avoid the performance drop. Concretely, it means to deactivate objects instead of destroying them when they have achieved their purpose and when you want to create a new instance of an object, you check if a disabled version of it is available to be recycled.

So I've made a simple C# script called PoolingManager.cs that does the job for you.

To use it, create a new empty object in the scene hierarchy and attach the PoolingManager script to it. Once this is done, simply call the Provide function of the PoolingManager singleton from anywhere in your code like so :

GameObject newObject = PoolingManager.Instance.Provide(myPrefab); //Initialize newObject and do other stuffs here

The Provide(Transform pPrefab) method will look if a unused(disabled) object of that same prefab name exists in the scene and if not, it will instanciate a new object with that prefab. The only thing you have to take care is to disable objects instead of destroying so the PoolingManager can reuse them. Also, if you have a script attached to your prefab and it does things in the Start() method, transfer these things in the OnEnable() method so the code you want to run when an object appears will happen even if it's a recycled instance. If everything goes well, your scene should look like this while playing :

When the player dies and you want to reset the level, you can simply call PoolingManager.Instance.DeactivateAllObjects() to disable all instancied objects at once, making them available for use again.

Download linkPoolingManager.cs