Dungeon Defense

using UnityEngine;
public class BladeTrap : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
var enemy = collision.collider.GetComponentInParent<Enemy>();
if (enemy == null)
return;
enemy.Die(enemy.transform.forward + enemy.transform.up);
}
}
view raw BladeTrap.cs hosted with ❤ by GitHub
using System.Collections;
using UnityEngine;
public class DoorTrap : Trap
{
public override void TriggerTrap()
{
foreach (var enemy in _enemies)
enemy.Die(Vector3.zero);
}
private IEnumerator Start()
{
yield return null;
transform.parent.GetComponent<Collider>().enabled = false;
transform.parent.GetComponent<Renderer>().enabled = false;
}
}
view raw DoorTrap.cs hosted with ❤ by GitHub
using System;
using UnityEngine;
using UnityEngine.AI;
public class Enemy : MonoBehaviour
{
Animator _animator;
NavMeshAgent _navMeshAgent;
Flag _flag;
float _nextAttackTime;
[SerializeField] float _attackDistance = 2;
[SerializeField] float _attackDelay = 3;
[SerializeField] int _attackDamage = 1;
private bool _dead;
void Awake()
{
_animator = GetComponentInChildren<Animator>();
_navMeshAgent = GetComponent<NavMeshAgent>();
}
void OnEnable()
{
_flag = FindObjectOfType<Flag>();
_navMeshAgent.SetDestination(_flag.transform.position);
}
void Update()
{
_animator.SetBool("Walk", _navMeshAgent.velocity.magnitude > 0);
if (ReadyToAttack())
Attack();
}
void Attack()
{
_nextAttackTime = Time.time + _attackDelay;
_animator.SetTrigger("Attack");
_flag.TakeDamage(_attackDamage);
}
bool ReadyToAttack()
{
float distanceToTarget = Vector3.Distance(transform.position, _flag.transform.position);
if (distanceToTarget > _attackDistance)
return false;
if (Time.time < _nextAttackTime)
return false;
return true;
}
[ContextMenu("Die")]
public void Die(Vector3 launchVelocity)
{
if (_dead)
return;
_dead = true;
_navMeshAgent.enabled = false;
_animator.enabled = false;
GetComponent<Collider>().enabled = false;
var rigidbodies = GetComponentsInChildren<Rigidbody>();
foreach(var rb in rigidbodies)
{
rb.velocity = launchVelocity;
}
Destroy(gameObject, 5f);
}
}
view raw Enemy.cs hosted with ❤ by GitHub
using UnityEngine;
using UnityEngine.SceneManagement;
public class Flag : MonoBehaviour
{
[SerializeField] int _maxHealth = 10;
int _health;
void OnEnable()
{
_health = _maxHealth;
}
public void TakeDamage(int amount)
{
_health -= amount;
if (_health <= 0)
Die();
}
void Die()
{
SceneManager.LoadScene(0);
}
}
view raw Flag.cs hosted with ❤ by GitHub
using System;
using UnityEngine;
using UnityEngine.AI;
public class Player : MonoBehaviour
{
RaycastHit[] _results = new RaycastHit[100];
NavMeshAgent _navMeshAgent;
Animator _animator;
Enemy _target;
float _nextAttackTime;
[SerializeField] float _attackDistance = 1.5f;
[SerializeField] float _attackDelay = 3;
[SerializeField] float _launchPower = 3;
void Awake()
{
_navMeshAgent = GetComponent<NavMeshAgent>();
_animator = GetComponentInChildren<Animator>();
}
void Update()
{
_animator.SetBool("Walk", _navMeshAgent.velocity.magnitude > 0);
if (Input.GetMouseButtonDown(0))
HandleClick();
else if (_target != null)
MoveToTarget();
if (ReadyToAttack())
AttackTarget();
}
void AttackTarget()
{
_nextAttackTime = Time.time + _attackDelay;
_animator.SetTrigger("Attack");
var launchVelocity = transform.forward + transform.up;
launchVelocity *= _launchPower;
_target.Die(launchVelocity);
}
bool ReadyToAttack()
{
if (_target == null)
return false;
float distanceToTarget = Vector3.Distance(transform.position, _target.transform.position);
if (distanceToTarget > _attackDistance)
return false;
if (Time.time < _nextAttackTime)
return false;
return true;
}
void MoveToTarget()
{
_navMeshAgent.SetDestination(_target.transform.position);
}
void HandleClick()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
int hits = Physics.RaycastNonAlloc(ray, _results);
if (TrySetEnemyTarget(hits))
return;
TrySetGroundTarget(hits);
}
bool TrySetEnemyTarget(int hits)
{
for (int i = 0; i < hits; i++)
{
var enemy = _results[i].collider.GetComponentInParent<Enemy>();
if (enemy != null)
{
_target = enemy;
return true;
}
}
return false;
}
void TrySetGroundTarget(int hits)
{
for (int i = 0; i < hits; i++)
{
if (_navMeshAgent.SetDestination(_results[i].point))
{
_target = null;
break;
}
}
}
}
view raw Player.cs hosted with ❤ by GitHub
using UnityEngine;
public class Spawner : MonoBehaviour
{
float _nextSpawnTime;
[SerializeField] float _spawnDelay = 7f;
[SerializeField] GameObject _prefab;
void Update()
{
if (ReadyToSpawn())
Spawn();
}
bool ReadyToSpawn() => Time.time >= _nextSpawnTime;
void Spawn()
{
_nextSpawnTime = Time.time + _spawnDelay;
Instantiate(_prefab, transform.position, transform.rotation);
}
}
view raw Spawner.cs hosted with ❤ by GitHub
using System;
using System.Collections.Generic;
using UnityEngine;
public class Trap : MonoBehaviour
{
float _nextToggleTime;
bool _trapActive;
[SerializeField] protected List<Enemy> _enemies;
[SerializeField] float _toggleRate = 3f;
void Update()
{
if (ShouldToggleTrap())
ToggleTrap();
}
bool ShouldToggleTrap() => Time.time >= _nextToggleTime;
private void ToggleTrap()
{
_nextToggleTime = Time.time + _toggleRate;
_trapActive = !_trapActive;
GetComponent<Animator>().SetBool("Active", _trapActive);
if (_trapActive)
TriggerTrap();
}
[ContextMenu("Trigger Trap")]
public virtual void TriggerTrap() { Debug.LogError("No Implementation"); }
void OnTriggerEnter(Collider other)
{
var enemy = other.GetComponent<Enemy>();
if (enemy != null)
_enemies.Add(enemy);
}
void OnTriggerExit(Collider other)
{
var enemy = other.GetComponent<Enemy>();
if (enemy != null)
_enemies.Remove(enemy);
}
}
view raw Trap.cs hosted with ❤ by GitHub
using UnityEngine;
public class TrapPlacer : MonoBehaviour
{
[SerializeField] Trap[] _trapPrefabs;
int _currentTrapIndex;
void Update()
{
for (int i = 0; i < 9; i++)
{
if (Input.GetKeyDown(KeyCode.Alpha1 + i))
{
_currentTrapIndex = i;
break;
}
}
if (Input.GetMouseButtonDown(1))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hitInfo, Mathf.Infinity, LayerMask.GetMask("Ground")))
{
if (hitInfo.collider.GetComponentInChildren<Trap>() != null)
return;
SpawnTrap(hitInfo);
}
}
}
private void SpawnTrap(RaycastHit hitInfo)
{
var placementPoint = hitInfo.collider.transform.position + Vector3.up;
Trap trap = Instantiate(_trapPrefabs[_currentTrapIndex], placementPoint, Quaternion.identity);
trap.transform.SetParent(hitInfo.collider.transform);
}
}
view raw TrapPlacer.cs hosted with ❤ by GitHub