Region Sampling is unfortunately currently broken in Niagara. This would easily allow the nanobots to for example only spawn from the hands in this scenario, by setting up material sections in the SK and then turning these into sampling regions. I attached the Niagara System containing the nanobots to the root component of the Animation Blueprint by blueprint, to allow the nanobots to also follow and stick to the arms even during their animation. The GPU sprites can be alligned with the mesh by setting their SpriteFacing to the normals of the Skeletal Mesh. Make sure this is done in the Niagara update stack so the nanobots follow the arms even during animation. The color of the nanobots can be matched with the correct color of their spawn/attachment point on the mesh, by baking the albedo texture into the mesh as vertex color. Do keep in mind some saturation is lost, but this can be accounted for in the shader. I made sure any randomness is set deterministically on spawn, to then use these values during update, to avoid the randomn values being recalculated per frame. The pivot of the point of impact of the damage is set dynamically by taking the input coordinates when the laser hits the forcefield by blueprint, after which the distance of this point to absolute world position is taken in the shader of the forcefield to mask the transition. To be able to have the hexagons support different margin sizes dynamically, the hexagons are build using math instead of using a texture. As a basis for this pattern I have used this script from pedrolb on Shadertoy: https://www.shadertoy.com/view/XlKczR I recreated this in the material editor of UE4 using the default nodes plus an extra custom node I made with HLSL to allow for a proper stepping function, and then further optimised this setup. The hexagons were initially setup using this script below: float uvTile = 10.0; float hexagonSeparation = 0.05; //[0.0, 1.0] float hexagonAspect = sqrt(3.0); void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord/iResolution.x; uv.y *= hexagonAspect; vec2 uvTiled = uv * uvTile + iTime; vec2 uvOffset = uvTiled + floor((uvTiled.y) / 1.5) * 0.5; vec2 uvChanged = abs(fract(uvOffset) - 0.5) * 2.0; float hexagonMask = 0.0; if(mod(uvTiled.y, 1.5) < 1.0) { hexagonMask=step(uvChanged.x, 1.0 - hexagonSeparation); } else { hexagonMask=step(uvChanged.x + hexagonSeparation * hexagonAspect, uvChanged.y) + step(uvChanged.y + hexagonSeparation * hexagonAspect, uvChanged.x); } // Output to screen //fragColor=vec4(uvChanged, 0.0, 1.0); fragColor=vec4(hexagonMask); }
Stuff:
Older videos showcasing different parameters can be found here: