Attacking multiple enemies

Hi I’m new to the Unity community and was wondering if anyone could help me with my problem.

My problem is that I want to be able to attack multiple mob monsters with the distance/direction detector (Since collision detection doesn’t work with my animations). I was wondering if someone could guide me into how to go about doing it. I’ve been stumped for a few days now, and even thought about changing the target to be an array target, but errors kept popping up and further stumping me.

Here is an example of what I have right now:

var target: GameObject;

function AttackWhip02() {

[INDENT]attackMove = true;
attackMoveSpeed = 2.5;
yield WaitForSeconds (.25);

var distance: float = Vector3.Distance(target.transform.position, transform.position);
var dir: Vector3 = (target.transform.position - transform.position).normalized;
var direction: float = Vector3.Dot(dir, transform.forward);

if(distance < 3.0f) {
[INDENT]if(direction > 0.40) {
[INDENT]var enemyHealth = target.GetComponent(EnemyHealth);
enemyHealth.AdjustCurrentHealth(-16);[/INDENT]
}[/INDENT]
}

attackMove = false;
attackMoveSpeed = 0;[/INDENT]
}

I uploaded what I have so far to hopefully understand what I want: http://thedistantvoice.com/WebPlayer/NEW_Aug20/WebPlayer.html
The mob would swarm you and you can only target one at a time [left shift for target] (targetting is bugged right now so you may not be able to tell who you CAN attack)

I’d be grateful for anyone who could give me input as to how I can go about with it. and I hope I’m submitting it in the right section.

Use Raycast for detection etc…

RaycastAll is what you want.

Thanks for the response!

Although it limits the area I want if it solves my problem of being able to attack multiple enemies, I can deal with it.

This is what I was able to come up with:

var target: GameObject;

function Start(){
[INDENT]target = GameObject.FindWithTag("Enemy");[/INDENT]
}

function AttackSword01(){

	if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), 10)){
		var enemyHealth = target.GetComponent(EnemyHealth);
		enemyHealth.AdjustCurrentHealth(-10);
[INDENT]}[/INDENT]
}

This works but for only one enemy still, I tried changing the target variable to an array but that doesn’t seem to help, could someone guide me in the right direction to make it so I can attack multiple enemies? Not sure what or how to begin using RayCastAll if that’ll solve my problem, the few explanations of it I found online just confused me more.

function AttackSword01(){
	var hits : RaycastHit[] = Physics.RaycastAll(transform.position, transform.forward, 10);
        if( hits != null ) {
            for(var i: int = 0; i < hits.Length; i ++){
                var enemyHealth : EnemyHealth;
                if(hit.collider.CompareTag("Enemy")  ( enemyHealth = hit.collider.GetComponent(EnemyHealth) ))
            		enemyHealth.AdjustCurrentHealth(-10);
                }
            }
        }
    }
}

I’m not fluent in JS but something like that. No need to do the search in Start()

Whoa thanks for the speedy response! I fixed up the coding a bit:

function AttackSword01(){

	var hits : RaycastHit[] = Physics.RaycastAll(transform.position, transform.forward, 10);
        if( hits != null ) {
            for(var i: int = 0; i < hits.Length; i ++){
                var enemyHealth : EnemyHealth;
                if(hits.collider.CompareTag("Enemy")  ( enemyHealth == hits.collider.GetComponent(EnemyHealth))){
            		enemyHealth.AdjustCurrentHealth(-10);
            		print ("attack");
                }
            }
      	}
}

After I tested this out there was an error that I’m not sure how to fix :

NullReferenceException: Object reference not set to an instance of an object
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.String cacheKeyName, System.Type[ ] cacheKeyTypes, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.GetDispatcher (System.Object target, System.Object[ ] args, System.String cacheKeyName, Boo.Lang.Runtime.DynamicDispatching.DispatcherFactory factory)
Boo.Lang.Runtime.RuntimeServices.Invoke (System.Object target, System.String name, System.Object[ ] args)
AnimationScript+$AttackSword01$22+$.MoveNext () (at Assets/Scripts/AnimationScript.js:490)

Which seems to refer to this line:

if(hits.collider.CompareTag("Enemy")  ( enemyHealth == hits.collider.GetComponent(EnemyHealth))){

Unless you meant to stick this code in which would explain the change from “hits” to “hit” in your coding:

var hit : RaycastHit = hits[i];

After trying that, there were no errors, but no damage was being dealt when I was attacking.

sorry it should be hits_.collider.CompareTag and hits*.collider.GetComponent(EnemyHealth);_
If it helps heres what it would look like in C# ( which i use )
_
*_ <em>*void AttackSword01() { EnemyHealth enemyHealth; foreach( var hit in Physics.RaycastAll( transform.position, transform.forward, 10f ) ) if( hit.collider.CompareTag("Enemy") ( enemyHealth = hit.collider.GetComponent<EnemyHealth>() ) ) enemyHealth.AdjustCurrentHealth(-10); }*</em> _*_
I just noticed in your code you used a equality check instead of a set.
I’m setting the value and testing the existance of it ( basically for short hand ). If heres what the expanded code would look like:
_
*_ <em>*void AttackSword01() { foreach( var hit in Physics.RaycastAll( transform.position, transform.forward, 10f ) ) { if( hit.collider.CompareTag("Enemy") ) { EnemyHealth enemyHealth = hit.collider.GetComponent<EnemyHealth>(); if( enemyHealth ) enemyHealth.AdjustCurrentHealth(-10); } } }*</em> _**_

Ah, I used the equality check since it was placed in the condition section (if), I guess that’s different in C# and JS? I did my best converting C# to JS (used to it by now) and ended up with:

for(var hits in Physics.RaycastAll(transform.position, transform.forward, 10)){
                var enemyHealth : EnemyHealth;
                if(hits.collider.CompareTag("Enemy")){
                	enemyHealth = hits.collider.GetComponent(EnemyHealth);
            		enemyHealth.AdjustCurrentHealth(-10);
            		print ("attack");
                }
            }

And it works! Thanks for much BDev! Now I have to find a way to prevent my players and monsters from falling off the terrain when attacking… =P

I truly appreciate your help and speedy resonses BDev! Shares Mango Pudding =D

Glad it works! You may want to modify it a bit like so:

                if(hits.collider.CompareTag("Enemy")){
                	enemyHealh = hits.collider.GetComponent(EnemyHealth);
                        [B]if( enemyHealth ) {[/B]
            	    	    enemyHealth.AdjustCurrentHealth(-10);
            		    print ("attack");
                        [B]}[/B]
                }

just incase the enemy for some reason didnt have a EnemyHealth Component. I don’t know if JS allows for non conditionals inside a if statement, but yea C# does. I was setting the variable and then checking that the variable wasnt null/non-existant, Its just to keep the line count down though and it may or may not be more legible. Cheers