2
\$\begingroup\$

I want to implement a "shield" that reacts to projectile hits. Currently, my colliders are mapped to the animated sprite's outline on all frames.

I'm looking for something like the image below. For example, what shader could I use?

shield being hit by a lazer

\$\endgroup\$
  • \$\begingroup\$ possible duplicate of XNA shield effect with a Primative sphere problem \$\endgroup\$ – Seth Battin Nov 19 '14 at 15:05
  • \$\begingroup\$ I just noticed you're asking about sprites; my answer was based on doing this with 3D objects so it may or may not be applicable. Can you share an example of the animated sprites you're using so we can get a better idea of the situation? \$\endgroup\$ – DMGregory Nov 22 '14 at 19:05
1
\$\begingroup\$

Here's how I've approached this situation in Unity in the past:

I create a custom shield shader that accepts some number of vector parameters (typically 3 or 4), each representing a recent hit. The xyz components are the position of the hit in local coordinates, and the w component is the intensity.

Within the fragment shader, I compute the object-space distance of the pixel being shaded from each recent hit's xyz position, and apply a falloff curve to get a brightness value. The falloff range or the max brightness can be linked to the intensity parameter w. After summing the brightness from all hits, I use that as a blend weight for my "shield active" output value (usually a texture or refraction effect).

I then have a script on the shield GameObject that logs recent hits, keeping a buffer of Vector4s the same size as the shader accepts. Each frame in Update(), it decays the w parameter on each (so hits fade over time) and passes the vectors to the shield Renderer's material with SetVector() for rendering. This script needs some logic for how to allocate the limited hit slots when a new hit comes in - for instance overwriting old/weak hits first, or combining two nearby hits into a single more intense one.

(Ordinary cautions about creating and caching a unique material instance and manually Destroy()ing it when done apply, so that you don't leak materials)

If you need a lot of simultaneous hits sometimes, and can afford the extra draw calls, you can also render the mesh repeatedly for each (batch of) hit(s) using DrawMeshNow().

If you want to do this without custom shaders, and are okay with the shield effect sitting right on the object's skin (instead of a distance away), you could try using Projectors with the default "Projector/Light" material to effectively "stamp" a shield glow onto the geometry. Note that this re-renders every object in the projector's volume, for each projector placed, so your draw calls go up. I'm not sure if projectors work with sprites, so you might need to create a mesh the shape of your sprite for the projector to shine onto.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

If you could generate a texture which is about the normal on the surface of the object you want to show the shield. There is no need for shaders.

  • First, you need to prepare a cellular texture like the reaction in the picture, which should be transparent. Then, about the reaction when hit by the beam.
  • Then, you need to prepare a(maybe several) dome for your shield and apply the material which contains the texture in the first step.
  • After that, when hit by a beam, just put the dome at the hit point, and change its rotation to face the contradict direction of the normal.

So, the only important thing is to find out the normal of your sprite.

About shader solution, I'm not sure if this method could work. This is just an idea:

  1. You need to pass the hit point's world coordinate(for example, pos) into your shader.
  2. Use newpos = mul(UNITY_MATRIX_MVP, pos) to get a position. and newpos.uv to get the UV.
  3. Draw the texture in the area around the newpos.uv within a radius in the fragment shader. However, this method could not generate the correct perspective effect.

Hope this can be a bit helpful to you.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for the response, could you elaborate on "preparing a dome" a bit? I'm not quite sure what you mean by that! \$\endgroup\$ – Aequitas Nov 19 '14 at 14:05
  • \$\begingroup\$ I mean that if your shield has a dome shape in 3D, you can simply prepare a 3D mesh that has a dome shape. And put the texture on it. Then put your shield in the correct position and direction. \$\endgroup\$ – Dev7x Nov 19 '14 at 17:49
  • \$\begingroup\$ I was thinking of mapping the shield to the collider area, not really have a circular dome, but if the original route is improbable it definitely is a good suggestion! \$\endgroup\$ – Aequitas Nov 20 '14 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.