Skip to content

Unity Cheatsheet

Unity - Game Development for Mobile

Unity is a powerful cross-platform game engine used to create 2D, 3D, VR, and AR games and simulations. This cheatsheet focuses on mobile game development with Unity.

Table of Contents

Installation

Unity Hub

# Download Unity Hub from unity.com
# Unity Hub manages Unity versions and projects

# Install Unity version
# Open Unity Hub -> Installs -> Add
# Select desired Unity version (e.g., 2021.3 LTS)
# Add modules: Android Build Support, iOS Build Support

# Set environment variables (optional)
# UNITY_HOME=/path/to/unity/version
# PATH=$PATH:$UNITY_HOME/Editor

Android Setup

# In Unity Hub, add Android Build Support module
# Unity will install required Android SDK & NDK

# Verify setup in Unity Editor
# Edit -> Preferences -> External Tools
# Check Android SDK, NDK, and JDK paths

# For custom SDK/NDK
# Download from developer.android.com
# Set paths in Unity Editor

iOS Setup (macOS only)

# In Unity Hub, add iOS Build Support module

# Install Xcode from Mac App Store
# Install Xcode Command Line Tools
xcode-select --install

# Install CocoaPods
sudo gem install cocoapods

# Verify setup in Unity Editor
# Edit -> Preferences -> External Tools
# Check Xcode path

Unity Editor

Main Windows

  • Scene View: Visual representation of the game world
  • Game View: Preview of the game as seen by the player
  • Hierarchy: List of all GameObjects in the current scene
  • Project: Browser for all assets in the project
  • Inspector: Properties of the selected GameObject or asset
  • Console: Displays logs, warnings, and errors

Keyboard Shortcuts

  • Q: Hand Tool (pan)
  • W: Move Tool
  • E: Rotate Tool
  • R: Scale Tool
  • T: Rect Tool (for UI)
  • Ctrl/Cmd + S: Save Scene
  • Ctrl/Cmd + P: Play/Pause Game
  • Ctrl/Cmd + Shift + P: Step Frame
  • F: Focus on selected object
  • Ctrl/Cmd + D: Duplicate selected object

Project Management

# Create new project
# Unity Hub -> Projects -> New
# Select template (2D, 3D, URP, HDRP)
# Enter project name and location

# Open existing project
# Unity Hub -> Projects -> Add
# Select project folder

# Upgrade project
# Open project in newer Unity version
# Unity will prompt for upgrade

Core Concepts

GameObject

  • The fundamental objects in Unity that represent characters, props, scenery, cameras, etc.
  • A container for Components.

Component

  • Functional pieces of a GameObject.
  • Examples: Transform, Mesh Renderer, Rigidbody, Collider, Scripts.

Transform Component

  • Every GameObject has a Transform component.
  • Defines the GameObject's position, rotation, and scale.

Scene

  • A container for a set of GameObjects.
  • Represents a level, a menu, or a part of the game.

Prefab

  • A reusable GameObject stored in the Project view.
  • Allows you to create, configure, and store a GameObject complete with all its components, property values, and child GameObjects as a reusable asset.

Asset

  • Any file used in a Unity project, such as models, textures, sounds, scripts, etc.

Scripting with C

Creating a Script

// In Project view, right-click -> Create -> C# Script
// Name the script (e.g., PlayerController)
// Attach script to a GameObject by dragging it to the Inspector

MonoBehaviour Lifecycle

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Called when the script instance is being loaded
    void Awake()
    {
        Debug.Log("Awake called");
    }

    // Called on the frame when a script is enabled before any of the Update methods are called the first time
    void Start()
    {
        Debug.Log("Start called");
    }

    // Called every frame
    void Update()
    {
        // Game logic that needs to run every frame
    }

    // Called every fixed framerate frame
    void FixedUpdate()
    {
        // Physics calculations
    }

    // Called every frame, after all Update functions have been called
    void LateUpdate()
    {
        // Camera movement, etc.
    }

    // Called when the object becomes enabled and active
    void OnEnable()
    {
        Debug.Log("OnEnable called");
    }

    // Called when the object becomes disabled or inactive
    void OnDisable()
    {
        Debug.Log("OnDisable called");
    }

    // Called when the MonoBehaviour will be destroyed
    void OnDestroy()
    {
        Debug.Log("OnDestroy called");
    }
}

