Projectlie Shooting Enemy Added

This commit is contained in:
2022-02-22 11:25:25 +03:00
parent 860847e11a
commit 3b89be5041
12 changed files with 495 additions and 0 deletions

View File

@@ -0,0 +1,45 @@
using Pausable;
using UnityEngine;
namespace AI
{
[RequireComponent(typeof(Rigidbody2D))]
public class Projectile : MonoBehaviour, IPausable
{
[SerializeField] protected float damageOnContact = 50f;
private Rigidbody2D _rigidbody = null;
private void Awake()
{
_rigidbody = GetComponent<Rigidbody2D>();
}
public void SetVelocity(Vector2 velocity)
{
_rigidbody.velocity = velocity;
}
private void OnCollisionEnter2D(Collision2D other)
{
ProjectilePool.Instance.Return(this);
}
public bool IsPaused { get; protected set; } = false;
public void Pause()
{
IsPaused = true;
UpdateRigidbody();
}
public void Resume()
{
IsPaused = false;
UpdateRigidbody();
}
private void UpdateRigidbody()
{
_rigidbody.simulated = !IsPaused;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1451960c367cc30478631b32ba4f8356
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using System.Collections.Generic;
using UnityEngine;
namespace AI
{
public class ProjectilePool : MonoBehaviour
{
private static ProjectilePool _instance = null;
public static ProjectilePool Instance
{
get
{
if (_instance == null)
{
GameObject go = new GameObject(typeof(ProjectilePool).Name);
_instance = go.AddComponent<ProjectilePool>();
}
return _instance;
}
}
public Stack<Projectile> pool = null;
private GameObject prefab;
private void Awake()
{
if (_instance != this && _instance != null)
{
Destroy(this);
return;
}
pool = new Stack<Projectile>(64);
prefab = Resources.Load<GameObject>("Projectiles/Basic Projectile");
}
public Projectile Get()
{
Projectile projectile = null;
pool.TryPop(out projectile);
if (projectile == null)
projectile = Instantiate(prefab).GetComponent<Projectile>();
projectile.gameObject.SetActive(true);
return projectile;
}
public void Return(Projectile projectile)
{
projectile.gameObject.SetActive(false);
pool.Push(projectile);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d37792a64c70ac4eb6971ac3a062f15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
using Pausable;
using UnityEngine;
using UnityEngine.Events;
namespace AI
{
public class ShootingEnemyAI : MonoBehaviour, IPausable
{
[SerializeField] protected float attacksPerSecond = 1f;
[SerializeField] protected float attackRange = 5f;
[SerializeField] protected float timeForProjectileToHit = .25f;
protected float cooldownPerShoot = 0f;
protected float remainingCooldown = 0f;
private float attackRangeSquared = 5f;
private Transform target = null;
private bool canShoot => (target.transform.position - transform.position).sqrMagnitude < attackRangeSquared && target != null;
public UnityEvent OnShoot { get; protected set; } = null;
#region IPausable
public bool IsPaused { get; protected set; } = false;
public virtual void Pause() => IsPaused = true;
public virtual void Resume() => IsPaused = false;
#endregion
protected void Awake()
{
cooldownPerShoot = 1f / attacksPerSecond;
attackRangeSquared = attackRange * attackRange;
OnShoot = new UnityEvent();
UpdateTarget(FindObjectOfType<Player.PlayerController>()?.transform);
}
protected void Update()
{
remainingCooldown -= Time.deltaTime;
if (remainingCooldown <= 0f && canShoot)
Shoot();
}
protected void Shoot()
{
Projectile projectile = ProjectilePool.Instance.Get();
projectile.transform.position = transform.position;
Vector3 velocity = GetVelocityForProjectile(timeForProjectileToHit);
RaycastHit2D raycastHit2D = Physics2D.Raycast(transform.position, target.position - transform.position, attackRange);
if (raycastHit2D.transform != target)
velocity = GetVelocityForProjectile(timeForProjectileToHit * 2);
projectile.SetVelocity(velocity);
remainingCooldown = cooldownPerShoot;
OnShoot?.Invoke();
}
private Vector3 GetVelocityForProjectile(float time)
{
Vector3 vector3 = target.position - transform.position;
vector3.z = 0f;
vector3.y -= (Physics2D.gravity.y / 2) * (time * time);
vector3 /= time;
return vector3;
}
public void UpdateTarget(Transform transform) => target = transform;
private void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, 0.125f);
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, attackRange);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9308b2482216814428bfc53e4e5113c2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: