VariaBULLET2D Projectile System (Create Patterns Visually)

A place for people with an interest in developing new shmups.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

All of these aspects of collisions/globalshotmanager is covered in the System guide:
https://neondagger.com/variabullet2d-system-guide/

The reason why the explosion prefabs are referenced by the string name rather than directly loading in the inspector is because it would mean every shot or collidable object would have an instance of the explosion loaded into memory. It's better to just have a pool of explosions that can be referenced by any object in the scene that needs it.

But the problem isn't with the string itself, but more likely you're loading the explosions in the wrong GlobalShotManager.

I've separated the GlobalShotManager used in demos as the one in the "Demo" folder and the one that you should be using for your own projects in the root folder.

Check out the paragraph in the System guide referenced above for a clearer description:
https://neondagger.com/variabullet2d-system-guide/#globalshotmanager

You can force instantiation of the correct GlobalShotManager by attaching the "ForceGlobalShotManager" script to a persistent gameobject (EG, Camera) and make sure "Demo Version" is unchecked.
https://neondagger.com/variabullet2d-system-guide/#lazy-vs-forced-instantiation

At the bottom of the guide is a checklist of common hiccups to look out for:
https://neondagger.com/variabullet2d-system-guide/#troubleshooting
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

I feel glad that I have experimented with your asset more, and it became very easy for me to make derived classes thanks to well-documented and component-based code.

I managed to create a derived class from ShotCollisionDamage that enables children to explode instantly and modified base to allow objects with ShotCollisionDamage to instantly explode on command. Comes in handy for multiple parts to explode. I don't know of any pre-existing solutions yet, but made one up myself.

Feel free to PM or e-mail me if you're interested in seeing some changes that might come in handy.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

MrJBRPG wrote:I managed to create a derived class from ShotCollisionDamage that enables children to explode instantly and modified base to allow objects with ShotCollisionDamage to instantly explode on command. Comes in handy for multiple parts to explode. I don't know of any pre-existing solutions yet, but made one up myself..
Ah, very cool! That's a neat little extension. I definitely see the utility in that.

I'll be looking to add to VB very soon here and I got your email and will probably hit you up for some recommends and/or your solutions to potentially add to it.
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

I have played around with your demo scenes more and noticed that while bullets will go out of bounds for a certain time until destroyed or re-pooled. However, all laser shots are not removed when going out of bounds. I have even tested that on your Horizontal Shooter demo scene. with the packet laser being shot from boss object, and they never get destroyed, with and without enclosure boxes. Can you find a way to destroy bullets after exiting the screen boundaries, translating from pixel to world coordinates?

I also discovered that the default packet laser actually stops stretching and will not move until the laser is released. My project has much bigger play field and lower numbers of pixels per unit compared to your sample projects. I wonder how that works and whether you can enable users to set limits on stretching.

One more thing, is there a way to allow laser packets by creating multiple copies of multiple unique middle sections? Several shooting games have lasers that have spiral-like animations around the 'tube'.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

MrJBRPG wrote:I have even tested that on your Horizontal Shooter demo scene. with the packet laser being shot from boss object, and they never get destroyed, with and without enclosure boxes.
This was actually a pretty simple fix. I just never noticed the issue because I moved some code around and it obviously broke here.

ShotLaserPacket class has an override for the usual OnOutBounds() method. Everything is fine there, but the method is never called! That's because it used to be called in ShotBase (which is what ShotLaserPacket inherits from), but was moved into ShotBullet instead because... well, who knows what I was thinking at the time lol.

Bottom line, to fix this across the board simply remove the OnOutBounds call in ShotBullet.Update() and move that call instead to the base class ShotBase.Update(). IE: the ShotBase.Update() will now read as:

Code: Select all

        public virtual void Update()
        {
            OnOutBounds(); //moved from ShotBullet
            scale = (IgnoreGlobalSpeedScale) ? 1 : GlobalShotManager.Instance.SpeedScale;
            scaledSpeed = ShotSpeed * scale;
        }
You can update this on your end or wait until the fix shows up in the next version update.

MrJBRPG wrote:I also discovered that the default packet laser actually stops stretching and will not move until the laser is released. My project has much bigger play field and lower numbers of pixels per unit compared to your sample projects. I wonder how that works and whether you can enable users to set limits on stretching.
That's interesting. I'm not reproducing that on my end, but essentially lasers stop stretching when they've reached the edge of the camera boundary + a quarter of either the camera width (if a horizontal viewport) or a quarter of the height (if vertical viewport). So, something isn't detecting the correct boundary it seems. The code that handles that and you can tinker with is found in ShotLaser.Start() and commented here:

Code: Select all

        public override void Start()
        {
            collidesWith = Physics2D.GetLayerCollisionMask(gameObject.layer);
            globalDirection = (transform.parent.lossyScale.x < 0) ? -1 : 1;

            if (Screen.width > Screen.height)
                maxDistance = (int)(Screen.width + Screen.width / 4f) * globalDirection; //max distance for horizontal viewports
            else
                maxDistance = (int)(Screen.height + Screen.height / 4f) * globalDirection; //max distance for vertical viewports
MrJBRPG wrote: One more thing, is there a way to allow laser packets by creating multiple copies of multiple unique middle sections? Several shooting games have lasers that have spiral-like animations around the 'tube'.
Yes, very good question. I also had this idea during development but wasn't sure of the least messy way to handle it. Probably the best way to do this in later versions of Unity is to use the sprite-masking feature in the SpriteRenderer. But earlier versions don't have masking so the best way to do that is to copy little chunks of the mid section as different points in the animation. The trouble with that is it could load up a ton of gameobjects for each chunk, and doesn't look as smooth as each chunk gets instantiated in sections.

So yeah, sprite masking is probably the way to go. I'll revisit this for sure as it makes for more interesting animations.

Great finds/tips as usual. And let me know if you have any luck with the laser distance issue!
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

IN response to the three answers you made, I have tried the following:

On Out Of Bounds moved to ShotBase instead of ShotBullet actually works.

Max Distance and main laser scaling issues -
I noticed that the default laser sprites are measured in 100 pixels per unit, and made a copy that does 1 pixel per unit. When I tested them out on my custom scene that has a far bigger camera size (168.5 rather than 18, 24, or 32), the laser scaling is quite off from decreasing pixels per unit to 1.

To solve the problem of the laser stretching, you might want to reconfigure the origin point so that the start piece is invisible, the main piece always scales from the absolute starting tip (assuming that laser is oriented from left (start) to right (front / blast) from original picture), and the front / blast piece is always attached to the absolute front tip of the main piece to scale appropriately.

Somehow I am somewhat convinced that the laser packet could be rewritten to allow custom pixel per unit calculation (all parts must conform to the same pixel per unit [ppu]) or something that is more adjustable with slightly varying ppu scaling of those sprites.

As for the sprite masking and concern of creating too many game object instances, why not try a tiled version, like a repeating background that animates, but applied to a laser? That might require the individual to have the middle be an animated sprite, but converted into a tiled version.


-------


When I played around with the asset more and watched other games for research, I am thinking of a few more questions:

Is is possible to allow explosions to actually deal damage, by treating as a shot? It seems that the explosion is the only object that disappears after completing the animation.
I wonder if you can implement a shot bullet animated, with new options of number of loops before disappearing and animation style of forward and reverse / forward only, like the ping pong effect?

I have seen older games that did not have transparency, but relied on shots appearing and disappearing when the animation is finished, like flame throwers and napalm bombers.

I do enjoy tinkering with the asset so far.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

VariaBULLET2D v1.04 has been submitted and should be coming out in a couple of days. The main new addition is what I'm calling SUPER LASERS (DDP style, omnidirectional lasers).
Image


A short video showing how they operate:
https://youtu.be/mQ8rjwIXVKQ

And a new section added to the documentation, scroll to the "Super Laser" section under Laser Shots:
https://neondagger.com/variabullet2d-in ... aser-shots
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

MrJBRPG wrote:Somehow I am somewhat convinced that the laser packet could be rewritten to allow custom pixel per unit calculation (all parts must conform to the same pixel per unit [ppu]) or something that is more adjustable with slightly varying ppu scaling of those sprites.
Yeah anticipating the end user PPU, camera settings, orientation and how they handle boundaries has been surprisingly difficult! V1.04 is coming out soon (see post above) and one of the new additions is a field "Added Max Distance" on lasers to extend how far they reach in case the system miscalculates. It's still not going to cover all possible scenarios and I'll have to look closer at 1PPU situations to see what kind of bugs pop up.

I did fix a few other bugs that may be related to what you're experiencing. Guess I'll have to wait and see what you think!
MrJBRPG wrote: As for the sprite masking and concern of creating too many game object instances, why not try a tiled version, like a repeating background that animates, but applied to a laser? That might require the individual to have the middle be an animated sprite, but converted into a tiled version.
So in the above video you'll see the new Super Lasers that I implemented based on your original question. I decided to use the sprite masking method I mentioned, and while doing that I noticed how a lot of lasers in games like DDP have a tiling technique to make it seem like they flow infinitely. I used that technique in the demo laser and (provided that the user tiles the middle segments correctly) it's just a matter of enabling the "Stagger Animations" toggle to make this all work.

Turns out that there were some odd issues also that I had to figure out like when right up close to a target, what happens when the laser starting image overlaps the tip (?!!). The fix I went for ended up being to mask the end of the tip. Turned out pretty good, I think!

But really the most difficult part was getting the lasers to correctly raycast (boxcast, actually) on an angle allowing for 360 degree rotation, and also considering some users might flip the x-axis (as in a run n gun game). So all of that took a bit more time to test out.

MrJBRPG wrote: Is is possible to allow explosions to actually deal damage, by treating as a shot? It seems that the explosion is the only object that disappears after completing the animation.
I wonder if you can implement a shot bullet animated, with new options of number of loops before disappearing and animation style of forward and reverse / forward only, like the ping pong effect?
I had originally considered allowing emitters to be treated as explosions. So basically using the same bullet system to instantiate explosions. There's still a way to hack that out and I'll give you an example in a minute (and it allows for "explosions" that also cause damage), but the main issue with actually allowing those kinds of prefabs to end up in the GlobalShoManager.Explosions array is it messes with the explosion system's (rather simple) way of just looking for an Explosion script attached to an object in the explosion pool, executing it, and re-pooling.

Shots have their own routine which might be harder to predict and integrate into the explosion routine. But in principle most of what is needed is already in place to make it work, including sprite flickering, and the new shot attributes of color changing/dissipating, etc. I might have to look at how I can refactor and use something like an interface (IAnimatable, or something) that both shots and explosions use the same routines from and then just let the system run those and not worry about the details. That's possible.

That hack I was referring to is already in the system, the prefab example for it is called ParticleExplodeOnHit, and the scene that demonstrates it is called RunNGunParticleFX

Basically the shot itself carries a controller/emitter and when the shot collides with an object it triggers firing its child controller, which sets off a shot pattern in whatever pattern you set up. You can use the Colorize settings to dissipate and make it appear more like a realistic explosion effect.

It's not absolutely perfect because it means every shot carries its own "explosion." It's less performant, but I guess if you don't expect to have thousands of bullets on screen at once and using this "hack" it shouldn't be a big problem.

I'll think more about what I can do with the existing explosions system!
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

Thank you for the update, and I did notice that ShotBaseAnimatable does have inner code that detects the current frame and then does something at the end, such as AnimateOnce. I thought it was nifty because that can lead to more options such as implementing number of loops or amount of time bullet can stay appearing before disappearing.

I am currently trying to make a subclass from ShotBaseAnimatable that enables bullets to expire based on the number of loops from the animation, and it seems to be tricky. Basically the idea behind that is that it check the current frame of the animated bullet per update, and if it reached the end with "Loop Limit" enabled, then increase the current loop by 1 until you reach target number of loops before bullet will disappear or explode.

If I can pull that off, I can share that with you through email. Maybe have that option inside the ShotBaseAnimatable.

At least that can be a nice alternative compared to having to have an explosion tacked on to each shot.

I got one more question for you:

If I want a shot to persist while allowing damage to flicker, how can that be done?
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

MrJBRPG wrote:I am currently trying to make a subclass from ShotBaseAnimatable that enables bullets to expire based on the number of loops from the animation, and it seems to be tricky. Basically the idea behind that is that it check the current frame of the animated bullet per update, and if it reached the end with "Loop Limit" enabled, then increase the current loop by 1 until you reach target number of loops before bullet will disappear or explode.
I think that's a good idea and it sounds like you're on the right track for how to implement it. The BasicAnimation object in ShotBaseAnimatable uses a Timer object to determine when an animation should loop back around. It does this whenever Timer.Flag returns true. So, what you can do in ShotBaseAnimatable is probably check how many times this Timer.Flag became true, use a counter to increment based on that, and then when that counter reaches the loop limit, set a public bool in ShotBaseAnimatable to true (Something like ShotBaseAnimatable.LoopLimitReached).

Then in a shot class, it can check in the update if

Code: Select all

if (ShotBaseAnimatable.anim.LoopLimitReached == true)
     RePoolOrDestroy()

MrJBRPG wrote:If I want a shot to persist while allowing damage to flicker, how can that be done?
Ah, Ok. So normally when a shot collides with an object, that raises its OnCollisionEnter2D event that then triggers RePoolOrDestroy().

What you want to do is delay calling RePoolOrDestroy() after the collsion occurs. Here's how you can begin to set that up:

Let's call this hypothetical class "ShotPersistOnHit", so something like

Code: Select all

public class ShotPersistOnHit : ShotLinearNonPhysics { }

Now, delay when RePoolOrDestroy is called with something like this:

Code: Select all

public class ShotPersistOnHit : ShotLinearNonPhysics 
{ 
        bool hitDetected;
        Timer timerAfterHit;
        public int TimeLimitOnHit;

        public override void Update()
        {
            base.Update();

            if (hitDetected)
                 timerAfterHit.Run(TimeLimitOnHit);

            if (timerAfterHit.Flag
                 RePoolOrDestroy();
        }

        protected override void OnCollisionEnter2D(Collision2D collision)
        {
            //You can use the collision list to filter which collidable objects create the peristence effect. EG: you can filter out terrain, so that it does not persist when it hits a wall...
            if (CollisionFilter.collisionAccepted(collision.gameObject.layer, CollisionList))
            {
                hitDetected = true;
            }
        }

}
That's a bit messy and not perfect code. I'm sure there are some missing details needing to be debugged, but hopefully that sort of makes sense for how you'd go about getting the result you're looking to produce. Let me know!
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

While the suggestions are good for further implementation, I want to make sure things are a little more clear on the ShotPersisOnHit:

When the bullet does collide with acceptable collisions to persist, versus those that instantly remove the bullet, it seems necessary to call the OnCollisionStay2D function to enable damage seeping, as seen with various weapons that enable piercing, like pierce lasers and flamethrowers.

Gradius Gaiden with Lord British's Disruptor comes into mind:
https://youtu.be/5SkHZbvilqM?t=427

Also Fire Shark's green loop laser and red flamethrower, which actually pierces through enemy from multiple ticks:
https://www.youtube.com/watch?v=L8ZfgjzkwZw&t=53s

Perhaps that is something to think about as well.

In the meanwhile, I am going to implement my own solutions.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

Oh, silly me. I thought you meant to have the bullet stay alive after it collides with an enemy but fizzle out after a set time limit. Not sure where I got that idea from.

I guess the easiest thing for bullets and lasers is to put a bool in there that, if enabled, makes it so that OnCollisionEnter2D doesn't destroy/repool the bullets or shorten lasers.... But there will have to still be a filter if you want walls and other objects to destroy/repool.

I realize that these kinds of "piercing" bullets/lasers do show up in games fairly often, so I'm going to try to implement it as easily as possible for the next version update.
User avatar
MrJBRPG
Posts: 231
Joined: Wed Jan 04, 2017 10:42 pm

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by MrJBRPG »

casualcoder wrote:Oh, silly me. I thought you meant to have the bullet stay alive after it collides with an enemy but fizzle out after a set time limit. Not sure where I got that idea from.

I guess the easiest thing for bullets and lasers is to put a bool in there that, if enabled, makes it so that OnCollisionEnter2D doesn't destroy/repool the bullets or shorten lasers.... But there will have to still be a filter if you want walls and other objects to destroy/repool.

I realize that these kinds of "piercing" bullets/lasers do show up in games fairly often, so I'm going to try to implement it as easily as possible for the next version update.
You could still do that sort of thing too. It depends on how you prioritize those features and how straightforward or worthwhile to implement them.
User avatar
casualcoder
Posts: 346
Joined: Sat Apr 21, 2012 4:35 am
Location: West Coast, Canada

Re: VariaBULLET2D Projectile System (Create Patterns Visuall

Post by casualcoder »

Yeah I hacked a bit at the ShotBullet OnCollisionEnter2D method and used its CollisionFliter to allow bullet destruction (walls, etc), otherwise the bullet persists if "isPiercing" is true. (code below)

Kind of a goofy hack using the existing bullet collision filter, because this filter is really supposed to just be about setting a bullet's own explosions and such. In this scenario, there isn't anything you can do if you want a bullet to carry its own explosion but also continue on without being destroyed/repooled.

The only other easy way to handle this is to have a separate collision filter just for what the bullet ends up "piercing" vs what causes it to destroy/repool.

For that reason I think it might end up confusing users and giving them too many options, and so as of now I'm thinking I'll leave this feature out. Curious what your solution looks like.

Code: Select all

    public class ShotBullet : ShotCollFlux
    {

        bool isPiercing = true;

        protected override void OnCollisionEnter2D(Collision2D collision)
        {               
            if (CollisionFilter.collisionAccepted(collision.gameObject.layer, CollisionList))
            {
                CollisionFilter.setExplosion(Explosion, ParentExplosion, collision.gameObject.transform, collision.contacts[0].point, AngleDirection, this);
                base.OnCollisionEnter2D(collision);
                return;
            }

            if (isPiercing)
                return;

            base.OnCollisionEnter2D(collision);
        }       
    }
Post Reply