Accessing Components

// Get component on the same GameObject
Rigidbody rb = GetComponent<Rigidbody>();

// Get component on a child GameObject
Transform childTransform = GetComponentInChildren<Transform>();

// Get component on a parent GameObject
PlayerController parentController = GetComponentInParent<PlayerController>();

// Add component to GameObject
BoxCollider collider = gameObject.AddComponent<BoxCollider>();

// Find GameObject by name
GameObject player = GameObject.Find("Player");

// Find GameObject by tag
GameObject enemy = GameObject.FindWithTag("Enemy");

// Find all GameObjects with tag
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");

Input Handling

// Keyboard input
if (Input.GetKeyDown(KeyCode.Space))
{
    // Jump
}

if (Input.GetKey(KeyCode.A))
{
    // Move left
}

if (Input.GetKeyUp(KeyCode.LeftShift))
{
    // Stop sprinting
}

// Mouse input
if (Input.GetMouseButtonDown(0))
{
    // Left mouse button clicked
}

float mouseX = Input.GetAxis("Mouse X");
float mouseY = Input.GetAxis("Mouse Y");

// Touch input
if (Input.touchCount > 0)
{
    Touch touch = Input.GetTouch(0);

    if (touch.phase == TouchPhase.Began)
    {
        Debug.Log("Touch began");
    }

    if (touch.phase == TouchPhase.Moved)
    {
        Debug.Log("Touch moved");
    }

    if (touch.phase == TouchPhase.Ended)
    {
        Debug.Log("Touch ended");
    }
}

Coroutines

using System.Collections;
using UnityEngine;

public class CoroutineExample : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Fade());
    }

    IEnumerator Fade()
    {
        Debug.Log("Coroutine started");

        // Wait for 2 seconds
        yield return new WaitForSeconds(2f);

        Debug.Log("After 2 seconds");

        // Wait for the end of the frame
        yield return new WaitForEndOfFrame();

        Debug.Log("End of frame");

        // Wait for another coroutine to finish
        yield return StartCoroutine(AnotherCoroutine());

        Debug.Log("Coroutine finished");
    }

    IEnumerator AnotherCoroutine()
    {
        Debug.Log("Another coroutine started");
        yield return new WaitForSeconds(1f);
        Debug.Log("Another coroutine finished");
    }

    // Stop a coroutine
    public void StopMyCoroutine()
    {
        StopCoroutine(Fade());
        StopAllCoroutines();
    }
}

Scene Management

using UnityEngine.SceneManagement;

// Load a scene by name
SceneManager.LoadScene("Level1");

// Load a scene by index
SceneManager.LoadScene(1);

// Load a scene asynchronously
StartCoroutine(LoadSceneAsync("Level2"));

IEnumerator LoadSceneAsync(string sceneName)
{
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);

    while (!asyncLoad.isDone)
    {
        float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
        Debug.Log("Loading progress: " + (progress * 100) + "%");
        yield return null;
    }
}

// Get the current scene
Scene currentScene = SceneManager.GetActiveScene();
string sceneName = currentScene.name;

Physics

Rigidbody

  • Component that enables a GameObject to be affected by physics.
  • Rigidbody: For 3D physics.
  • Rigidbody2D: For 2D physics.
// Get Rigidbody component
Rigidbody rb = GetComponent<Rigidbody>();

// Add force
rb.AddForce(Vector3.forward * 10f, ForceMode.Impulse);

// Add torque (rotation)
rb.AddTorque(Vector3.up * 5f, ForceMode.Force);

// Set velocity
rb.velocity = new Vector3(0, 10, 0);

// Move position (for kinematic rigidbodies)
rb.MovePosition(transform.position + Vector3.forward * Time.deltaTime);

// Move rotation
rb.MoveRotation(transform.rotation * Quaternion.Euler(Vector3.up * 10f * Time.deltaTime));

Collider

  • Defines the shape of a GameObject for physical collisions.
  • BoxCollider, SphereCollider, CapsuleCollider, MeshCollider.
  • BoxCollider2D, CircleCollider2D, CapsuleCollider2D.

Collision Detection

