Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by oliver-jones · Nov 25, 2010 at 07:12 AM · prefabarraylookatturret

Mega Bug In Turret - Help

Okay, Still having problems,

I have a turret on my scene that has been duplicated a few times. All the turret does is looks at an enemy within its radius and shoots at it. The enemy are from an array (they are initiated prefabs). So every enemy that steps into the turrets radius it is added to a Generic.List. Heres what works fine: Enemy is added to the List when they enter radius (collider), and are removed when they move out. But a bug crops up when the turret manages to kill (destroy) the enemy, and some turrets targets are 'missing' due to this, therefore they just stop, and don't do anything?

Watch My Video: www.olliejones.com/TurretHelp2.mov

The turrets target is its current enemy selected on the List, so when that gets destroyed, it doesn't find a new enemy, and I don't know how to code for that not to happen.

I have 2 scripts, one called SmoothLookAt (attached to the turret) and DamageReceiver (attached to enemy prefab). I believe this is happening because one of my variables is a static, but I need this for my DamageReicver to talk to my SmoothLookAt.

Here Are My Scripts:

SmoothLookAt:

static var damping = 6.0; static var smooth = false; static var ActivateScorpionRange = false; static var ScorpionRange : float = 8;

static var Scorpion : boolean = true;

var target : Transform; var closeObjects = new System.Collections.Generic.List.<Transform>(); static var EnemyFound = false;

//static var LookAtDead = false;

function Update () {

 //---Movement of Scorpion---\\
 if(Scorpion == true)
 {
     if (smooth) //Smooth Rotation\\ -- Note To Self - damping = lagged fire
     {
         if(closeObjects.Count == 0)
         {
             target = null;
             return;
         }

         target = closeObjects[0];
         var rotation = Quaternion.LookRotation(target.position - transform.position);
         transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
         BroadcastMessage("Fire");

     }
     else //Snap Rotation\\
     {
         //Make sure there is an enemy. \\
         if(closeObjects.Count == 0)
         {
             target = null;
             return;
         }

         target = closeObjects[0];
         transform.LookAt(target);
         BroadcastMessage("Fire");
         //closeObjects.Remove(transform);

     }
 }

 //DamageReceiver uses this to remove target once destroyed \\
 if(DamageReceiver.Dead == true) // I BELIEVE THIS MIGHT BE THE PROBLEM - STATIC!
 {
     closeObjects.Remove(target);
     target = null;
     DamageReceiver.Dead = false;
     return;
 }       

}

//When an enemy enters the trigger, add them to the list.
function OnTriggerEnter (enemy : Collider) { closeObjects.Add(enemy.transform); }

//When they leave, take them off of the list.

function OnTriggerExit (enemy : Collider) { closeObjects.Remove(enemy.transform); }

DamageReciver:

var hitPoints = 10.0; var detonationDelay = 0.0; var explosion : Transform; var deadReplacement : Rigidbody; var credits = 100;

static var Dead = false; //this is used to tell SmoothLookAt the enemy has been destroyed - now remove it from list.

function ApplyDamage (damage : float) { // We already have less than 0 hitpoints, maybe we got killed already? if (hitPoints <= 0.0) //credits += 100; return;

 hitPoints -= damage;
 if (hitPoints &lt;= 0.0) {
     // Start emitting particles
     var emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);
     if (emitter)
         emitter.emit = true;

     Invoke("DelayedDetonate", detonationDelay);
 }

}

function DelayedDetonate () { Dead = false; BroadcastMessage ("Detonate"); //BroadcastMessage("LookAtDead"); Dead = true; }

function Detonate () { // Destroy ourselves

 //GetComponent closeObjects.Remove
 Destroy(gameObject);

 // Create the explosion
 if (explosion)
     Instantiate (explosion, transform.position, transform.rotation);

 // If we have a dead barrel then replace ourselves with it!
 if (deadReplacement) {
     var dead : Rigidbody = Instantiate(deadReplacement, transform.position, transform.rotation);

     // For better effect we assign the same velocity to the exploded barrel
     dead.rigidbody.velocity = rigidbody.velocity;
     dead.angularVelocity = rigidbody.angularVelocity;
 }

 // If there is a particle emitter stop emitting and detach so it doesnt get destroyed
 // right away
 var emitter : ParticleEmitter = GetComponentInChildren(ParticleEmitter);
 if (emitter) {
     emitter.emit = false;
     emitter.transform.parent = null;
 }

}

Please help me out, this has been bothering me for sometime now, and I can't make any progress with my game until this is fixed.

Thanks, Ollie

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Nov 25, 2010 at 07:25 AM 0
Share

Something tells me that I'm going to need to put the turrets in an array too

5 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Kliffy · Nov 25, 2010 at 09:15 PM

What about something like: if(target==null && closeObjects.count > 0) { closeObjects.Remove(target); }

in the update script

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Nov 25, 2010 at 09:43 PM 0
Share

O$$anonymous$$G!! It works!! thank you so much, you have no idea how much I appreciate that! Been stuck on it for weeks! Urh, such a simple code too! Soo ANGRY! -- URH - TANTRU$$anonymous$$!!

avatar image oliver-jones · Nov 28, 2010 at 02:44 PM 0
Share

Just a quick question - How would I also add a " && tag = "enemy"" within that too?

avatar image
0

Answer by Kliffy · Nov 25, 2010 at 09:17 AM

http://technology.blurst.com/unity-physics-trigger-collider-examples/

An object destroyed inside of a trigger will not send OnTriggerExit events. This link will explain a fix if you think this is your problem.

Err never mind you seem to understand this. Well it is a good link anyway.

Do the dead turrets ever get removed from the list?

I'm not an expert on static but it could mean that there is one DamageReceiver.Dead for all DamageReceiver components. So you should perhaps make Dead public and not static. Also, the unity convention would be dead (lowercase) since it is a variable.

It does not need to be static. Here's an idea:

function OnTriggerEnter (enemy : Collider) { closeObjects.Add(enemy.gameObject); }

Keep a list of gameObjects instead of transforms. Then you can call:

transform.LookAt(target.GetComponent(Transform));

or

if(target.GetComponent(DamageReceiver).dead) { //blah }

Oops again. I guess I assumed DamageReceiver was a component of all target gameobjects.

In any case, there is certainly a solution without that static and an array of gameObjects could help with that.

I dunno I gotta go to sleep.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Nov 25, 2010 at 09:52 AM 0
Share

Haha, okay thanks - go sleep! Would appreciate any help from others. Cheers

avatar image oliver-jones · Nov 25, 2010 at 02:35 PM 0
Share

$$anonymous$$aybe you can help me by expanding on this when you wake up, I'm not very strong at coding and I'm just lost. When I use GetComponent I get an ExceptionalError: Object reference not set to an instance of an object. And all that happens the turret tracks and kills the first enemy. Then does not track another others.

avatar image
0

Answer by _Petroz · Nov 25, 2010 at 10:24 AM

Looking at your code comments it appears the only reason 'Dead' is static is so that it is visible inside SmoothLookAt. Using statics and BroadcastMessage for communication between classes is not needed when you have an instance of the object. I agree that you should use GetComponent as Kliffy suggested.

Get an instance of your script component from the Transform and call functions on it directly.

I noticed you are using quite a few static variables. Static variables are easy to use because they're accessible everywhere, but they have major drawbacks and should be used sparingly. Having global scope means whenever you have a bug, that variable is in visible so it can't be ruled out, implicitly increasing the complexity of all your code. Another issue is everything can modify it, so if you've discovered that a variable has the wrong value you can't make any assumptions about what changed it, again because everything has access.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Nov 25, 2010 at 10:29 AM 0
Share

Noted! Thanks Petroz, is there a possibility of a code example? Thanks

avatar image
0

Answer by Kliffy · Nov 25, 2010 at 05:43 PM

I'm not sure what causes that error based on what I have in front of me. But, I would use your ontriggerenter/exit to make a list of GameObjects of targets. I would make dead a public var. You could just make a function

function IsDead() { return dead; }

and you can call that from the turret script. In that case dead could even be private, and you could make a function for the turret to call to change dead from true to false. And then each target will have its own dead variable.

What is dead receiver attached to currently? When you tell it to Destroy(gameObject) I'm not sure how the subsequent stuff gets called although I guess the destruction happens at the end of the frame?

If you are worried with my implementation that the gameobject will be destroyed before the turret can see that they are dead, you can send a time variable to Destroy(gameobject, time) to have it be destroyed after a certain length of time which would allow a dying animation to be played and while the turret realizes the target is no longer worth shooting / looking at because it is dead.

My guess is that you have multiple turrets changing that static dead back and forth, as well as different targets changing it back and forth and at some point it gets changed in a way / order that you did not intend and causes the bug.

Also if you try to do my suggestion, dead would be a var called in the constructor (aka at the top and outside of functions) of DamageReceiver and it would originally be set to false. And then I presume that the detonation script would just send the message and set dead to true.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Nov 25, 2010 at 06:46 PM 0
Share

What I reckon what it might be: eg: Turret A and Turret B are both tracking the same enemy, Turret A kills the enemy, thus Turret B's target it was just tracking is set to 'missing' and therefore doesn't do anything. I think that is what is causing the problem now. How would I fix this?

avatar image
0

Answer by Kegrah · Oct 05, 2011 at 10:47 PM

I've been working on a similar thing for my tower defense, I got this code up and working last night with the use of GameObject.FindGameObjectsWithTag to just search for anything tagged as Enemy (just tag your enemy prefab and it should work out). Oh and you'll probably have to swap out the GetComponent for the decrement of enemy health with whatever your enemy script name and health value in the firing function

 var closest : GameObject;
 var rotSpeed : float = 3;
 var enemyFound : boolean = false;
 var shootRange : float = 35.0;
 
 
 function Update(){
     FindClosestEnemy();
 
     if(enemyFound){
         var targetRot = Quaternion.LookRotation(closest.transform.position-transform.position);
         transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime * rotSpeed);
 
         if(Vector3.Distance(transform.position, closest.transform.position) < shootRange){
             FireAtEnemy();
         }
     }
 }
 
 function FindClosestEnemy () : GameObject {
     var distance = Mathf.Infinity; 
     var position = transform.position; 
 
     var gos : GameObject[];
     gos = GameObject.FindGameObjectsWithTag("Enemy");
 
     for (var go : GameObject in gos)  { 
         var diff = (go.transform.position - position);
         var curDistance = diff.sqrMagnitude; 
         if (curDistance < distance) { 
             closest = go; 
             distance = curDistance;
             enemyFound = true;
         } 
     } 
     return closest;
 }
 
 function FireAtEnemy(){
     var enemyHP = closest.GetComponent("enemyScript");
     enemyHP.health = enemyHP.health -1;
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

1 Person is following this question.

avatar image

Related Questions

Prefab not loading in data from Inspector 1 Answer

Array of Arrays of GameObjects/Prefabs (C#) 1 Answer

How to make a GameObject separate from a prefab? 0 Answers

transform.LookAt causes my object to explode 1 Answer

Rotate Turret to Tag 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges