How to Use Unity: 2D, 3D, C# Scripting & Mobile Deployment
Key Takeaways
- Unity uses Component-based architecture: every GameObject is a container for scripts, colliders, renderers, etc. You don't write "monster" class; you attach a `MonsterController` script to a 3D model.
- C# scripting is not optional—UnityScript (JavaScript) was deprecated in 2017. Learn basic C# syntax (variables, methods, `Update()`) before touching animations or physics.
- Mobile deployment requires specific settings: disable VSync, reduce draw calls, use texture atlases. A typical iOS game with 200+ draw calls runs at 20 FPS; optimized at 50-80 draw calls runs at 60 FPS.
- 2D vs 3D isn't just about the camera: 2D mode uses orthographic projection, pixel-perfect settings, and sprite renderers. Mixing both (e.g., 2D character in 3D world) is possible but adds complexity.
---
Getting Started: Install and First Project
Download Unity Hub (not the editor directly) from unity.com. Hub manages multiple versions—stick to 2022 LTS for stability. Create a new project: choose 2D Core or 3D Core. Name it "MyFirstGame" and save it somewhere you can find (not on Desktop).
What You Actually See
- Scene window: your game world. Navigate with right-click + WASD or middle-click drag.
- Game window: what the player sees. Click Play to test.
- Hierarchy: all GameObjects in the scene. Think of it as a family tree.
- Inspector: properties of the selected object. This is where you tweak values.
- Project window: files (scripts, sprites, sounds). Drag them into the scene to instantiate.
First mistake beginners make: double-clicking a script opens Visual Studio, but they don't know how to attach it. Solution: drag the script from Project onto any GameObject in Hierarchy.
---
2D vs 3D: When to Use Which
| Aspect | 2D Mode | 3D Mode |
| -------- | --------- | --------- |
| Camera | Orthographic (no perspective) | Perspective (depth) |
| Render Pipeline | Built-in 2D Renderer (or URP 2D) | Universal RP (URP) or HDRP |
| Colliders | BoxCollider2D, CircleCollider2D | BoxCollider, SphereCollider |
| Typical Game | Platformer, puzzle, top-down RPG | FPS, open-world, racing |
| Performance | Lower polygon count, sprite-based | Higher, uses LODs and culling |
Personal rule: if your game doesn't need depth (e.g., characters moving on a flat plane), use 2D. I once spent 3 weeks making a 3D platformer that would have been 3 days in 2D. You can always add 3D elements later (like parallax layers).
---
C# Scripting: The Minimum You Need
Open any script—you'll see `Start()` (runs once) and `Update()` (runs every frame). That's your loop.
Example: Move a Player
```csharp
public class PlayerMovement : MonoBehaviour
{
public float speed = 5f;
private Rigidbody2D rb;
void Start()
{
rb = GetComponent
}
void Update()
{
float moveX = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(moveX * speed, rb.velocity.y);
}
}
```
Common gotcha: `Input.GetAxis` returns values between -1 and 1. If you expect 0 or 1, use `Input.GetKey(KeyCode.A)` instead. For mobile, you'll replace this with touch input.
Debugging tip: Always use `Debug.Log()` liberally. When your character doesn't move, add `Debug.Log("Horizontal: " + moveX);` inside Update. If you see 0, the key bindings might be wrong (check Edit > Project Settings > Input Manager).
---
Mobile Deployment: Android & iOS
Android (Free)
1. Switch platform: File > Build Settings > Android > Switch Platform.
2. Install Android SDK via Unity Hub (or manually set path).
3. Set Minimum API Level to 22 (covers 95% of devices).
4. In Player Settings: disable Auto Graphics API and select OpenGL ES 3.0 (faster on older phones).
5. Enable Development Build for testing (shows logs).
iOS (Paid: $99/year Apple Developer)
1. Requires a Mac with Xcode.
2. Set Target SDK to Device SDK (not Simulator).
3. In Player Settings > Other Settings: set Bundle Identifier (e.g., "com.yourname.game").
4. Build fails often due to missing icon sizes. Use Unity's Default Icon for first build.
Real numbers: A 20MB 2D game (sprites + scripts) builds to ~35MB APK on Android. The same game on iOS becomes ~45MB due to Metal shaders. Compress textures with ASTC (6x6 block) for both platforms—reduces size by 30% with minimal quality loss.
---
Common Pitfalls (and How to Avoid Them)
- Physics jitter: Never change `transform.position` on a Rigidbody; use `rb.MovePosition()` or `rb.velocity`. Direct manipulation breaks physics.
- Memory leaks: Destroying GameObjects? Set references to `null` and call `Resources.UnloadUnusedAssets()` after scene changes. I once had a 2GB memory buildup from not cleaning up spawned bullets.
- UI scaling: Use Canvas Scaler with Scale With Screen Size. Set Reference Resolution to 1920x1080 and Screen Match Mode to 0.5 (blend). Never hardcode pixel positions—use anchors.
---
Your First Mini Project: 2D Coin Collector
1. Create a 2D project.
2. Add a Sprite (right-click > 2D Object > Sprite > Square). Rename to "Player".
3. Add a Rigidbody2D and BoxCollider2D to Player.
4. Create a Circle sprite, rename to "Coin", add CircleCollider2D (check "Is Trigger").
5. Write a `Coin.cs` script:
```csharp
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Player"))
{
Destroy(gameObject);
// Add score later
}
}
```
6. Tag Player as "Player".
7. Add PlayerMovement script from earlier.
8. Play. Collect coins. Celebrate.
---
FAQ
Q: Why does my script not run when I attach it?
A: Check for typos in class name (must match filename). Also ensure the script inherits from `MonoBehaviour`. If it's empty (no Update or Start), Unity won't call anything—add at least `void Start() {}`.
Q: How do I handle touch input for mobile?
A: Use `Input.touchCount > 0` and `Input.GetTouch(0)`. For simple left/right movement, check `touch.position.x` relative to screen center. Example: if x < Screen.width/2, move left.
Q: My game runs at 10 FPS on mobile. What's wrong?
A: Most likely draw calls. Open Profiler (Window > Analysis > Profiler) and check Rendering. If draw calls > 100, reduce by: (a) batching objects with same material, (b) using texture atlases, (c) disabling shadows on mobile. Also set Target Frame Rate to 60 in a script's Start: `Application.targetFrameRate = 60;`.