// Called when this collider/rigidbody has begun touching another rigidbody/collider
void OnCollisionEnter(Collision collision)
{
    Debug.Log("Collision entered with: " + collision.gameObject.name);

    if (collision.gameObject.CompareTag("Enemy"))
    {
        // Take damage
    }
}

// Called once per frame for every collider/rigidbody that is touching another rigidbody/collider
void OnCollisionStay(Collision collision)
{
    Debug.Log("Collision staying with: " + collision.gameObject.name);
}

// Called when this collider/rigidbody has stopped touching another rigidbody/collider
void OnCollisionExit(Collision collision)
{
    Debug.Log("Collision exited with: " + collision.gameObject.name);
}

Trigger Detection

  • Colliders can be marked as "Is Trigger" to detect when objects enter their volume without causing a collision.
// Called when the Collider other enters the trigger
void OnTriggerEnter(Collider other)
{
    Debug.Log("Trigger entered by: " + other.gameObject.name);

    if (other.CompareTag("Player"))
    {
        // Collect item
    }
}

// Called once per frame for every Collider other that is touching the trigger
void OnTriggerStay(Collider other)
{
    Debug.Log("Trigger staying with: " + other.gameObject.name);
}

// Called when the Collider other has stopped touching the trigger
void OnTriggerExit(Collider other)
{
    Debug.Log("Trigger exited by: " + other.gameObject.name);
}

Raycasting

// Cast a ray from the camera to the mouse position
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

if (Physics.Raycast(ray, out hit, 100f))
{
    Debug.Log("Ray hit: " + hit.collider.gameObject.name);
    Debug.Log("Hit point: " + hit.point);
}

// Cast a ray from a transform
if (Physics.Raycast(transform.position, transform.forward, out hit, 10f))
{
    Debug.Log("Forward ray hit: " + hit.collider.gameObject.name);
}

// Raycast with layer mask
int layerMask = 1 << 8; // Layer 8
if (Physics.Raycast(transform.position, Vector3.down, out hit, 2f, layerMask))
{
    Debug.Log("Ground detected");
}

UI System

Canvas

  • The root element for all UI in a scene.
  • Render Mode: Screen Space - Overlay, Screen Space - Camera, World Space.

UI Components

  • Text: Displays text.
  • Image: Displays an image.
  • RawImage: Displays a texture.
  • Button: A clickable button.
  • Toggle: A checkbox.
  • Slider: A draggable slider.
  • Scrollbar: A scrollbar.
  • InputField: A text input field.
  • Panel: A container for other UI elements.
  • ScrollView: A scrollable view.

Rect Transform

  • The Transform component for UI elements.
  • Defines position, size, anchors, and pivot.

Event System

  • Handles input events for UI elements.
  • Requires an EventSystem GameObject in the scene.

Button Click Event

using UnityEngine.UI;

public Button myButton;

void Start()
{
    myButton.onClick.AddListener(OnButtonClick);
}

void OnButtonClick()
{
    Debug.Log("Button clicked!");
}

Accessing UI Components

using UnityEngine.UI;

public Text scoreText;
public Image healthBar;
public InputField nameInput;

void UpdateScore(int score)
{
    scoreText.text = "Score: " + score;
}

void UpdateHealth(float health)
{
    healthBar.fillAmount = health / 100f;
}

string GetPlayerName()
{
    return nameInput.text;
}

Animation

Animator Component

  • Controls animations on a GameObject.
  • Uses an Animator Controller asset to manage animation states.

Animator Controller

  • A state machine for animations.
  • States: Represent individual animations (e.g., Idle, Walk, Run, Jump).
  • Transitions: Define how to move between states.
  • Parameters: Variables that control transitions (e.g., Speed, IsJumping).

Animation Clips

  • Assets that contain animation data (e.g., keyframes for position, rotation, scale).

Controlling Animations from Script

Animator animator = GetComponent<Animator>();

// Set float parameter
animator.SetFloat("Speed", moveSpeed);

// Set bool parameter
animator.SetBool("IsJumping", true);

// Set trigger parameter
animator.SetTrigger("Attack");

// Get current animation state
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName("Attack"))
{
    // In attack animation
}

Animation Events

  • Call a function at a specific point in an animation clip.
  • Add an event in the Animation window.
// Function to be called by animation event
public void OnAttackAnimationEnd()
{
    Debug.Log("Attack animation finished");
}

