Download

Plasma/Energy Shield like in Star Wars

Hi,

I’m trying to create an “energy shield”-effect for my player pawn (like the big blue bubbles in Star Wars or the shield of the droideka) which should be attached to the player itself. The player should be able to activate the shield and walk around it whilst it is surrounding him.

1a278a82301eeef453f3cbfe200df2b6c0546a91.jpeg

Everything is working accordingly but one thing: I can’t get the shield to work when it’s attached to the player.

My plan was to have the player spawn a shieldactor and let it handle all the collision as long as it exists.
I started by creating a new class derived from AActor and called it PlasmaShield. I added a static mesh component for the visual representation of the shield and also for collision detection. When a new shield instance is created it performs some required steps:

It sets its rotation to absolute, adds it’s owner to the array of “IgnoreActorWhenMoving” so it wont cause any problems with the collision of the player (who is inside of the shield). Then I attach the collision component of the shield to the root component of the player.



void APlasmaShield::Activate(AActor* NewOwner)
{
	SetOwner(NewOwner);
	if (Owner)
	{
		ABrawlingPawn* MyPawn = Cast <ABrawlingPawn>(Owner);

		if (MyPawn)
		{
			MyPawn->SetHasShield(true);
		}

		//attach to owner's root component
		USceneComponent* Body = Owner->GetRootComponent();
		MeshComp->bAbsoluteRotation = true;
		MeshComp->AttachTo(Body, "");
		MeshComp->IgnoreActorWhenMoving(Owner, true);
		
		FTimerHandle TimerHandle;
		GetWorldTimerManager().SetTimer(TimerHandle, this, &APlasmaShield::Deactivate, LifeTime-0.5, false);

		PlaySound(openSound);
		TimeLine.ReverseFromEnd();
	}
}


And I guess the attaching is, what’s wrong. I’ve read that when I attach an actor to another actor only one collision component can be active at all times. So since the shield is attached to the player and not the other way around, the shield doesn’t register any collisions as it updates it position. Just the player’s collision component is registering those. As long as the shield is not attached it works great, but I want it to move with the player.

How would I go for it? I mean this must’ve been achieved before as it is a quite simple idea.

One approach could be to attach the player to the shield, but what would I do about the movement input which the player receives? I also could set the box extend of my player’s collision to a heigher value to simulate the shield but then the whole concept of having it as an extra class would be stupid imo.

Can someone provide me some insight here?

P.S:
After reading a little bit further I found this thread: https://answers.unrealengine.com/questions/238964/collision-when-using-attached-actors.html
This seems to be quite the same problem but doesn’t help much since I also want the collision to be correct (for example not fitting through a narrow space when the shield is activated).

~Theo

anyone having at least some thoughts on this?

You should be able to have multiple collision components on one actor. Just make sure when you get the event hit (I’m guessing this is what you’re using?) You check that the hit component isn’t the shield.

@mrooney

My problem is that when the shield is attached to the player it doesn’t register any collisions. Which means the shield doesn’t collide with anything, not even with world statics which are placed in the level. However if it is’nt attached it does have this collison which is missing now. I should not be able to receive the hit on the player when the shield is active since it should catch the projectile and the collision (projectile is destroyed on hit).

What’s the collision presets you have setup on it? My first reaction would be that the default collision set up on it is mucked up. I’ve had no issues having multiple collision components, so it makes me feel like the collision settings on the component were messed up. I’d consider testing in blueprint just by putting a sphere component on your character and seeing if it generates the hit events you expect and then try to replicate as many settings as you can to your C++ version.

This should still be possible the way I said. As long as you check that the hit component was the shield not your capsule you should be able to make yourself not take damage and destroy the projectile.

I’ll give it a try to reproduce it in blueprints; however it’s working and blocking bullets when it’s not attached. This means it has to be the attaching. Thanks for your reply, I’ll report back tomorrow (also with my settings) :slight_smile:

Edit: Maybe I was not clear enough. I do have collision (also on the shield) when I’m not moving. So if my player stands still and other bump into him, they bump into the shield instead. perfect. but when the player is moving the shield doesn’t have collision. Thats got something to do with the sweep collision check I mentioned in the link, I reckon.

