Your Cart
Loading
unity 2d bullet hell tutorial bullet hell unity tutorial

Unity 2D Bullet Hell Tutorial | Unity Tutorial

Unity 2D Bullet Hell Tutorial | Unity Tutorial


In this tutorial, we'll explore how to create the iconic Bullet Hell effect in Unity 2D. You’ll learn how to design and implement complex bullet patterns that overwhelm the player, including techniques for precise bullet movement and spawning. We’ll cover how to use Unity's particle systems, script intricate bullet behaviors, and optimize performance for smooth gameplay. By the end of this tutorial, you'll be equipped to add intense, visually stunning Bullet Hell effects to your games, enhancing the challenge and excitement for players.



WATCH FULL TUTORIAL ON YOUTUBE



CHECK OUR PROJECTS


SUBSCRIBE FOR LATEST OFFERS



=========================================================


3 Unity Projects Only $50 - ON SALE!!!!

https://youtu.be/7mI-fJpXN88


Contact: unitycoderz2022@gmail.com


=========================================================



Scripts:


Bullet.cs


using UnityEngine;


public class Bullet : MonoBehaviour

{

  public float bulletSpeed = 10f; // Speed of the bullet

  private Vector2 shootDirection; // Direction in which the bullet will move


  void Start()

  {

    // Optionally initialize other properties if needed

  }


  private void OnEnable()

  {

    // Start the destroy countdown when the bullet is enabled

    Invoke("Deactivate", 3f);

  }


  void Update()

  {

    // Move the bullet in the set direction with the defined speed

    transform.Translate(shootDirection * bulletSpeed * Time.deltaTime);

  }


  // Method to set the direction of the bullet

  public void SetShootDirection(Vector2 dir)

  {

    shootDirection = dir.normalized; // Set direction and normalize it

  }


  // Method to deactivate the bullet instead of using Unity's Destroy method

  private void Deactivate()

  {

    gameObject.SetActive(false);

  }


  private void OnDisable()

  {

    // Cancel any pending invokes when the bullet is disabled

    CancelInvoke();

  }

}


--------------------------------------------------------------------------------------------------------------------------------


ObjectPool.cs


using System.Collections.Generic;

using UnityEngine;


public class ObjectPool : MonoBehaviour

{

  public static ObjectPool Instance;


  [SerializeField]

  private GameObject pooledBullet; // The bullet prefab to pool

  private List<GameObject> bullets; // List to store pooled bullets

  private bool notEnoughBulletsInPool = true; // Flag to indicate if we need to instantiate new bullets


  void Awake()

  {

    // Set up singleton pattern

    if (Instance == null)

    {

      Instance = this;

      DontDestroyOnLoad(gameObject); // Optional: keep this instance across scenes

    }

    else

    {

      Destroy(gameObject);

    }

  }


  void Start()

  {

    bullets = new List<GameObject>();

  }


  public GameObject LoadBullets()

  {

    // Check if we have any inactive bullets in the pool

    for (int i = 0; i < bullets.Count; i++)

    {

      if (!bullets[i].activeInHierarchy)

      {

        // Return the first inactive bullet found

        return bullets[i];

      }

    }


    // If no inactive bullets were found, create a new one

    if (notEnoughBulletsInPool)

    {

      GameObject newBullet = Instantiate(pooledBullet);

      newBullet.SetActive(false);

      bullets.Add(newBullet);

      return newBullet;

    }


    return null; // No available bullets

  }

}


-----------------------------------------------------------------------------------------------------------------------------------------


BulletShooter.cs


using System.Collections;

using System.Collections.Generic;

using UnityEngine;


public class BulletShooter : MonoBehaviour

{

  [SerializeField]

  private int bulletAmount = 10; // Number of bullets to fire


  [SerializeField]

  private float startAngle = 90f; // Starting angle of the firing pattern

  [SerializeField]

  private float endAngle = 270f; // Ending angle of the firing pattern


  void Update()

  {

    // Check if the Space bar is pressed

    if (Input.GetKeyDown(KeyCode.Space))

    {

      Fire();

    }

  }


  public void Fire()

  {

    float angleStep = (endAngle - startAngle) / bulletAmount;

    float angle = startAngle;


    for (int i = 0; i < bulletAmount; i++)

    {

      float bulDirX = transform.position.x + Mathf.Cos(angle * Mathf.Deg2Rad);

      float bulDirY = transform.position.y + Mathf.Sin(angle * Mathf.Deg2Rad);

      Vector2 bulMoveVector = new Vector2(bulDirX, bulDirY);

      Vector2 bulDir = (bulMoveVector - (Vector2)transform.position).normalized;


      GameObject bul = ObjectPool.Instance.LoadBullets();

      if (bul != null)

      {

        bul.transform.position = transform.position;

        bul.transform.rotation = Quaternion.identity;


        Bullet bulletScript = bul.GetComponent<Bullet>();

        if (bulletScript != null)

        {

          bulletScript.SetShootDirection(bulDir);

        }


        bul.SetActive(true);

        angle += angleStep;

      }

    }

  }

}





DOWNLOAD CODESTER FILES