Mobile Development

Platform-Specific Compilation

#if UNITY_ANDROID
    // Android-specific code
#elif UNITY_IOS
    // iOS-specific code
#else
    // Code for other platforms (e.g., Editor)
#endif

Screen Orientation

// Set screen orientation
Screen.orientation = ScreenOrientation.LandscapeLeft;

// Allow auto-rotation
Screen.autorotateToPortrait = true;
Screen.autorotateToLandscapeLeft = true;
Screen.autorotateToLandscapeRight = true;
Screen.autorotateToPortraitUpsideDown = false;

Touch Controls

void Update()
{
    if (Input.touchCount > 0)
    {
        Touch touch = Input.GetTouch(0);

        switch (touch.phase)
        {
            case TouchPhase.Began:
                // Handle touch began
                break;

            case TouchPhase.Moved:
                // Handle touch moved
                Vector2 touchDeltaPosition = touch.deltaPosition;
                break;

            case TouchPhase.Ended:
                // Handle touch ended
                break;
        }
    }
}

Accelerometer

// Get accelerometer data
Vector3 acceleration = Input.acceleration;

// Use accelerometer for movement
float moveHorizontal = acceleration.x;
float moveVertical = acceleration.y;

Gyroscope

// Enable gyroscope
Input.gyro.enabled = true;

// Get gyroscope data
Quaternion rotation = Input.gyro.attitude;
Vector3 rotationRate = Input.gyro.rotationRate;

Device Vibration

// Vibrate device
Handheld.Vibrate();

Persistent Data

// PlayerPrefs for simple data storage
PlayerPrefs.SetInt("HighScore", 100);
PlayerPrefs.SetString("PlayerName", "John");
PlayerPrefs.SetFloat("Volume", 0.8f);

int highScore = PlayerPrefs.GetInt("HighScore", 0);
string playerName = PlayerPrefs.GetString("PlayerName", "Guest");
float volume = PlayerPrefs.GetFloat("Volume", 1.0f);

PlayerPrefs.Save();

// For complex data, use file I/O
string path = Application.persistentDataPath + "/save.dat";
File.WriteAllText(path, "My save data");
string saveData = File.ReadAllText(path);

Performance Optimization

Profiler

  • A tool to analyze and optimize game performance.
  • Window -> Analysis -> Profiler.
  • CPU Usage: Identify performance bottlenecks in scripts.
  • GPU Usage: Analyze rendering performance.
  • Memory: Track memory allocations and identify memory leaks.

Batching

  • Static Batching: For non-moving objects that share the same material.
  • Dynamic Batching: For small moving objects that share the same material.

Culling

  • Frustum Culling: Automatically enabled. Objects outside the camera's view are not rendered.
  • Occlusion Culling: Prevents rendering of objects that are hidden behind other objects.

Level of Detail (LOD)

  • Renders models with different levels of detail based on their distance from the camera.

Texture Compression

  • Use appropriate texture compression formats for each platform (e.g., ASTC for Android/iOS).

Object Pooling

  • Reuse objects instead of instantiating and destroying them frequently.
public class ObjectPool : MonoBehaviour
{
    public GameObject objectToPool;
    public int amountToPool;
    private List<GameObject> pooledObjects;

    void Start()
    {
        pooledObjects = new List<GameObject>();
        for (int i = 0; i < amountToPool; i++)
        {
            GameObject obj = Instantiate(objectToPool);
            obj.SetActive(false);
            pooledObjects.Add(obj);
        }
    }

    public GameObject GetPooledObject()
    {
        for (int i = 0; i < pooledObjects.Count; i++)
        {
            if (!pooledObjects[i].activeInHierarchy)
            {
                return pooledObjects[i];
            }
        }
        return null;
    }
}

Asset Management

AssetBundles

  • Archives of assets that can be loaded on demand.
  • Used for downloadable content (DLC) and reducing initial app size.

Addressable Assets

  • A system to manage and load assets by address.
  • Simplifies asset management and loading.

Resources Folder

  • A special folder where assets can be loaded by name at runtime.
  • Not recommended for large projects due to performance implications.
// Load asset from Resources folder
Texture2D texture = Resources.Load<Texture2D>("Textures/my_texture");
GameObject prefab = Resources.Load<GameObject>("Prefabs/my_prefab");

