Open MikeMMattinson opened 7 months ago
I think it should be more like this...
As the player is moving, there might be one or more Enemies within range that are attacking. As I am looking at this, it is misleading, the circle around player should actually be attack circles for each enemy....
As the game updates, loop through all active enemies and look for opportunities to attack player.
From ChatGPT 3.5,
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float attackRange = 3f; // Adjust this value as needed
public int damageAmount = 10; // Adjust damage amount as needed
public LayerMask playerLayer; // Set this in the Unity Editor to the layer where your Player objects are
void Update()
{
// Check for nearby Player and attack if within range
AttackPlayerInRange();
}
void AttackPlayerInRange()
{
Collider[] hitColliders = Physics.OverlapSphere(transform.position, attackRange, playerLayer);
foreach (Collider collider in hitColliders)
{
// Check if the collider is the Player
PlayerController player = collider.GetComponent<PlayerController>();
if (player != null)
{
// Player is within attack range, initiate attack
player.TakeDamage(damageAmount); // Call the TakeDamage method in PlayerController or your desired logic
}
}
}
}
From ChatGPT3.5, here is an example of how to loop through all active enemies:
void FindActiveEnemies()
{
// Find all Enemy objects in the scene
Enemy[] allEnemies = FindObjectsOfType<Enemy>();
// Clear the current list of enemies
enemies.Clear();
// Loop through each enemy to check if it's within range of the player
foreach (Enemy enemy in allEnemies)
{
float distanceToPlayer = Vector2.Distance(enemy.transform.position, player.transform.position);
if (distanceToPlayer <= distanceBetween)
{
enemies.Add(enemy); // Add the enemy to the list if it's within range
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System;
[System.Serializable]
public class Entity : MonoBehaviour
{
private int level;
private int health;
private int attack;
private int defense;
public GameObject damageNumberPrefab;
public void Awake(){
// used for initial setup that
// doesn't rely on other objects
// or components being initialized.
// get rid of the Clone reference
this.name = this.name.Replace("(Clone)","").Trim();
SetLevel(1);
SetAttack(1);
SetHealth(5);
SetDefense(1);
Debug.Log($"[{this.name}] {this} ____ AWAKE.");
}
public void Start(){
// used for initial setup that
// does rely on other objects
// or components being initialized.
Debug.Log($"[{this.name}] {this} ____ STARTED.");
}
public void SetLevel(int level)
{
this.level = level;
}
public int GetLevel()
{
return this.level;
}
public void LevelUp()
{
this.level ++; // plus 1
}
public void SetAttack(int attack)
{
this.attack = attack;
}
public int GetAttack()
{
return attack;
}
public void AttackUp(int increase = 1){
// default attack increase is 1
// max of 8
SetAttack(Math.Min(GetAttack()+increase,8));
}
public void SetDefense(int defense)
{
this.defense = defense;
}
public int GetDefense()
{
return defense;
}
public void DefenseUp(int increase = 1){
// default defense increase is 1
// max of 8
SetDefense(Math.Min(GetDefense()+increase,8));
}
public void SetHealth(int health)
{
this.health = health;
}
public int GetHealth()
{
return health;
}
public void HealthUp(int increase = 5){
// default health increase is 5
// max of 200
SetHealth(Math.Min(GetHealth()+increase,200));
}
public void Attack(Entity other)
{
// if attack > other.defense then attack
if (this.attack > other.defense)
{
Debug.Log($"{name} at {transform.position} attacks {other.name} at {other.transform.position} with Attack: {attack}");
// call TakeDamage()
other.TakeDamage(this);
// draw attack line from enemy to other
//drawLineToPlayer();
}
}
public void TakeDamage(Entity other)
{
// other.attack > this.defense
if (other.GetAttack() > this.defense)
{
// decrease health by actual damage.
Debug.Log($"Other's attack > {name} defense.");
int actualDamage = other.GetAttack() - this.defense;
health -= (actualDamage);
// Instantiate damage number prefab at this position
GameObject damageNumberObj = Instantiate(damageNumberPrefab, transform.position, Quaternion.identity);
if (damageNumberPrefab != null)
{
// Set the damage value on the damage number
DamageNumber damageNumber = damageNumberObj.GetComponent<DamageNumber>();
damageNumber.SetDamage(actualDamage);
if (this.health <= 0)
{
Die();
}
}
else
{
Debug.Log("did not create damage number object.");
}
}
// other.attack < this.defense
else
{
Debug.Log($"{other.name}'s attack of {other.GetAttack()} < {name} defense of {this.defense}.");
}
}
protected virtual void Die()
{
// Override this method in derived classes
Debug.Log($"Entity {name} died!");
}
// public void drawLineToPlayer()
// {
// // Set the positions for the LineRenderer (start and end points)
// lineRenderer.SetPosition(0, transform.position); // Start position: enemy's position
// lineRenderer.SetPosition(1, player.transform.position); // End position: player's position
// // Enable the LineRenderer to make the line visible
// lineRenderer.enabled = true;
// // Start coroutine to disable LineRenderer after duration
// StartCoroutine(DisableLineRendererAfterDelay());
// }
// // Coroutine to disable LineRenderer after specified duration
// private IEnumerator DisableLineRendererAfterDelay()
// {
// yield return new WaitForSeconds(lineDuration);
// lineRenderer.enabled = false;
// }
public override string ToString()
{
string temp = $", Level: {level}";
temp += $", Health: {health}";
temp += $", Defense: {defense}";
temp += $", Attack: {attack}";
temp += $", Position: {transform.position}";
return temp;
}
}