System strzelania w Unity (ObjectPooling)

System tworzenia nowych pocisków, które poruszają się z użyciem fizyki Rigidbody2D

Funkcja strzelania po wciśnięciu LMB lub odpowiednich przycisków na padzie

Download Unity package: Gun

using UnityEngine;

public class Gun : MonoBehaviour
{
    [SerializeField] GameObject refBulletPrefab;
    [SerializeField] GameObject refGunAim;
    [SerializeField] bool canRotate;

    void Update()
    {
        if (canRotate) Rotate();
        if (Input.GetButtonDown("Fire1")) Shoot();
    }

    void Shoot()
    {
        GameObject bullet = Instantiate(refBulletPrefab, refGunAim.transform.position, refGunAim.transform.rotation);
    }

    void Rotate()
    {
        Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mousePosition.z = 0;
        Vector3 direction = mousePosition - transform.position;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
    }
}
using UnityEngine;

public class Bullet : MonoBehaviour
{
    Rigidbody2D _rb;
    readonly float _speed = 20f;
    readonly float _lifetime = 2f;

    void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
        Destroy(gameObject, _lifetime);
    }
    void FixedUpdate()
    {
        _rb.linearVelocity = transform.right * _speed;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        Destroy(gameObject);
    }

}

System strzelania z Object Pooling

Object pooling to technika optymalizacji, która polega na tworzeniu puli obiektów i ich ponownym używaniu, zamiast ciągłego tworzenia i niszczenia obiektów.

Download Unity package: Gun_pool

using System.Collections.Generic;
using UnityEngine;

public class Gun : MonoBehaviour
{
    [SerializeField] GameObject refBulletPrefab;
    [SerializeField] GameObject refGunAim;
    [SerializeField] bool canRotate;
    List<GameObject> pooledObjects = new List<GameObject>();
    readonly int _amountToPool = 15;
    void Start()
    {
        for (int i = 0; i < _amountToPool; i++)
        {
            GameObject obj = Instantiate(refBulletPrefab);
            obj.SetActive(false);
            pooledObjects.Add(obj);
        }
    }

    void Update()
    {
        if (canRotate) Rotate();
        if (Input.GetButtonDown("Fire1")) Shoot();
    }

    void Shoot()
    {
        GameObject bullet = GetPooledObject();
        if (bullet)
        {
            Quaternion rot = refGunAim.transform.rotation;

            if (refGunAim.transform.position.x - transform.position.x < 0)
            {
                rot =  Quaternion.Euler(rot.eulerAngles + new Vector3(0f, 0f, 180f)); 
            }
            bullet.transform.SetPositionAndRotation(refGunAim.transform.position, rot);
            bullet.SetActive(true);
        }
    }
    public GameObject GetPooledObject()
    {
        for (int i = 0; i < pooledObjects.Count; i++)
        {
            if (!pooledObjects[i].activeInHierarchy)
            {
                return pooledObjects[i];
            }
        }
        return null;
    }
    void Rotate()
    {
        Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mousePosition.z = 0;
        Vector3 direction = mousePosition - transform.position;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
        transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
    }
}
using UnityEngine;

public class Bullet : MonoBehaviour
{
    Rigidbody2D _rb;
    readonly float _speed = 20f;
    readonly float _lifetime = 2f;

    void Start()
    {
        _rb = GetComponent<Rigidbody2D>();
    }
    void FixedUpdate()
    {
        _rb.linearVelocity = transform.right * _speed;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        Disable();
    }
    void OnEnable()
    {
        Invoke(nameof(Disable), _lifetime);
    }
    void OnDisable()
    {
        CancelInvoke();
    }
    void Disable()
    {
        gameObject.SetActive(false);
    }
}

System wielu broni z typami pocisków i zadawaniem obrażeń

Skrypt Gun nie zmienia się.

Download Unity package: Gun and machinegun bullets damage

using UnityEngine;

public abstract class Bullet : MonoBehaviour
{
    Rigidbody2D _rb;
    protected virtual float Speed { get; set; }
    protected virtual int Damage { get; set; }
    readonly float _lifetime = 2f;

    void Awake()
    {
        _rb = GetComponent<Rigidbody2D>();
    }
    void FixedUpdate()
    {
        _rb.linearVelocity = transform.right * Speed;
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        Hp hp = collision.gameObject.GetComponent<Hp>();
        if (hp)
        {
            hp.TakeDamage(Damage);
        }
        Disable();
    }
    void OnEnable()
    {
        Invoke(nameof(Disable), _lifetime);
    }
    void OnDisable()
    {
        CancelInvoke();
    }
    void Disable()
    {
        gameObject.SetActive(false);
    }
}
using UnityEngine;

public class BulletPistol : Bullet
{
    void Start()
    {
        Speed = 12;
        Damage = 1;
    }
}
using Unity.VisualScripting;
using UnityEngine;

public class BulletMachineGun : Bullet
{

   void Start()
    {
        Speed = 30;
        Damage = 3;
    }
}
using UnityEngine;

public class Hp : MonoBehaviour
{
    [SerializeField] int hp;

    public void TakeDamage(int damage)
    {
        hp -= damage;
        if(hp <= 0)
        {
            Destroy(gameObject);
        }
    }

}

Podobne wpisy

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *