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
0
Question by BilboStabbins · Feb 15, 2013 at 05:35 PM · rigidbodyspawnerpoolangry bots

AngryBots bullet spawner - Some help to convert to use Rigidbodies?

I'd like to make use of the bullet pool spawning system used in Angry Bots which keeps a pool of bullet objects in the scene for instant use. The system uses translation to move the bullets however which isn't right for the game I'm working on. So I would like to instead make it use Rigidbodies and move the bullets using AddForce().

I've tried firing the bullet from various places, in both the Spawnng script and the Destroying but the results seem to vary. For instance, the bullets either speed up as I'm firing, or the system won't recycle them correctly.

There are 2 brief scripts which are shown below. One Spawns the bullets and the other fires them (using translation) and them destroys them after a specified time. They have been converted to C# from the original JS in AngryBots with only the relevant sections shown.

Any help would be great - Thanks.

SimpleLaser

 using UnityEngine;
 using System.Collections;
 
 public class SimpleLaser : MonoBehaviour
 {
     public Vector3 Direction = Vector3.zero;
 
     public float lifeTime = 2f;
 
     private float spawnTime = 0.0f;
 
     public bool destroyForMe = false;
 
     public float ShotForce;
 
     public void OnEnable()
     {
         Debug.LogWarning("OnEnable"); 
 
         // The time this object spawned
         spawnTime = Time.time;
 
         gameObject.rigidbody.velocity = Vector3.zero;
         gameObject.rigidbody.angularVelocity = Vector3.zero;
 
         // This is the force being added. 
         gameObject.rigidbody.AddForce(Direction * ShotForce); 
     }
 
     void Update()
     {
         if (Time.time > spawnTime + lifeTime) // ||dist < 0)
         {
             Debug.LogWarning("Spawner.Destroy(gameObject)");
 
             Spawner.Destroy(gameObject);
         }
     }
 }


EnemyBehaviour

     public IEnumerator DoFireAnim()
     {
         // Causes the coroutine to repeat
         while (true)
         {
             Enemy_Anim_obj.animation[roll.name].speed = 2;
             Enemy_Anim_obj.animation.CrossFade(roll.name, 0.2f);
 
             yield return new WaitForSeconds(RollTime);
 
             Enemy_Anim_obj.animation.Stop(roll.name);
 
             Enemy_Anim_obj.animation[open.name].speed = 2;
             Enemy_Anim_obj.animation.CrossFade(open.name, 0.2f);
 
             if (Enemy_Anim_obj.animation.IsPlaying(open.name))
             {
                 // Wait
             }
             else
                 Enemy_Anim_objEnemy_Anim_obj.animation.CrossFade(idle.name, 0.2f);
 
             yield return new WaitForSeconds(0.3f);
 
             shootingFlag = true;
 
             Debug.Log("Called Shoot()");
 
             // Enough time to fire bullets
             yield return new WaitForSeconds(0.6f);
 
             Enemy_Anim_obj.animation.CrossFade(close.name, 0.2f);
         }
     }
 
     
     //--------------------------------------------------------
     void FixedUpdate()
     {     
          if (shootingFlag)
          {
              Debug.LogWarning("SHOOTING");
 
 
              GameObject newLaserProjectile_L = Spawner.Spawn(LaserProjectile,
                                                          Left_gun.position,
                                                          Left_gun.rotation) as GameObject;
 
              Vector3 L_GunBulletDir = playerTarget_obj.transform.position - Left_gun.transform.position;
 
              newLaserProjectile_L.transform.rotation = Quaternion.LookRotation(L_GunBulletDir);
 
              newLaserProjectile_L.GetComponent<SimpleLaser>().Direction = L_GunBulletDir;
              newLaserProjectile_L.GetComponent<SimpleLaser>().OnEnable();
 
              shootingFlag = false;
          }         
     }
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 Benproductions1 · Feb 18, 2013 at 03:42 AM 0
Share

It would be easier to write a specific system that handles the bullets for your specific reason, rather than using angryBots's

1 Reply

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

Answer by Ellandar · Feb 21, 2013 at 02:47 PM

I haven't actually looked at angryBots so I'll just go by what I'm thinking.

If you are going to fire bullets using force instead of controlling it's position, you'll need to approach the problem slightly differently.

Instead of fireing the bullet, and then maintaining it's trajectory/speed within an Update() like the "Fireing and Destroying" scripts seems to do in your example, you probably should create your own script to control the bullet.

Create a script, add it to your bullets. You may want to pass in some variables (direction?). The moment you enable the bullet, it will fire itself straight forward if you don't change anything.

 public void OnEnable()
 {
     spawnTime = Time.time;              //time this object spawned
     Vector3 direction = gameObject.rigidbody.forward;    //direction to shoot, modify at will
     float forceToApply = 25;            // higher number = faster travelling bullet.
     gameObject.rigidbody.AddForce(direction * forceToApply ) // This is the force being added.  
 } 
 
 public void Update()
 {
     // Some code in here to track time and to relocate the bullet to your pool when timeout occurs.
 }


Notes: If you move a rigidbody by relocating it's position you should also stop it first:

 rigidbody.velocity = Vector3.zero;
 rigidbody.angularVelocity = Vector3.zero;

If you move your bullet too fast, it may travel through any colliders you want it to hit before the game has a chance to trigger the collision.

Let me know if you want more info, I'll see what I can come up with.

Sources: http://docs.unity3d.com/Documentation/ScriptReference/Rigidbody.AddForce.html

Comment
Add comment · Show 8 · 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 BilboStabbins · Feb 26, 2013 at 03:59 AM 0
Share

Hi Ellandar and thanks for the help.

I've implemented the method you've suggested and it looks like the pooling doesn't work. The projectiles are being destroyed very quickly even though I have the lifeTime set to 2 seconds. I have also disabled any collision scripts to eli$$anonymous$$ate them being destroyed by other things.

The way the code works is that I have a coroutine which is first called by a trigger that the Player enters (for proximity to the enemy) - this is called only once. The coroutine carries out an enemy's animations and then sets a boolean (called shootingFlag) to true. This causes the statements in FixedUpdate to execute. FixedUpdate Instantiates the projectile and sets its direction.

It then passes the direction the bullet should travel in to SimpleLaser and then calls its OnEnable() function. I was initially passing the direction as a parameter to OnEnable by received an error a couple of times so am now setting it but using the global variable Direction ins$$anonymous$$d.

I have set the the cache size on the object in the Inspector to 4, but have tried larger values with no change in behaviour.

Please see above for the updated code.

Thanks again

avatar image Ellandar · Feb 26, 2013 at 04:41 AM 0
Share

G'day Bilbo,

Caught me at work at the moment, so not a lot of time to look at this. A couple of initial things that might help you on the path:

  1. Add Debug.Log(this.name +" has been alive: " +(spawnTime + lifeTime) to your SimpleLaser's Update() just before the destroy in the if statement. That'll probably help with debugging a bit, especially if you are na$$anonymous$$g your bullets along the limes of bullet_1, bullet_2, etc.

  2. Just before: "shootingFlag = True;" add another Debug.Log(newLaserProjectile_L.name +" was just spawned at: "+Time.time);

That should allow you to see the real time passed between spawn and destroy, especially helped if each of your bullets/lasers are named numerically.

Once I get home in 3 1/2 hours I'll sit down and take a proper look at the code (if no one else has chimed in and sorted it by then).

Ell.

avatar image Ellandar · Feb 26, 2013 at 10:38 AM 0
Share

From what I can see, your code should work. The only thing I can think of is that your spawner is not in fact spawning a new laser/bullet, but reusing the one that's on the screen somehow? Thus resetting it before it gets a chance to actually travel anywhere?

Ell

avatar image BilboStabbins · Feb 26, 2013 at 03:18 PM 0
Share

Excellent, so the Console output has helped to show me what's going on now :)

Basically when I completely turn off the collider on the projectile, the pooling works O$$anonymous$$ - so I can deal with that later.

I've attached an image of the Console output. One thing that's a little concerning is that OnEnable is being called twice for every projectile instantiation. Now, although the pooling works, the force that its fired at starts off slow (for about 4 shots or so) and then speeds up and pla$$anonymous$$us at a faster speed. Not sure what would be causing this, as I've set both the velocity and angular velocity of the projectile to 0 each time before firing.

Image

Thanks for the help

avatar image Ellandar · Feb 27, 2013 at 12:08 AM 1
Share

$$anonymous$$eeting got canceled, yay. Ok, the way force works is it's added (using Force) over time usually. If we change to one of the alternative methods (http://docs.unity3d.com/Documentation/ScriptReference/Force$$anonymous$$ode.html) we can probably fix that.

I'd probably use VelocityChange in s$$anonymous$$d of Force, as this is an instant application of force and it ignores the mass value (so it'll go really fast, quickly). It's applied as a function of distance/time, in this case units per second i'd say (u/s). Short version here is, higher number = faster.

Start with:

 gameObject.rigidbody.AddForce(Direction * ShotForce,Force$$anonymous$$ode.VelocityChange);

and see how it goes.

Show more comments

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

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Why does the bullet has wrong direction? 1 Answer

A question about the Angry Bots demo. 0 Answers

AddExplosionForce doing nothing? 1 Answer

Rotation problem with spawning bullet 2 Answers

[SOLVED] GameObject pooling is not returning enough objects! 0 Answers


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