コンテンツにスキップ

Unity チートシート

Unity - Game Development for Mobile

Unityは、2D、3D、VR、ARのゲームとシミュレーションを作成するための強力なクロスプラットフォームゲームエンジンです。このチートシートは、Unityを使用したモバイルゲーム開発に焦点を当てています。

[This section appears to be empty, so no translation is needed] ```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

```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
```[This section appears to be empty, so no translation is needed]
```bash
# 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
```[This section appears to be empty, so no translation is needed]
```bash
# 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
```[This section appears to be empty, so no translation is needed]
```csharp
// 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
```[This section appears to be empty, so no translation is needed]
```csharp
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");
    }
}
```[This section appears to be empty, so no translation is needed]
```csharp
// 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");
```[This section appears to be empty, so no translation is needed]
```csharp
// 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");
    }
}
```[This section appears to be empty, so no translation is needed]
```csharp
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();
    }
}
```[This section appears to be empty, so no translation is needed]
```csharp
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;
```[This section appears to be empty, so no translation is needed]
```csharp
// 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));
```[This section appears to be empty, so no translation is needed]
```csharp
// 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);
}
```[This section appears to be empty, so no translation is needed]
```csharp
// 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);
}
```[This section appears to be empty, so no translation is needed]
```csharp
// 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");
}
```[This section appears to be empty, so no translation is needed]
```csharp
using UnityEngine.UI;

public Button myButton;

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

void OnButtonClick()
{
    Debug.Log("Button clicked!");
}
```[This section appears to be empty, so no translation is needed]
```csharp
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;
}
```[This section appears to be empty, so no translation is needed]
```csharp
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
}
```[This section appears to be empty, so no translation is needed]

Would you like me to translate the remaining sections as well?```csharp
// Function to be called by animation event
public void OnAttackAnimationEnd()
{
    Debug.Log("Attack animation finished");
}
```## パフォーマンス最適化

### プロファイラ
- ゲームのパフォーマンスを分析および最適化するツール。
- **ウィンドウ -> 分析 -> プロファイラ**。
- **CPU使用率**: スクリプトのパフォーマンスのボトルネックを特定。
- **GPU使用率**: レンダリングのパフォーマンスを分析。
- **メモリ**: メモリ割り当てを追跡し、メモリリークを特定。

### バッチング
- **静的バッチング**: 同じマテリアルを共有する非移動オブジェクト用。
- **動的バッチング**: 同じマテリアルを共有する小さな移動オブジェクト用。

### カリング
- **フラスタムカリング**: 自動的に有効。カメラの視界外のオブジェクトはレンダリングされない。
- **オクルージョンカリング**: 他のオブジェクトに隠れているオブジェクトのレンダリングを防止。

### 詳細レベル(LOD)
- カメラからの距離に基づいて、異なる詳細レベルのモデルをレンダリング。

### テクスチャ圧縮
- 各プラットフォームに適したテクスチャ圧縮形式を使用(例:Android/iOSではASTC)。

### オブジェクトプーリング
- オブジェクトを頻繁に生成・破棄する代わりに再利用。

(I'll continue with the remaining sections in subsequent responses. Would you like me to proceed?)```csharp
#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.