Home>

In the game, it is often necessary to create a light effect on the edge of the body where the character is hit,The method used in this article is,Overlay a renderer with a made edge light shader,And dynamically control the gradient effect of the edge light through the script,Shows the edge light effect after being hit

The engineering structure is as follows

1 Create a material ball hittedmateffect.mat in the assets/resources/material directory, use transparentrim.shader

Note that resources.load is used in the code, so it must be placed in this directory,You can change it to another way

2 Create a sphere in the scene, hang the runner script, run it, click anywhere on the screen,The sphere will show the edge light effect

running result

Code

transparentrim.shader

shader "effect/transparentrim" {
 properties {
 _rimcolor ("rim color", color)=(0.5,0.5,0.5,0.5)
 _innercolor ("inner color", color)=(0.5,0.5,0.5,0.5)
 _innercolorpower ("inner color power", range (0.0,1.0))=0.5
 _rimpower ("rim power", range (0.0,5.0))=2.5
 _alphapower ("alpha rim power", range (0.0,8.0))=4.0
 _allpower ("all power", range (0.0, 10.0))=1.0
 }
 subshader {
 tags {"queue"="transparent"}
 cgprogram
 #pragma surface surf lambert alpha
 struct input {
 float3 viewdir;
 internal_data
 };
 float4 _rimcolor;
 float _rimpower;
 float _alphapower;
 float _alphamin;
 float _innercolorpower;
 float _allpower;
 float4 _innercolor;
 void surf (input in, inout surfaceoutput o) {
  half rim=1.0-saturate (dot (normalize (in.viewdir), o.normal));
  o.emission=_rimcolor.rgb * pow (rim, _rimpower) * _ allpower + (_innercolor.rgb * 2 * _innercolorpower);
  o.alpha=(pow (rim, _alphapower)) * _ allpower;
 }
 endcg
 }
 fallback "vertexlit"
}

hittedmateffect.cs

//hittedmateffect.cs
using unityengine;
using system.collections;
public class hittedmateffect:monobehaviour
{
  bool mbactive=false;
  bool mbinit=false;
  material mmat=null;
  public float mlife;
  private static int s_innercolor=-1;
  private static int s_allpower=-1;
  private static int s_alphapower=-1;
  void awake ()
  {
    s_innercolor=shader.propertytoid ("_ innercolor");
    s_allpower=shader.propertytoid ("_ allpower");
    s_alphapower=shader.propertytoid ("_ alphapower");
  }
  //use this for initialization
  ///<summary>
  ///Set the material color
  ///</summary>
  ///<param name="color"></param>
  public void setcolor (color color)
  {
    mmat.setcolor (s_innercolor, color);
  }
  public void setlifetime (float time)
  {
    mlife=time;
  }
  public void active ()
  {
    if (! mbinit)
      addeffect ();
    mmat.setfloat (s_allpower, 0.9f);
    mbactive=true;
    mlife=0.2f;
  }
  void update ()
  {
    if (! mbactive)
      return;
    mlife-= time.deltatime;
    if (mlife<0)
    {
      mbactive=false;
      mmat.setfloat (s_allpower, 0);
    }
    float v=mathf.sin ((1-mlife) * 8 * mathf.pi) + 2;
    mmat.setfloat (s_alphapower, v);
  }
  void addeffect ()
  {
    object mat=resources.load ("material/hittedmateffect");
    mmat=gameobject.instantiate (mat) as material;
    foreach (var curmeshrender in transform.getcomponentsinchildren<renderer>())
    {
      material [] newmaterialarray=new material [curmeshrender.materials.length + 1];
      for (int i=0;i<curmeshrender.materials.length;i ++)
      {
        if (curmeshrender.materials [i] .name.contains ("hittedmateffect"))
        {
          return;
        }
        else
        {
          newmaterialarray [i]=curmeshrender.materials [i];
        }
      }
      if (null!=mmat)
        newmaterialarray [curmeshrender.materials.length]=mmat;
      curmeshrender.materials=newmaterialarray;
    }
    mbinit=true;
  }
  void removeeffect ()
  {
    foreach (var curmeshrender in transform.getcomponentsinchildren<renderer>())
    {
      int newmaterialarraycount=0;
      for (int i=0;i<curmeshrender.materials.length;i ++)
      {
        if (curmeshrender.materials [i] .name.contains ("hittedmateffect"))
        {
          newmaterialarraycount ++;
        }
      }
      if (newmaterialarraycount>0)
      {
        material [] newmaterialarray=new material [newmaterialarraycount];
        int curmaterialindex=0;
        for (int i=0;i<curmeshrender.materials.length;i ++)
        {
          if (curmaterialindex>= newmaterialarraycount)
          {
            break;
          }
          if (! curmeshrender.materials [i] .name.contains ("hittedmateffect"))
          {
            newmaterialarray [curmaterialindex]=curmeshrender.materials [i];
            curmaterialindex ++;
          }
        }
        curmeshrender.materials=newmaterialarray;
      }
    }
  }
}

runner.cs

using system.collections;
using system.collections.generic;
using unityengine;
public class runner:monobehaviour
{
  //use this for initialization
  void start ()
  {
  }
  //update is called once per frame
  void update ()
  {
    if (input.getmousebuttondown (0))
    {
      hittedmateffect sc=gameobject.getcomponent<hittedmateffect>();
      if (null == sc)
        sc=gameobject.addcomponent<hittedmateffect>();
      sc.active ();
      sc.setcolor (color.red);
    }
  }
}
  • Previous Unity uses ScrollRect to make joystick
  • Next Python unittest unit test framework and assert method