Arrow Dodge Game Implementation

A comprehensive guide to implementing an arrow dodge game in Unity from start to finish. Covers player movement, arrow spawning, collision detection, HP system, and more.

Game Overview

The arrow dodge game is a survival game where you avoid arrows falling from above. The player moves left and right to dodge arrows, and loses HP when hit by an arrow. The game ends when HP reaches 0.

Game Features

  1. Player Movement: Move player left and right with arrow keys
  2. Arrow Spawning: Spawn arrows from the top of the screen at regular intervals
  3. Arrow Falling: Spawned arrows fall downward
  4. Collision Detection: Detect collisions between player and arrows
  5. HP System: Decrease HP when hit by an arrow
  6. Game Over: Game ends when HP reaches 0

Project Structure

02.Scripts/
├── PlayerController.cs      # Player movement control
├── GameManager.cs           # Game state and HP management
├── ArrowGenerator.cs         # Arrow spawning
└── ArrowController.cs        # Arrow movement and collision detection

1. Player Controller (PlayerController.cs)

Features

  • Receive left/right arrow key input
  • Move player left and right

Implementation Code

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Player movement speed
    public float moveSpeed = 0.2f;

    void Update()
    {
        // Left arrow key input
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            // Move left
            transform.Translate(-moveSpeed, 0, 0);
        }
        
        // Right arrow key input
        if (Input.GetKey(KeyCode.RightArrow))
        {
            // Move right
            transform.Translate(moveSpeed, 0, 0);
        }
    }
}

Key Concepts

  • Input.GetKey(): Returns true continuously while key is pressed
  • transform.Translate(): Moves relative to current position
  • moveSpeed: Adjusts movement speed (adjustable in Inspector)

Unity Setup

  1. Create player GameObject
  2. Add PlayerController script
  3. Set player image with Sprite Renderer
  4. Adjust moveSpeed value (default: 0.2)

2. Game Manager (GameManager.cs)

Features

  • Manage HP gauge
  • Provide HP decrease method

Implementation Code

using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    // UI Image component to display HP gauge
    public Image hpGauge;
    
    // Method to decrease HP
    public void DecreaseHp()
    {
        // Decrease HP gauge fill amount by 0.2
        hpGauge.fillAmount -= 0.2f;
    }
}

Key Concepts

  • Image.fillAmount: Value between 0.0 (empty) and 1.0 (full)
  • public method: Can be called from other scripts

Unity Setup

  1. Create GameManager GameObject
  2. Add GameManager script
  3. Create UI Canvas
  4. Add Image component (for HP gauge)
  5. Set Image Type to "Filled"
  6. Assign Image to GameManager's hpGauge

3. Arrow Generator (ArrowGenerator.cs)

Features

  • Spawn arrows at regular intervals
  • Spawn arrows at random X positions

Implementation Code

using UnityEngine;

public class ArrowGenerator : MonoBehaviour
{
    // Arrow prefab object
    public GameObject arrowPrefab;
    
    // Arrow spawn interval (in seconds)
    float spawnTime = 0.3f;
    
    // Variable to accumulate elapsed time
    float delta = 0f;

    void Update()
    {
        // Accumulate time between previous and current frame
        delta += Time.deltaTime;
        
        // Check if accumulated time exceeds spawn interval
        if (delta > spawnTime)
        {
            // Reset timer
            delta = 0f;
            
            // Clone prefab to create new arrow object
            GameObject ar = Instantiate(arrowPrefab);
            
            // Randomly determine X coordinate for arrow spawn
            float px = Random.Range(-8.4f, 8.4f);
            
            // Set spawned arrow's position
            ar.transform.position = new Vector3(px, 6f, 0);
        }
    }
}

Key Concepts

  • Time.deltaTime: Provides constant time interval regardless of framerate
  • Instantiate(): Clones prefab to create new object
  • Random.Range(): Generates random value

