Skip to content

Instantly share code, notes, and snippets.

@Mantic
Last active September 1, 2020 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mantic/f95949565dda92e18a6e5ee843d729f0 to your computer and use it in GitHub Desktop.
Save Mantic/f95949565dda92e18a6e5ee843d729f0 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using System.Collections.Generic;
public class TowerShooter : MonoBehaviour
{
public GameObject FirePoint;
public GameObject Projectile;
public GameObject Barrel;
[SerializeField] private float range = 15f;
[SerializeField] private string enemyTag = "Enemy";
[SerializeField] private float ShootRate = 0.5f;
[SerializeField] private float RotateSpeed = 10f;
private float nextShoot = 0f;
private GameObject Target;
void Start()
{
// Every 0.5 seconds, search for a new target.
InvokeRepeating("UpdateTarget", 0f, 0.5f);
}
// Obtain a new target
void UpdateTarget() {
// Get a list of all enemies in play.
GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
// We'll save which one is the closest by comparing against this variable. Default to infinity (so anything matches at first).
float closestDistance = Mathf.Infinity;
// A temp variable holding the closest enemy we find.
GameObject newEnemy = null;
// Loop through all enemies.
foreach (GameObject enemy in enemies) {
// Calculate their distance to the tower.
float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
// Only if they're within the tower's shooting range, will we consider them.
if(distanceToEnemy <= range) {
// If this enemy is closer than our clostest variable, remember it.
if(distanceToEnemy < closestDistance) {
newEnemy = enemy;
closestDistance = distanceToEnemy;
}
}
}
// If we didn't find a new enemy, set our current Target to null and abort.
if(newEnemy == null) {
Target = null;
return;
}
// If our new target is different from our existing target, look for its "Target" game object
// so we know where to aim. If we can't find that game object, aim at its transform position (usually the feet).
if(newEnemy != Target) {
GameObject targetX = GetChildWithName(newEnemy, "Target");
if(targetX != null) {
Target = targetX;
} else {
Target = newEnemy;
}
}
}
public void Fire() {
// Instantiate a projectile from the firepoints position and orientation.
// FirePoint is a gameobject on the tower position where it shoots from.
Instantiate(Projectile, FirePoint.transform.position, FirePoint.transform.rotation);
}
private void Update() {
// If we have a barrel object and have a target, Lerp towards the target (slowly rotate towards it).
if(Barrel != null && Target != null) {
Quaternion newRot = Quaternion.LookRotation(Barrel.transform.position - Target.transform.position);
Barrel.transform.rotation = Quaternion.Lerp(Barrel.transform.rotation, newRot, Time.deltaTime * RotateSpeed);
}
// If we have a target, start the shooting process.
if(Target != null) {
// If next shoot is less than current game time, fire!
if(nextShoot < Time.time) {
// Do math that tells us if we are pointing at them. -0.993 or less means we are.
Vector3 dir = (Target.transform.position - Barrel.transform.position).normalized;
float dotProd = Vector3.Dot(dir, Barrel.transform.forward);
// Only shoot if we're pointing at them.
if(dotProd < -0.993) {
// Set the next time we can shoot as "now + shoot rate"
nextShoot = Time.time + ShootRate;
Fire();
}
}
}
}
// While in the editor, this will draw the tower's range so we can easily design the game.
private void OnDrawGizmosSelected() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range);
}
// Used to go through a gameobject's children and find one with a specific name.
private GameObject GetChildWithName(GameObject obj, string name) {
Transform trans = obj.transform;
Transform childTrans = trans. Find(name);
if (childTrans != null) {
return childTrans.gameObject;
} else {
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment