Unity Cheatsheet¶
Unity - Game Development for Mobile
Unity es un potente motor de juegos multiplataforma utilizado para crear juegos y simulaciones en 2D, 3D, VR y AR. Esta hoja de referencia se enfoca en el desarrollo de juegos móviles con Unity.
Tabla de Contenidos¶
- Instalación
- Editor de Unity
- Conceptos Básicos
- Scripting con C#
- Física
- Sistema de UI
- Animación
- Desarrollo Móvil
- Optimización de Rendimiento
- Gestión de Assets
- Pruebas y Depuración
- Despliegue
- Mejores Prácticas
Would you like me to continue translating the rest of the document? I can proceed with the remaining sections if you confirm.```bash
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
```bash
# 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");
}
```## Desarrollo Móvil
```csharp
#if UNITY_ANDROID
// Android-specific code
#elif UNITY_IOS
// iOS-specific code
#else
// Code for other platforms (e.g., Editor)
#endif
```### Compilación Específica de Plataforma
```csharp
// Set screen orientation
Screen.orientation = ScreenOrientation.LandscapeLeft;
// Allow auto-rotation
Screen.autorotateToPortrait = true;
Screen.autorotateToLandscapeLeft = true;
Screen.autorotateToLandscapeRight = true;
Screen.autorotateToPortraitUpsideDown = false;
```### Orientación de Pantalla
```csharp
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;
}
}
}
```### Controles Táctiles
```csharp
// Get accelerometer data
Vector3 acceleration = Input.acceleration;
// Use accelerometer for movement
float moveHorizontal = acceleration.x;
float moveVertical = acceleration.y;
```### Acelerómetro
```csharp
// Enable gyroscope
Input.gyro.enabled = true;
// Get gyroscope data
Quaternion rotation = Input.gyro.attitude;
Vector3 rotationRate = Input.gyro.rotationRate;
```### Giroscopio
```csharp
// Vibrate device
Handheld.Vibrate();
```### Vibración del Dispositivo
```csharp
// 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);
```### Datos Persistentes
```csharp
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;
}
}
```## Optimización de Rendimiento
### Profiler
- Una herramienta para analizar y optimizar el rendimiento del juego.
- **Ventana -> Análisis -> Profiler**.
- **Uso de CPU**: Identificar cuellos de botella de rendimiento en scripts.
- **Uso de GPU**: Analizar el rendimiento de renderizado.
- **Memoria**: Rastrear asignaciones de memoria e identificar fugas de memoria.
### Agrupación
- **Agrupación Estática**: Para objetos no móviles que comparten el mismo material.
- **Agrupación Dinámica**: Para objetos pequeños móviles que comparten el mismo material.
### Culling
- **Culling de Frustum**: Habilitado automáticamente. Los objetos fuera de la vista de la cámara no se renderizan.
- **Culling de Oclusión**: Previene el renderizado de objetos ocultos detrás de otros objetos.
### Nivel de Detalle (LOD)
- Renderiza modelos con diferentes niveles de detalle según su distancia de la cámara.
### Compresión de Texturas
- Usar formatos de compresión de texturas apropiados para cada plataforma (por ejemplo, ASTC para Android/iOS).
### Agrupación de Objetos
- Reutilizar objetos en lugar de instanciarlos y destruirlos con frecuencia.
```csharp
// Load asset from Resources folder
Texture2D texture = Resources.Load<Texture2D>("Textures/my_texture");
GameObject prefab = Resources.Load<GameObject>("Prefabs/my_prefab");
```## Gestión de Recursos
### AssetBundles
- Archivos de recursos que pueden cargarse bajo demanda.
- Utilizados para contenido descargable (DLC) y reducir el tamaño inicial de la aplicación.
### Recursos Direccionables
- Un sistema para gestionar y cargar recursos por dirección.
- Simplifica la gestión y carga de recursos.
### Carpeta de Recursos
- Una carpeta especial donde los recursos pueden cargarse por nombre en tiempo de ejecución.
- No recomendado para proyectos grandes debido a implicaciones de rendimiento.
```csharp
// 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");
```## Pruebas y Depuración
### Depuración
```csharp
// 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);
}
}
```### Marco de Pruebas de Unity
- Un marco para escribir y ejecutar pruebas automatizadas en Unity.
- **Ventana -> General -> Test Runner**.
- **Pruebas de Modo Edición**: Se ejecutan en el Editor de Unity.
- **Pruebas de Modo Juego**: Se ejecutan mientras el juego está en ejecución.
```bash
# 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"
```## Implementación
### Configuración de Compilación
- **Archivo -> Configuración de Compilación**.
- Seleccionar plataforma de destino (Android, iOS).
- Agregar escenas a la compilación.
- Configurar ajustes del reproductor.
### Ajustes del Reproductor
- **Editar -> Configuración del Proyecto -> Reproductor**.
- **Nombre de la Empresa**, **Nombre del Producto**, **Versión**.
- **Ícono**, **Pantalla de Inicio**.
- **Identificador de Paquete** (por ejemplo, com.company.product).
- **Backend de Scripting** (Mono, IL2CPP).
- **Nivel de Compatibilidad de API**.
### Compilación para Android
```bash
# 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
```### Compilación para iOS (solo macOS)
Organización del Proyecto¶
Awake### Prácticas de Codificación
- Usar espacios de nombres para organizar código.
- Seguir una convención de nomenclatura consistente (por ejemplo, PascalCase para clases, camelCase para variables).
- Almacenar referencias de componentes en Starto GameObject.Find.
- Evitar usar Updateen