That’s super funky.

What I’d try in blueprint is add a sphere component to your dude and just hook up the hit event to print a string with the name of the component/actor that hit it when you get a hit event. That’s the easiest base case I can think of.

Is it possible that you’re turning off the collision on your actor at some point somewhere else in your gameplay?

Added static mesh to the player via blueprint and as expected: can’t have a second collision component. It’s just still the collision box blocking and not the shield.

b313480a33.jpg

e5f29fbce6e1dd97d920453dd80164823f8564e0.png

Just some quick thought:

1 - how are you adding the static in BP? Is it a component that you add in the Pawn Actor?
2 - Have you tried to make your Shield a standalone actor that you Spawn & Attached to your Pawn? So the colision actors will be different so your collision will work for your shield (if setup properly).
3 - Have you tried to activate: Show Collision in your editor command so you can see the the collision of the different actor in the world? Are they exactly where you think they should be?

Thanks for the ideas,

in the bp-test i just posted above it is exactly that (just a component). But in the original problem I’m spawning another actor and not adding it as a component. It does both not work as I want it to.

yes I do have as mentioned in the first post. It does work without any problems as long as it is not attached. It does exactly what it should do. The problem just occures when being attached.

One approach might be to attach multiple collision components to the actor, but only enable one at any given time…

e.g. Capsule collision disabled when shield enabled.

I created vehicle shields for my Hovertank game a couple of months ago, and being unsatisfied with the approaches I’ve seen so far I took my own, which works pretty well and doesn’t require layers of scene components etc. It can support up to four impact effects at once at the moment, but you can have as many as you want providing you don’t mind the extra instruction cost in the shield Shader. Four for me was a nice balance between the effect and the overhead (which is minute if anything, but I want lots of these to be use-able at the same time, since this is an FPS / RTS mix with lots of units on the field).

https://youtube.com/watch?v=CQmLuip_dNE

A brief overview of how it works:

  • The Shield ‘Inventory’ object (which is actually a weapon, but I digress) creates a single static mesh component on the owning actor, scales it to the bounding sphere size of the actor and applies a dynamic material instance to it.

  • Whenever the owning actor takes damage, it tells the shield object to display an effect. The actor modifies the amount of damage it takes based on the shield it currently has equipped. This does mean of course, that the projectiles still actually hit the object, which I want in my case (you may not, but there are workarounds for that). In order to work out the location of the effect, it just uses the direction that the damage came from. The intensity is worked out from the damage given.

  • The shield material has four sphere masks driven by parameters. Each one essentially masks in the shield material. Each sphere mask needs a location (which is adjusted in the material to be relative to the mesh orientation and radius in world-space), and an intensity. You can in theory have as many of these as you like, but I chose four because it worked well enough for me.

  • I then use my (existing) “Material FX Manager” class, which essentially exists so I can easily animate the parameters of Dynamic Material Instances based on a curve. When the shield receives an impact, it sets a location in world-space for the sphere mask (which the material adjusts to be relative), and using the oldest index - adds a new entry to the material manager, to animate the ‘intensity’ property over time. Essentially the shield adds an entry to the manager, and the manager ‘ticks’ the intensity of the mask based on a curve. When the curve expires, the entry is removed.

  • To eliminate jarring the appearance, if the shield takes more hits than it can display, it just reuses the oldest mask. The material manager works in such a way that if a new entry is given for the same material and parameter names, it removes the existing entry and starts again. See UT source code for a good example of this.


Effectively using this method I have no overdraw, no duplicate / extra meshes and therefore as few draw calls as possible. It’s also entirely self-contained and the material can still be pretty flexible. If I wanted to, I could modify it so that projectiles explode early if an object has a shield, and move the impact effect to the bounding sphere radius, but I didn’t want that in my case.

That looks awesome Jamsh!

Thanks, I hope it gives some insight / different approaches for going about it. Every one I’ve seen so far involves doing something expensive like duplicate components or something, which I wanted to avoid.