This would only work for one enemy at a time with one material as is. Unfortunately there isn’t a simple way to fix everything with your current solution- this’ll be a bit of a read. Feel free to respond with any questions you have.
I assume you have a sphere collision for testing whether enemies are inside the range of the ability. If you haven’t, you should. Add one and change the sphere radius until it matches your effect.
Here’s how I’ve fixed it:
-
Make a new struct. Blueprints can’t handle maps to arrays, so we need to create a wrapper struct that acts as one. I’ll name it WrapperStruct_MaterialArray. Inside, we simply have one parameter- a material interface array
-
Back in the ability totem, we create a new variable. This variable will map each of your enemies to their original materials.
-
In the TotemFreezeFunction, get all the overlapping actors that are enemies- meaning put the class all your enemies inherit from in the ClassFilter parameter. After that, loop over them. We’ll need to cast to the enemy base class in order to actually do anything with them, so do that.
-
We then do your pause anim set and then call a function we’ll create that applies the materials. This simply has two parameters- an EnemyBase object and a boolean. After this you can do whatever other freeze stuff you have.
-
For the unfreeze, we simply flip the boolean values and use the keys of EnemyBaseMaterials rather than the sphere overlap. We don’t need to use a cast here since keys are already EnemyBase.
-
Inside the function, the first thing we do is check whether we’re freezing or not.
The unfreeze is extremely simple, so I’ll go over that last. -
The first thing we do in frozen is check whether the enemy is already frozen
-
We then loop over all the materials the enemy mesh has
-
Inside the loop, we add the material to the array of materials for this specific enemy. It’s a bit of a pain since map find doesn’t return by reference, but oh well. You’ll just need to create a local variable to hold it for a second.
-
Finally, we set the material in the enemy to be the freeze material. Make sure to connect ElementIndex to ArrayIndex- don’t just use 0.
With the freeze portion done, we can quickly do the unfreeze.
We simply iterate through the stored array, set the materials on the enemy to match, and mark the enemy as unfrozen by removing their entry.
Here's the blueprint for the nodes in the function. BlueprintUE wouldn't recognize my function as a function, so that's the best I could do. Keep in mind this won't work well pasted since it's using the parameters of the function, so just use it as a reference.