Reference problems to other Gameobjects

Hey guys

I am pretty new to Unity. I try to do a simple 2D-Platforfmer currently but I am stuck on a problem. I wrote a script, which controls actually all of my Ki-Enemy. It has some line casts, health etc.

Once the Player hits the enemy, it should lose some health. This works as well.

But just with 1 enemy in the scene. Once there are more, it damages all the time the origin enemy. I’ve already created a prefab out of it, but it did not help.

I am pretty sure that the problem is the reference to it. I just reference the base gameobject.

What are the ways to reference to all instances of that object? How would you separate your scripts, because at the moment my ki script is a big mess, maybe I need to structure it differently to solve the problem with the reference thing?

Anyway, I appreciate every help I can get. Sorry for my English. And unfortunately, I have a deadline (I am doing it for school), so I hope you can give me fast some answers :smiley:

**

  • The following script is my script
    concerning my enemy. I comment it a
    bit, hope it is enough:

@iAmAwsum

**

using UnityEngine;
using System.Collections;

public class kiEnemyMoving : MonoBehaviour {

public LayerMask mskEnemyBlock;
public LayerMask mskEnemyGround;
public LayerMask playerSpot;
public float speed = 1;

bool booEnemyIsGrounded;
bool booEnemyIsBlocked;
bool booPlayerSpotted;
bool booEnemyAttack;

public Rigidbody2D ri2EnemyBody;
public SpriteRenderer mySprite;
public SpriteRenderer BodySprite;
private ControllerScriptAlt scrControllerScriptAlt;

Transform traEnemy;
float myWidth;
Vector2 vec = new Vector2(-1f,-1.0f);
Vector2 vec1 = new Vector2(1f, -1.0f);

public Animator anim;

Vector2 ve2EnemyLastPosition;

Vector2 ve2EnemyPace;
Vector2 ve2PlayerPosition = Vector2.zero;
Vector2 ve2EnemyPosition = Vector2.zero;
Vector2 ve2CurrRot;

Vector2 lineCastPosBlockCheck;

Vector2 watchPlayer;

bool booPlayerLeftFromEnemy;
bool booEnemyMovesLeft;
bool spotReminder = false;

bool booAttackBegin = false;

float fltAttackBegin;

float fltLastSpottedPlayer;
float fltTimeSinceLastSpotted;

int intCurrentEnemyHealth;

public int intMaxEnemyHealth;

//public Transform Player;

void Start ()
	{
	traEnemy = this.transform;
	ri2EnemyBody = GetComponent<Rigidbody2D>();
	mySprite = this.GetComponent<SpriteRenderer>();

// scrPlayerHealth = GameObject.Find(“_Playeralt2”).GetComponent();

	myWidth = mySprite.bounds.extents.x / 3;

	anim = GetComponent<Animator>();

	ve2PlayerPosition = GameObject.FindGameObjectWithTag("Player").transform.position;

	scrControllerScriptAlt = GameObject.FindGameObjectWithTag("Player").GetComponent<ControllerScriptAlt>();

	ve2EnemyPosition = this.transform.position;
	ve2EnemyLastPosition = new Vector2(ve2EnemyPosition.x - 1, ve2EnemyPosition.y);

	intCurrentEnemyHealth = intMaxEnemyHealth;

	if (ve2PlayerPosition.x > ve2EnemyPosition.x)
		booPlayerLeftFromEnemy = true;
	else
		booPlayerLeftFromEnemy = false;
	}

void FixedUpdate ()
	{

	if (scrControllerScriptAlt.booPlayerDied)
		Destroy(this);

	//setting up the linecasts

	Vector2 lineCastPosGroundCheck = traEnemy.position.toVector2() + traEnemy.right.toVector2() * myWidth + Vector2.down;
	if (booEnemyMovesLeft)
		lineCastPosBlockCheck = traEnemy.position.toVector2() + vec;
	else
		lineCastPosBlockCheck = traEnemy.position.toVector2() + vec1;
	
	Vector2 lineCastPosPlayerSpot = traEnemy.position.toVector2() + traEnemy.right.toVector2() * myWidth;
	Vector2 lineCastPosPlayerAttack = traEnemy.position.toVector2() + traEnemy.right.toVector2() * myWidth;

	Debug.DrawLine(lineCastPosGroundCheck, lineCastPosGroundCheck + new Vector2(0,-4.5f), Color.blue);
	booEnemyIsGrounded = Physics2D.Linecast(lineCastPosGroundCheck, lineCastPosGroundCheck + new Vector2(0,-4.5f), mskEnemyGround);

	Debug.DrawLine(lineCastPosBlockCheck, lineCastPosBlockCheck + traEnemy.right.toVector2() * 0.3f, Color.blue);
	booEnemyIsBlocked = Physics2D.Linecast(lineCastPosBlockCheck, lineCastPosBlockCheck + traEnemy.right.toVector2() * 0.3f, mskEnemyBlock);

	Debug.DrawLine(lineCastPosPlayerSpot, lineCastPosPlayerSpot + traEnemy.right.toVector2() * 10.0f, Color.yellow);
	booPlayerSpotted = Physics2D.Linecast(lineCastPosPlayerSpot, lineCastPosPlayerSpot + traEnemy.right.toVector2() * 10.0f, playerSpot);

	Debug.DrawLine(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traEnemy.right.toVector2() * 1.0f, Color.red);
	booEnemyAttack = Physics2D.Linecast(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traEnemy.right.toVector2() * 1.0f, playerSpot);

	//empty, will fill it later, when I have an idea what do to, when the enemy dies

	if (intCurrentEnemyHealth <= 0)
		{

		}

	//method to determin the setting, like in which direction the enemy moves and where the player is (left, right of the enemy)

	funSetting();

	//that is the idle mode, the enemy moves slow and turns when it is not grounded anymore or blocked

	if (!booPlayerSpotted && !spotReminder)
		{
		speed = 1;

		ve2EnemyPace = ri2EnemyBody.velocity;
		ve2EnemyPace.x = traEnemy.right.x * speed;
		ri2EnemyBody.velocity = ve2EnemyPace;

		anim.SetBool("EnemyHeavy_Run", true);

		if (!booEnemyIsGrounded || booEnemyIsBlocked)
			{
			ve2CurrRot = traEnemy.eulerAngles;
			ve2CurrRot.y += 180;
			traEnemy.eulerAngles = ve2CurrRot;

			}
		} 

	//once the player gets spotted a timer starts

	else if (booPlayerSpotted)
		{
		spotReminder = true;

		fltLastSpottedPlayer = Time.time;

		}
	
	//that is the so called "chasing" mode, the enemy moves faster and, depending where the player is, moves to him

	if (spotReminder && !booEnemyAttack)
		{
		speed = 6;

		booAttackBegin = false;

		if (booPlayerLeftFromEnemy && booEnemyMovesLeft)
			{
			funPlayerInReachTest();
			funEnemyWatchesLeft();
			} 
		else if (!booPlayerLeftFromEnemy && !booEnemyMovesLeft)
			{
			funPlayerInReachTest();
			funEnemyWatchesRight();
			} 
		else if (booPlayerLeftFromEnemy && !booEnemyMovesLeft)
			{
			funPlayerInReachTest();
			funEnemyWatchesLeft();
			} 
		else if (!booPlayerLeftFromEnemy && booEnemyMovesLeft)
			{
			funPlayerInReachTest();
			funEnemyWatchesRight();
			}
		
		fltTimeSinceLastSpotted = Time.time;

		//check, whether the enemy did not spot the player for longer than 6 seconds, if so, enemy looses interest and goes into idle again
		if (fltTimeSinceLastSpotted - fltLastSpottedPlayer > 6.0f)
			spotReminder = false;

		} 

	// if the player is in reach, the enemy starts to attack the player. Again a timer starts that let him only attack every 2 seconds
	else if (booEnemyAttack && !booAttackBegin)
		{
		funEnemyAttacksPlayer();
		fltAttackBegin = Time.time;
		booAttackBegin = true;
		} 
	else if (booAttackBegin)
		{
		float check = Time.time;
		if (check - fltAttackBegin > 2.0f)
			{
			funEnemyAttacksPlayer();
			anim.SetTrigger("Hit");
			scrControllerScriptAlt.funPlayerDamage(1);
			//this thing manages the knockback, because it depends unfortunatly from where the enemy is attacking the player
			if (booPlayerLeftFromEnemy)
				{
			StartCoroutine(scrControllerScriptAlt.IEnKnockback(0.02f, 100f, scrControllerScriptAlt.transform.position, 100f));
			} 
		else if (!booPlayerLeftFromEnemy)
			{
			StartCoroutine(scrControllerScriptAlt.IEnKnockback(0.02f, 100f, scrControllerScriptAlt.transform.position, -100f));

			}
			
			booAttackBegin = false;
			}
		}
}

	//method checks wether the player is in reach of the enemy. If it is not, it just stops
void funPlayerInReachTest()
	{
	if (booEnemyIsBlocked || !booEnemyIsGrounded)
		{
		ve2EnemyPace = ri2EnemyBody.velocity;
		ve2EnemyPace.x = 0;
		ri2EnemyBody.velocity = ve2EnemyPace;

		anim.SetBool("EnemyHeavy_Chasing", false);
		anim.SetBool("EnemyHeavy_Run", false);
		} 
	else
		{
		ve2EnemyPace = ri2EnemyBody.velocity;
		ve2EnemyPace.x = traEnemy.right.x * speed;
		ri2EnemyBody.velocity = ve2EnemyPace;

		anim.SetBool("EnemyHeavy_Chasing", true);
		anim.SetBool("EnemyHeavy_Run", false);
		}
	}

	//determines the initial situation of the scene

void funSetting()
	{

	ve2PlayerPosition = GameObject.FindGameObjectWithTag("Player").transform.position;
	ve2EnemyPosition = this.transform.position;

	if (ve2PlayerPosition.x > ve2EnemyPosition.x)
		booPlayerLeftFromEnemy = false;
	else
		booPlayerLeftFromEnemy = true;
	
	if (ve2EnemyPosition.x > ve2EnemyLastPosition.x)
		{
		booEnemyMovesLeft = false;
		anim.SetBool("EnemyHeavy_Run", true);
		}
	else if (ve2EnemyPosition.x < ve2EnemyLastPosition.x)
		{
		booEnemyMovesLeft = true;
		anim.SetBool("EnemyHeavy_Run", true);
		}
	
	ve2EnemyLastPosition = ve2EnemyPosition;

	}
//determines where the enemy shall look
void funEnemyWatchesLeft()
	{
	ve2CurrRot = traEnemy.eulerAngles;
	ve2CurrRot.y = 180;
	traEnemy.eulerAngles = ve2CurrRot;
	}

void funEnemyWatchesRight()
	{
	ve2CurrRot = traEnemy.eulerAngles;
	ve2CurrRot.y = 0;
	traEnemy.eulerAngles = ve2CurrRot;
	}
//set the enemy in attacking mode
void funEnemyAttacksPlayer()
	{
	ve2EnemyPace = ri2EnemyBody.velocity;
	ve2EnemyPace.x = 0;
	ri2EnemyBody.velocity = ve2EnemyPace;

	anim.SetBool("EnemyHeavy_Chasing", false);
	anim.SetBool("EnemyHeavy_Run", false);
	}
//method to damage the enemy through the player
public void funEnemyDamage(int dmg)
	{
	intCurrentEnemyHealth = intCurrentEnemyHealth - dmg;

	anim.SetTrigger("Damaged");
	}

}

  • The next script is from my player:

using UnityEngine;
using System.Collections;

public class ControllerScriptAlt : MonoBehaviour {

public Animator anim;
public Rigidbody2D rb;
private SceneManagment scrSceneManagment;

public LayerMask lmsAttackable;

SpriteRenderer mySprite;

bool facingRight = true;
float maxSpeed = 10.0f;

bool grounded = false;
public Transform groundCheck;
float groundRadius = 1f;
public LayerMask whatIsGround;

bool booPlayerDamaged;

public Transform traPlayer;
float myWidth;

bool booEnemyInRange;

private kiEnemyMoving scrKiEnemyMoving;

Vector2 lineCastPosPlayerAttack;

bool pressedSpace = false;

bool hit = false;

public int intCurrentPlayerHealth;
public int intMaxPlayerHealth = 3;
public bool booPlayerDied;

void Start () 
{
	anim = this.GetComponent<Animator>();
	rb = GetComponent<Rigidbody2D>();
	scrSceneManagment = GetComponent<SceneManagment>();
	intCurrentPlayerHealth = intMaxPlayerHealth;

	booPlayerDamaged = false;

	mySprite = this.GetComponent<SpriteRenderer>();

	myWidth = mySprite.bounds.extents.x / 3;

	scrKiEnemyMoving = GameObject.FindGameObjectWithTag("Enemy").GetComponent<kiEnemyMoving>();
	booPlayerDied = false;

		
}


void FixedUpdate ()
	{

	//setting up the linecasts depending on in which direction the player is looking 
	if (facingRight)
		{
		lineCastPosPlayerAttack = traPlayer.position.toVector2() + traPlayer.right.toVector2() * myWidth * 1.5f;
		Debug.DrawLine(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traPlayer.right.toVector2() * 1.5f, Color.red);
		booEnemyInRange = Physics2D.Linecast(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traPlayer.right.toVector2() * 1.5f, lmsAttackable);

		} 
	else if (!facingRight)
		{
		lineCastPosPlayerAttack = traPlayer.position.toVector2() + traPlayer.right.toVector2() * myWidth * -1.5f;
		Debug.DrawLine(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traPlayer.right.toVector2() * -1.5f, Color.red);
		booEnemyInRange = Physics2D.Linecast(lineCastPosPlayerAttack, lineCastPosPlayerAttack + traPlayer.right.toVector2() * -1.5f, lmsAttackable);
		}

	booPlayerDamaged = false;

	//groundchecks checks wether the player is grounded

	GroundCheck();

	anim.SetFloat("vSpeed", rb.velocity.y);

	//input of the player, excluded into a method
	float move = Controlling();

	//checks in which direction the player watches 
	if (move > 0 && !facingRight)
		Flip();
	else if (move < 0 && facingRight)
		Flip();
	
	//manages the initializing of the attack
	PressedSpace();

	//if the enemy is in range and the player pressed space, the enemy gets damaged, but only the one, which is referenced. There is the problem. Somewehere there...
	if (pressedSpace && booEnemyInRange)
		{
		scrKiEnemyMoving.funEnemyDamage(1);

		}

	hit = false;
	anim.SetBool("Hit", hit);

	//manages the health of the player

	if (intCurrentPlayerHealth > intMaxPlayerHealth)
		{
		intCurrentPlayerHealth = intMaxPlayerHealth;
		}

	if (intCurrentPlayerHealth <= 0)
		{
		funPLayerDie();
		}
	
	}
void Update()
	{
	//manages the jumpcapability of the player
	if (grounded /*|| !doubleJump*/ && Input.GetButtonDown("Jump") && !booPlayerDamaged)
		{
		anim.SetBool("Ground", grounded);
		rb.AddForce(new Vector2(0, 700));
		//if(!doubleJump && !grounded)
		//	doubleJump = true;
		}
	}

//method the flip the world, once the player moves in the other direciton
void Flip()
{
	facingRight = !facingRight;
	Vector3 theScale = transform.localScale;
	theScale.x *= -1;
	transform.localScale = theScale;
}

//groundcheck, I did not do this with a linecasts, just got that code from another script somewhere

void GroundCheck()
{
	grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);

	anim.SetBool("Ground",grounded);
}

//controlls the input of the player
float Controlling()
{
	float move = Input.GetAxis ("Horizontal");

	if (move != 0f) {
		anim.SetBool ("PlayerAlt2_Run", true);
	} 

	else 
	{
		anim.SetBool ("PlayerAlt2_Run", false);
	}

	rb.velocity = new Vector2(move * maxSpeed, rb.velocity.y);
	return move;
}
//checks, wether the player pressed space and communicates with the animator

void PressedSpace()
{
	pressedSpace = false;
	anim.SetBool("pressedSpace",pressedSpace);

	if (Input.GetKeyDown (KeyCode.Space) && !pressedSpace) 
	{
		pressedSpace = true;
		anim.SetBool("pressedSpace",pressedSpace);
	}
}
//method, what shall happen, once the player died
public void funPLayerDie()
	{
	scrSceneManagment.funRestartCurrentScene();
	booPlayerDied = true;

	}
//method, which controlls the damage the player can take by the enemy but also by traps etc...
public void funPlayerDamage(int dmg)
	{
	intCurrentPlayerHealth = intCurrentPlayerHealth - dmg;

	anim.SetTrigger("Damaged");

	booPlayerDamaged = true;

	}

//knockback Enumkerator, manages everything around knockbacks of the player
public IEnumerator IEnKnockback(float fltKnockDur, float fltKnockbackPwr, Vector3 ve3KnockbackDir, float fltKnockbackDir)
	{
	float timer = 0;

	while (fltKnockDur > timer)
		{
		timer += Time.deltaTime;

		rb.AddForce(new Vector3(ve3KnockbackDir.x * fltKnockbackDir, ve3KnockbackDir.y * fltKnockbackPwr * 2, transform.position.z));
		}

	yield return 0;
	}

}

First of all it would be appreciated if you would post your code with the damaging enemies, etc.

If you create a public GameObject and assigned the enemy prefab to it and then calling the damage script on the GameObject assigned above, it will always damage only the one assigned.
If you have your damage detections set up with raycasts then use the RayCastHit that you stored and and call

hit.transform.GetComponent<ScriptAttachedToEnemy>().DamageFunction(5);

Guys, please. I need help. I have a certain feeling that I miss something