- Home /
Sword Kills Enemies From Far Away
Hey guys,
I'm very new to Unity, and I'm running into some trouble right now. Here's my situation:
I have enemies that have a Box Collider on them, and a larger Sphere Collider attached as a trigger. I also have a code that makes the enemy chase the player when they Enter the Sphere Collider (trigger). Here's that code.
#pragma strict
//This script makes the enemy chase the player if they are close enough
// and change color to show if they are chasing or not.
var enemyTarget : Transform;
var shouldLook : boolean = false;
var speed : int = 2;
var enterGrowl : AudioClip;
var exitGrowl : AudioClip;
function Start ()
{
this.renderer.material.color = Color.blue;
animation.CrossFade("idle");
}
function Update ()
{
//Look at target or not and move towards it or not
if (shouldLook == true)
{
this.transform.LookAt(enemyTarget);
rigidbody.velocity = transform.forward * speed;
}
}
function OnTriggerEnter(other: Collider)
{
Debug.Log("TRIGGERED BY " + other.name);
//if the thing that entered my trigger is the player...
if (other.tag == "Player")
{
enemyTarget = other.gameObject.transform;
shouldLook = true;
//make em look angry
this.renderer.material.color = Color.red;
animation.CrossFade("run");
audio.PlayOneShot(enterGrowl);
}
}
function OnTriggerExit(other : Collider)
{
if (other.tag == "Player")
{
shouldLook = false;
//make em look peaceful
this.renderer.material.color = Color.blue;
animation.CrossFade("idle");
audio.PlayOneShot(exitGrowl);
}
}
That works fine. The problem is, I have a script attached to my sword that is supposed to kill the enemies when it hits the Box Collider. However, if you have the sword activated when you enter the sphere collider, the enemy is destroyed. Here's the code for the sword:
#pragma strict
var boolTest : boolean;
static var attackMelee : boolean = true;
function Start ()
{
renderer.enabled = false;
}
/*
function OnTriggerEnter (other : Collider)
{
Destroy(other.gameObject);
}
*/
function OnTriggerEnter(other: Collider)
{
// Debug.Log ("Hello");
if (other.tag == "E1" && renderer.enabled == true)
{
Destroy(other.gameObject);
audio.PlayOneShot(clang);
// Debug.Log ("DIE BOX!");
}
}
var swordSFX : AudioClip;
var clang : AudioClip;
function Update ()
{
if (Input.GetButtonDown ("Fire1"))
{
audio.PlayOneShot(swordSFX);
}
if (Input.GetKey("mouse 0"))
{
renderer.enabled = true;
}
else {renderer.enabled = false;}
}
I want to fix it so that the sword will only destroy the enemies if it hits the box collider, but not the sphere collider which is triggering the enemies and making them chase the player.
I'm very new to Unity, and I was given these codes in a class, so I'm just trying to make them work.
Thanks guys
Answer by fafase · May 03, 2012 at 07:07 AM
Instead of the OnTriggerEnter and OnTriggerExit, you could try to check the distance,
if(Vector3.Distance(enemyTarget.position, transform.position){
shouldLook = true;
//make em look angry
this.renderer.material.color = Color.red;
animation.CrossFade("run");
audio.PlayOneShot(enterGrowl);
if(!exiting) //Boolean for exit logic
exiting = !exiting;}
else{
if(exiting){ // create a boolean so that you enter that loop only once on exit
shouldLook = false;
//make em look peaceful
this.renderer.material.color = Color.blue;
animation.CrossFade("idle");
audio.PlayOneShot(exitGrowl);
exiting = !exiting;}
}
Now you don't need the trigger anymore, the distance will be check so ot is like having a circle around the enemy. Now your guy can come up closer to the enemy, only keep the sword colliding logic.
That could be a lead for yu to solve your issue.
That works, but the problem is that I have a lot of stuff relying on that trigger. Audio, etc.
Is there any way to change my Sword code so that it only destroys the enemy upon contact with the small box collider, but not the larger sphere collider?
Do you have both colliders (large and small) on the same object? Then maybe you could create an empty game object that you attach to the big one with the large collider and holding the collision only involves in the large one, I would think your issue right now is that you have both colliders on the same object and collision detection of both on the same script. Is that right?
Also, you could use what I gave above and add all the logic for the big box (Audio,etc) to the list.
That sounds like a good solution fafase, but how would I make the big collider on the empty game object cause the actual enemy to run his chase function? I've never tried using one script to trigger something in another script.
Just create an empty game object and add a box or sphere collider and size it as required. Then position the whole object inside the enemy and add the empty object as a child of the enemy. Add you logic to a script that you attach to the child empty object.
The use http://unity3d.com/support/documentation/ScriptReference/GameObject.GetComponentInChildren.html to reach the variable or functions. You'll see it is pretty easy and you will learn a lot with it. If you have trouble look around the forum there are plenty of examples for that.
Answer by Piflik · May 03, 2012 at 03:12 PM
OnTriggerEnter sees the trigger, OnCollisionEnter sees the collider. If you change the script for the sword to use OnCollisionEnter, it should work...theoretically ;)
Answer by SLonergan · May 03, 2012 at 10:28 PM
Just wanted to let you guys know that I cleaned up my code and solved the problem. I took fafase's advice, and attached an empty game object to each enemy to trigger the chase.
Here are my revised codes for anyone who has this problem in the future.
Enemy Script:
#pragma strict
var enemyTarget : Transform;
var shouldLook : boolean = false;
var speed : int = 2;
function Start ()
{
this.renderer.material.color = Color.blue;
animation.CrossFade("idle");
}
function Update ()
{
if (shouldLook == true)
{
this.transform.LookAt(enemyTarget);
rigidbody.velocity = transform.forward * speed;
animation.CrossFade("run");
}
if (shouldLook == false)
{
animation.CrossFade("idle");
}
}
And here's the script for the empty game object attached to each enemy:
#pragma strict
private var enemyScript : Enemy1;
var enterGrowl : AudioClip;
var exitGrowl: AudioClip;
var Enemy : Transform;
function Awake()
{
enemyScript = Enemy.GetComponent(Enemy1);
}
function OnTriggerEnter(other: Collider)
{
if (other.tag == "Player")
{
enemyScript.shouldLook = true;
audio.PlayOneShot(enterGrowl);
}
}
function OnTriggerExit(other : Collider)
{
if (other.tag == "Player")
{
enemyScript.shouldLook = false;
audio.PlayOneShot(exitGrowl);
}
}
Thanks to everyone for your help!