Unity Setup

  1. Create ArrowGenerator GameObject
  2. Add ArrowGenerator script
  3. Create arrow prefab (Arrow GameObject)
  4. Assign arrow prefab to ArrowGenerator's arrowPrefab
  5. Adjust spawnTime value (default: 0.3 seconds)

4. Arrow Controller (ArrowController.cs)

Features

  • Move arrow downward
  • Delete when off-screen
  • Detect collision with player
  • Decrease HP and delete arrow on collision

Implementation Code

using UnityEngine;

public class ArrowController : MonoBehaviour
{
    // Arrow movement speed
    public float arrowSpeed = 0.1f;

    // Reference to player object
    GameObject player;

    void Start()
    {
        // Find and store reference to GameObject named "player" in scene
        player = GameObject.Find("player");
    }

    void Update()
    {
        // Move arrow downward
        transform.Translate(0, -arrowSpeed, 0);

        // Check if arrow went too far below screen
        if (transform.position.y < -6f)
        {
            // Remove arrow object from memory
            Destroy(gameObject);
        }

        // Distance calculation for collision detection (circle-circle collision algorithm)
        
        // Store arrow's current position as 2D vector
        Vector2 p1 = transform.position;  // Arrow
        
        // Store player's current position as 2D vector
        Vector2 p2 = player.transform.position; // Player

        // Calculate direction vector from arrow to player
        Vector2 direction = p1 - p2;
        
        // Calculate distance between two objects (vector magnitude)
        float d = direction.magnitude;
        
        // Arrow collision radius
        float r1 = 0.5f; // Arrow radius
        
        // Player collision radius
        float r2 = 1.0f; // Player radius

        // Circle-circle collision detection: collision if distance between centers < sum of radii
        if (d < r1 + r2)
        {
            // Find GameObject named "GameManager" in scene and get reference
            GameObject gm = GameObject.Find("GameManager");
            
            // Get GameManager component and call DecreaseHp() method
            gm.GetComponent<GameManager>().DecreaseHp();

            // Delete arrow object since collision detected
            Destroy(gameObject);
        }   
    }
}

Key Concepts

  • GameObject.Find(): Find GameObject by name
  • GetComponent(): Get component
  • Vector2.magnitude: Vector magnitude (distance)
  • Circle-circle collision: Distance between centers < sum of radii

Unity Setup

  1. Add ArrowController script to arrow prefab
  2. Adjust arrowSpeed value (default: 0.1)
  3. Set player GameObject name to "player"
  4. Set GameManager GameObject name to "GameManager"

Step-by-Step Implementation Guide

Step 1: Scene Setup

  1. Create New Scene: File > New Scene
  2. Camera Setup: Use Orthographic camera (2D game)
  3. Background Setup: Set background image or color

Step 2: Player Setup

  1. Create Player GameObject

    • GameObject > 2D Object > Sprite
    • Rename to "player"
    • Set player image with Sprite Renderer
  2. Add PlayerController Script

    • Create PlayerController.cs script
    • Add to player GameObject
    • Adjust moveSpeed value

Step 3: Game Manager Setup

  1. Create GameManager GameObject

    • Create empty GameObject
    • Rename to "GameManager"
    • Add GameManager.cs script
  2. HP Gauge UI Setup

    • Create Canvas (GameObject > UI > Canvas)
    • Create Image (GameObject > UI > Image)
    • Set Image Type to "Filled"
    • Fill Method: Horizontal
    • Fill Origin: Left
    • Assign Image to GameManager's hpGauge

Step 4: Arrow Setup

  1. Create Arrow Prefab

    • GameObject > 2D Object > Sprite
    • Rename to "Arrow"
    • Set arrow image with Sprite Renderer
    • Add ArrowController.cs script
    • Drag to Prefabs folder to create prefab
  2. ArrowGenerator Setup

    • Create empty GameObject
    • Rename to "ArrowGenerator"
    • Add ArrowGenerator.cs script
    • Assign arrow prefab to arrowPrefab

Step 5: Test and Adjust

  1. Run Game: Click Play button
  2. Adjust Speeds:
    • Player movement speed (moveSpeed)
    • Arrow fall speed (arrowSpeed)
    • Arrow spawn interval (spawnTime)
  3. Adjust Collision Range:
    • Arrow radius (r1)
    • Player radius (r2)

Detailed Game Mechanics

1. Time-Based Arrow Spawning

delta += Time.deltaTime;  // Accumulate time
if (delta > spawnTime)    // When certain time elapsed
{
    delta = 0f;            // Reset timer
    // Spawn arrow
}
  • Time.deltaTime: Constant time regardless of framerate
  • delta accumulation: Track elapsed time
  • spawnTime: Adjust spawn interval

2. Circle-Circle Collision Detection Algorithm

Vector2 direction = p1 - p2;        // Direction vector
float d = direction.magnitude;       // Distance
if (d < r1 + r2)                    // Collision check
{
    // Handle collision
}
  • Distance between two points: Calculated using vector magnitude
  • Collision check: Distance < sum of radii
  • Radius adjustment: Set according to object size

3. HP System

hpGauge.fillAmount -= 0.2f;  // Decrease HP by 20%
  • fillAmount: Value between 0.0 and 1.0
  • 0.2 decrease: Decrease by 20% each time
  • Game over after 5 hits: Game over when fillAmount reaches 0

Game Improvement Ideas

1. Game Over Handling

public void DecreaseHp()
{
    hpGauge.fillAmount -= 0.2f;
    
    // Game over when HP reaches 0 or below
    if (hpGauge.fillAmount <= 0f)
    {
        GameOver();
    }
}

void GameOver()
{
    Debug.Log("Game Over!");
    Time.timeScale = 0f;  // Pause game
}

2. Score System

public int score = 0;
public Text scoreText;

void Update()
{
    // Score increases over time
    score += (int)(Time.deltaTime * 10);
    scoreText.text = "Score: " + score;
}

3. Difficulty Increase

float spawnTime = 0.3f;
float minSpawnTime = 0.1f;

void Update()
{
    // Decrease spawn interval over time
    spawnTime = Mathf.Max(minSpawnTime, 0.3f - Time.time * 0.01f);
}

4. Sound Effects

public AudioSource hitSound;
public AudioSource missSound;

void OnHit()
{
    hitSound.Play();
}

void OnMiss()
{
    missSound.Play();
}

Troubleshooting

Problem 1: Arrows Not Spawning

Cause: arrowPrefab not assigned Solution: Assign arrow prefab to ArrowGenerator's arrowPrefab

Problem 2: Collision Not Detected

Cause:

  • Player or GameManager name incorrect
  • Collision radius too small

Solution:

  • Check GameObject names ("player", "GameManager")
  • Increase r1, r2 values

Problem 3: HP Gauge Not Updating

Cause: hpGauge not assigned Solution: Assign Image component to GameManager's hpGauge

Problem 4: Arrows Too Fast or Slow

Cause: arrowSpeed value inappropriate Solution: Adjust ArrowController's arrowSpeed value


Summary

Core Script Roles

Script Role Main Features
PlayerController Player control Left/right movement
GameManager Game state management HP management
ArrowGenerator Arrow spawning Timed spawning
ArrowController Arrow control Movement, collision detection

Key Unity Features

  • Input.GetKey(): Key input detection
  • transform.Translate(): Object movement
  • Instantiate(): Object creation
  • Destroy(): Object deletion
  • Time.deltaTime: Frame-independent time
  • Vector2.magnitude: Distance calculation
  • GameObject.Find(): Find object
  • GetComponent(): Get component

Next Steps

Based on this game, you can add the following features:

  1. Game over screen
  2. Restart functionality
  3. Score system
  4. Difficulty increase
  5. Power-up items
  6. Sound effects
  7. Particle effects

Practice Problems

  1. Add game over functionality so the game ends when HP reaches 0.

  2. Add a score system that increases based on survival time.

  3. Add a difficulty increase system so arrow spawn speed increases over time.

  4. Add a screen flash effect when hit by an arrow.

  5. Create a bonus system that adds points when the player dodges an arrow.