Testing & Debugging

Debugging

// Log messages to the console
Debug.Log("This is a log message");
Debug.LogWarning("This is a warning");
Debug.LogError("This is an error");

// Draw debug lines in the Scene view
Debug.DrawLine(transform.position, transform.position + transform.forward * 10f, Color.red);
Debug.DrawRay(transform.position, transform.forward * 10f, Color.green);

// Assertions
Debug.Assert(condition, "Assertion failed");

Unity Test Framework

  • A framework for writing and running automated tests in Unity.
  • Window -> General -> Test Runner.
  • Edit Mode Tests: Run in the Unity Editor.
  • Play Mode Tests: Run in the game while it's playing.
// Edit Mode Test
using NUnit.Framework;

public class CalculatorTests
{
    [Test]
    public void Add_TwoNumbers_ReturnsSum()
    {
        var calculator = new Calculator();
        var result = calculator.Add(2, 3);
        Assert.AreEqual(5, result);
    }
}

// Play Mode Test
using System.Collections;
using NUnit.Framework;
using UnityEngine.TestTools;

public class PlayerTests
{
    [UnityTest]
    public IEnumerator Player_Jumps_ChangesYPosition()
    {
        var player = new GameObject().AddComponent<Player>();
        float initialY = player.transform.position.y;

        player.Jump();

        yield return new WaitForSeconds(0.5f);

        Assert.Greater(player.transform.position.y, initialY);
    }
}

Deployment

Build Settings

  • File -> Build Settings.
  • Select target platform (Android, iOS).
  • Add scenes to the build.
  • Configure player settings.

Player Settings

  • Edit -> Project Settings -> Player.
  • Company Name, Product Name, Version.
  • Icon, Splash Screen.
  • Bundle Identifier (e.g., com.company.product).
  • Scripting Backend (Mono, IL2CPP).
  • API Compatibility Level.

Android Build

# In Build Settings, switch to Android platform
# Connect Android device with USB debugging enabled
# Click "Build and Run"

# To create an APK
# Click "Build"
# Save the APK file

# To create an AAB (Android App Bundle)
# Check "Build App Bundle (Google Play)"
# Click "Build"

iOS Build (macOS only)

# In Build Settings, switch to iOS platform
# Click "Build"
# This will generate an Xcode project

# Open the Xcode project
# In Xcode, set up signing and capabilities
# Select target device and run the app

# To create an archive for App Store
# In Xcode, Product -> Archive

Best Practices

Project Organization

Assets/
├── _Project/
│   ├── Scenes/
│   ├── Scripts/
│   │   ├── Core/
│   │   ├── Gameplay/
│   │   └── UI/
│   ├── Prefabs/
│   ├── Materials/
│   ├── Textures/
│   ├── Animations/
│   └── Audio/
├── Plugins/
├── ThirdParty/
└── Resources/

Coding Practices

  • Use namespaces to organize code.
  • Follow a consistent naming convention (e.g., PascalCase for classes, camelCase for variables).
  • Cache component references in Awake or Start.
  • Avoid using GameObject.Find in Update.
  • Use object pooling for frequently created objects.
  • Optimize loops and avoid unnecessary calculations.

Performance Tips

  • Use the Profiler to identify bottlenecks.
  • Use static batching for static objects.
  • Use LOD for complex models.
  • Compress textures and audio.
  • Use appropriate shaders and avoid overdraw.
  • Keep the hierarchy as flat as possible.

Summary

Unity is a versatile and powerful game engine for mobile development, offering a rich set of tools and features to create high-quality games and interactive experiences.

Key Advantages: - Cross-Platform: Build for Android, iOS, and other platforms from a single codebase. - Rich Ecosystem: Large asset store with ready-to-use assets, tools, and extensions. - Powerful Editor: Intuitive and flexible editor for designing and building games. - Strong Community: Extensive documentation, tutorials, and community support.

Best Use Cases: - 2D and 3D mobile games of all genres. - AR and VR applications. - Interactive simulations and visualizations. - Rapid prototyping and development.

Considerations: - Can have a steep learning curve for beginners. - Performance optimization is crucial for mobile platforms. - Build size can be large if not managed carefully.

By mastering Unity's core concepts, scripting, and mobile-specific features, developers can create engaging and successful mobile games.