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
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);
}
}
}