- Home /
Enemy script only runs for one enemy
Hello everyone.Im beginner and trying to make 2d platformer.I have little issue here. Here is my enemy script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
public int health;
private int maxHealth = 100;
private float distance;
public Transform targetTransform;
public bool canTakeDamage;
// Use this for initialization
void Start () {
health = maxHealth;
}
void Update () {
calculateDistance();
}
void calculateDistance()
{
distance = Vector3.Distance(gameObject.transform.position, targetTransform.transform.position);
if(distance < 1)
{
canTakeDamage = true;
}else if(distance > 1)
{
canTakeDamage = false;
}
}
public void takeDamage(int damage)
{
health = health - damage;
}
}
and here is my playerscript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
private Rigidbody2D rgbd2d;
private Animator anim;
private Enemy enemy;
public float speed;
public float jumpForce;
public bool isGrounded=true;
public float maxSpeed;
public bool isWalking;
private float move;
public bool isEnemyAgainstMe;
// Use this for initialization
void Start () {
rgbd2d = gameObject.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
enemy = GameObject.FindGameObjectWithTag("enemy").GetComponent<Enemy>();
}
// Update is called once per frame
void Update () {
anim.SetFloat("speed", Mathf.Abs(move));
anim.SetBool("isGrounded", isGrounded);
attack();
amIWalking();
doIWantToJump();
determinePlayersDirection();
}
void FixedUpdate()
{
move = Input.GetAxis("Horizontal");
rgbd2d.velocity = new Vector2(move * speed, rgbd2d.velocity.y);
if(rgbd2d.velocity.x > maxHiz)
{
rgbd2d.velocity = new Vector2(maxHiz, rgbd2d.velocity.y);
}
else if (rgbd2d.velocity.x < -maxHiz)
{
rgbd2d.velocity = new Vector2(-maxHiz, rgbd2d.velocity.y);
}
}
void amIWalking()
{
if (rgbd2d.velocity.x < 0 || rgbd2d.velocity.x>0)
{
isWalking = true;
}
else if(rgbd2d.velocity.x == 0)
{
isWalking = false;
}
}
void determinePlayersDirection()
{
if (Input.GetAxis("Horizontal") < 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
else if (Input.GetAxis("Horizontal") > 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
}
void doIWantToJump()
{
if (Input.GetButtonDown("Jump"))
{
if (isGrounded)
{
rgbd2d.AddForce(Vector2.up * jumpForce);
isGrounded = false;
}
}
}
void attack()
{
if (Input.GetKeyDown("return"))
{
if (enemy.canTakeDamage == true && isEnemyAgainstMe == true)
{
enemy.takeDamage(20);
}
}
}
}
The issue is, when i add two or more enemies, the enemy script only runs at last added enemy. Where am i doing wrong?
Answer by Divinyx · Jan 14, 2018 at 10:57 PM
I'm not sure what you mean by
"the enemy script only runs at last added enemy."
do the enemy variables not initialize or update? Are the components not being attached to the enemy?
I'm gonna assume you want the enemy to take damage since you also added your player script in there, thing is... you're only accounting for one single enemy
private Enemy enemy;
enemy = GameObject.FindGameObjectWithTag("enemy").GetComponent<Enemy>();
if (enemy.canTakeDamage == true && isEnemyAgainstMe == true)
{
enemy.takeDamage(20);
}
so you might want to use a collection to store all enemies and use GameObject.FindGameObjectsWithTag("enemy")
not Object.. note the 's'
then reference it with an index such as enemy[0].canTakeDamage ...
Answer by Ectogenesis · Jan 16, 2018 at 09:11 PM
Thanks for support! I m getting an idea about process. I updated my player script and still can t decrease enemies health independently(randomly only one enemy can take damage and the others cant).Im sharing only updated parts. Player script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
private Rigidbody2D rgbd2d;
private Animator anim;
public Enemy enemy;
public float speed;
public float jumpForce;
public bool isGrounded=true;
public float maxHiz;
public bool isWalking;
private float move;
private GameObject[] enemies;
private int enemyIndex;
//public bool enemyClose;
public bool isEnemyAgainstMe;
// Use this for initialization
void Start () {
rgbd2d = gameObject.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
enemies = GameObject.FindGameObjectsWithTag("enemy");
}
public void takeIndex(int index)
{
enemyIndex = index;
}
void attack()
{
if (Input.GetKeyDown("return"))
{
enemy = enemies[enemyIndex].GetComponent<Enemy>();
if (enemy.canTakeDamage == true && isEnemyAgainstMe == true)
{
enemy.takeDamage(20);
}
}
}
And here is my enemy script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
public int index;
public int health;
private int maxHealth = 100;
private float distance;
public Transform targetTransform;
private PlayerController player;
//public float distanceLimit;
public bool canTakeDamage;
void calculateDistance()
{
distance = Vector3.Distance(gameObject.transform.position, targetTransform.transform.position);
if(distance < 1)
{
canTakeDamage = true;
player.takeIndex(index);
}else if(distance > 1)
{
canTakeDamage = false;
}
So i gave manually indexes to the enemies but im sure there is an easier way to do.How can i do this? Thanks for the helps again :)
Its random because if you set the enemy index manually.. its not the same as indices co$$anonymous$$g from GameObject.FindGameObjectsWithTag("enemy")
. Right now you don't have anything to check what enemy you are looking at, so you could only just either choose to damage every enemy near the player or damage one random enemy around the player and ignore the rest. Ins$$anonymous$$d of setting the indices manually, just loop through all possible enemies and check which ones are nearby, then damage those...
foreach (Enemy enemy in enemies) {
// if enemy is closeby
enemy.takeDamage(20)
}