unity官网:www.unity.cn
1,只狼弹反特效
fixed4 frag (v2f i) : SV_Target
{
//这里是为了让扩散为圆形而不是屏幕的比例,_Aspect是屏幕的宽高比
float2 p=i.uv*float2(_Aspect,1);
float2 dir =normalize(p-_BlurCenter);
dir*=_MainTex_TexelSize.xy;
//对方向上的点采样取平均
fixed4 col =tex2D(_MainTex,i.uv-dir*1) ;
col +=tex2D(_MainTex,i.uv-dir*2) ;
col +=tex2D(_MainTex,i.uv-dir*3) ;
col +=tex2D(_MainTex,i.uv-dir*5) ;
col +=tex2D(_MainTex,i.uv-dir*8) ;
col +=tex2D(_MainTex,i.uv+dir*1) ;
col +=tex2D(_MainTex,i.uv+dir*2) ;
col +=tex2D(_MainTex,i.uv+dir*3) ;
col +=tex2D(_MainTex,i.uv+dir*5) ;
col +=tex2D(_MainTex,i.uv+dir*8) ;
col *=0.1;
return col;
}
2,场景特效
Shader "Hidden/RainRippleFX"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Rain("Rain", 2D) = "black" {}
_Ripple("Ripple", 2D) = "black" {}
_NoiseTex("Noise Tex", 2D) = "black"{}
_RainForce("RainForce",Range(0,0.5)) = 0
}
SubShader
{
Cull Off ZWrite Off ZTest Always
Fog { Mode Off } Blend Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 frustumDir : TEXCOORD0;
float2 uv : TEXCOORD1;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex, _NoiseTex;
sampler2D _CameraDepthTexture, _Rain, _Ripple;
float4x4 _FrustumDir;
float3 _CameraForward;
fixed _RainForce;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
float2 uv = v.uv;
int ix = (int)uv.x;
int iy = (int)uv.y;
o.frustumDir = _FrustumDir[ix + 2 * iy];
o.uv = uv;
return o;
}
fixed lum(fixed3 c)
{
return c.r * 0.2 + c.g * 0.7 + c.b * 0.1;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv));
float linear01Depth = Linear01Depth(depth);
float linearEyeDepth = LinearEyeDepth(depth);
float3 worldPos = _WorldSpaceCameraPos + linearEyeDepth * i.frustumDir.xyz;
float2 fogUV = (worldPos.xz + worldPos.y * 0.5) * 0.0025;
fixed fogNoiseR = tex2D(_NoiseTex, float2(fogUV.x + _Time.x * 0.15, fogUV.y)).r;
fixed fogNoiseG = tex2D(_NoiseTex, float2(fogUV.x , fogUV.y + _Time.x * 0.1)).g;
fixed fogNoiseB = tex2D(_NoiseTex, float2(fogUV.x - _Time.x * 0.05, fogUV.y - _Time.x * 0.3)).b;
fixed3 rippleNoise = tex2D(_Rain, worldPos.xz * 0.005 - _Time.y);
fixed3 ripple = (1-tex2D(_Ripple, worldPos.xz * ((fogNoiseR + fogNoiseG + fogNoiseB + rippleNoise * 0.3) * 0.1 + 0.7))) * step(linear01Depth, 0.99);
ripple *= step(ripple.r, col.r * 0.6 + 0.5);
ripple *= step(col.r * 0.6 + 0.3, ripple.r);
ripple *= (rippleNoise.r * rippleNoise.g * rippleNoise.b);
ripple *= (fogNoiseR + fogNoiseG) * fogNoiseB + 0.5;
fixed2 rainUV = fixed2(i.uv.x , i.uv.y * 0.01 + _Time.x * 1.1);
rainUV.y += i.uv.y * 0.001;
rainUV.x += pow(i.uv.y + (_CameraForward.y + 0.5), _CameraForward.y + 1.15) * (rainUV.x - 0.5) * _CameraForward.y;
fixed3 rain = tex2D(_Rain, rainUV);
col.rgb += ripple * (1 - i.uv.y) * 0.8 * _RainForce * 2;
col.rgb += saturate(rain.r - rain.g * (1 - _RainForce * 0.5) - rain.b * (1 - _RainForce * 0.5)) * 0.15 * (i.uv.y) * _RainForce * 2;
return col;
}
ENDCG
}
}
}
3,部分插件代码
timeInt = time / (2.0 * interval)
float2 fTime = frac(float2(timeInt, timeInt * .5)
posA = pos.xz - (flowDir/2) * fTime.x * flowDir
posB = pos.xz - (flowDir/2) * fTime.y * flowDir
gridA0 = waveParticles(posA.xz, freq0,scale0)
gridA1 = waveParticles(posA.xz, freq1,scale1)
…
gridB0 = waveParticles(posB.xz, freq2,scale0)
gridB1 = waveParticles(posB.xz, freq3,scale1)
…
float3 pos0 = gridA0 + gridA1 + gridA2 + gridA3
float3 pos1 = gridB0 + gridB1 + gridB2 + gridB3
pos = blend(pos0, pos1, abs((2*frac(timeInt)-1)))
pos.y += heightMap.eval(uv)
float v = abs(i_view.y);
half towardsSun = pow(max(0., dot(i_lightDir, -i_view)),_SubSurfaceSunFallOff);
half3 subsurface = (_SubSurfaceBase + _SubSurfaceSun * towardsSun) *_SubSurfaceColour.rgb * _LightColor0 * shadow;
subsurface *= (1.0 - v * v) * sssIndensity;
col += subsurface;
4,源码传送门
https://github.com/CRYTEK/CRYENGINE/CryFX/Water.cfx
https:// github.com/crest-ocean/ crest
https:// github.com/Verasl/BoatA ttack
5,《阴阳师》的召唤画符表现
Graphics.SetRenderTarget(destTexture);
GL.PushMatrix();
GL.Clear(true, true, new Color(0,0,0,0f));
GL.PopMatrix();
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
float4 col = tex2D(_MainTex, IN.texcoord);
col.rgb *= col.a;
return col;
}
using UnityEngine;
using System.Collections;
using DG.Tweening;
using UnityStandardAssets.ImageEffects;
public class Summon : MonoBehaviour
{
private readonly int TEX_SIZE = 512;
private RenderTexture texRender;
public Material _BrushMaterial;
public Material _DrawMaterial;
private Texture brushTypeTexture;
private GameObject _SummonObj = null;
private enum BrushColor
{
red,
green,
blue,
pink,
yellow,
gray,
black,
white,
count,
}
private float brushScale = 0.2f;
private bool m_bShow = true;
private bool m_bMouseDown = false;
private BrushColor brushColorType = BrushColor.black;
private Color[] brushColor = new Color[(int)BrushColor.count] { Color.red, Color.green, Color.blue, new Color(255, 0, 255), Color.yellow, Color.gray, Color.black, Color.white };
private Vector3 startPosition = Vector3.zero;
private Vector3 endPosition = Vector3.zero;
private Rect rcDraw;
void Start()
{
_SummonObj = Instantiate(Resources.Load("Models/summon")) as GameObject;
_SummonObj.transform.position = new Vector3(0, 8f, 15f);
texRender = new RenderTexture(TEX_SIZE, TEX_SIZE, 24, RenderTextureFormat.ARGB32);
brushTypeTexture = _BrushMaterial.mainTexture;
rcDraw = new Rect((Screen.width - TEX_SIZE) * 0.5f, (Screen.height - TEX_SIZE) * 0.5f, TEX_SIZE, TEX_SIZE);
Clear(texRender);
// 预加载资源避免召唤时候卡
UnityEngine.Object bossPrefab = Un2.AssetLoader.LoadPrefab(string.Format("Normal/{0}.prefab", "m_01_boss1"));
float timeAfterLoad = Time.realtimeSinceStartup;
if (bossPrefab != null)
{
GameObject bossModel = Instantiate(bossPrefab) as GameObject;
GameObject.DestroyImmediate(bossModel);
}
}
void Update()
{
if (Input.GetMouseButton(0))
{
OnMouseMove(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0));
}
if (Input.GetMouseButtonUp(0))
{
OnMouseUp();
}
}
void OnMouseUp()
{
startPosition = Vector3.zero;
m_bMouseDown = false;
}
void OnMouseMove(Vector3 pos)
{
if (pos.x < rcDraw.xMin || pos.x > rcDraw.xMax || pos.y < rcDraw.yMin || pos.y > rcDraw.yMax)
{
return;
}
endPosition = pos;
if (!m_bMouseDown)
{
DrawBrush(texRender, (int)endPosition.x, (int)endPosition.y, brushTypeTexture, brushColor[(int)brushColorType], brushScale);
m_bMouseDown = true;
}
if (startPosition.Equals(Vector3.zero))
{
startPosition = endPosition;
return;
}
float distance = Vector3.Distance(startPosition, endPosition);
if (distance > 1)
{
int d = (int)distance;
for (int i = 0; i < d; i++)
{
float difx = endPosition.x - startPosition.x;
float dify = endPosition.y - startPosition.y;
float delta = (float)i / distance;
DrawBrush(texRender, new Vector2(startPosition.x + (difx * delta), startPosition.y + (dify * delta)), brushTypeTexture, brushColor[(int)brushColorType], brushScale);
}
}
startPosition = endPosition;
}
void Clear(RenderTexture destTexture)
{
Graphics.SetRenderTarget(destTexture);
GL.PushMatrix();
GL.Clear(true, true, new Color(0,0,0,0f));
GL.PopMatrix();
Renderer render = _SummonObj.GetComponentInChildren();
render.material.SetTexture("_DecalTex", null);
}
void DrawBrush(RenderTexture destTexture, Vector2 pos, Texture sourceTexture, Color color, float scale)
{
DrawBrush(destTexture, (int)pos.x, (int)pos.y, sourceTexture, color, scale);
}
void DrawBrush(RenderTexture destTexture, int x, int y, Texture sourceTexture, Color color, float scale)
{
DrawBrush(destTexture, new Rect(x, y, sourceTexture.width, sourceTexture.height), sourceTexture, color, scale);
}
void DrawBrush(RenderTexture destTexture, Rect destRect, Texture sourceTexture, Color color, float scale)
{
float left = destRect.left - destRect.width * scale / 2.0f - rcDraw.left;
float right = destRect.left + destRect.width * scale / 2.0f - rcDraw.left;
float top = destRect.top - destRect.height * scale / 2.0f - rcDraw.top;
float bottom = destRect.top + destRect.height * scale / 2.0f - rcDraw.top;
Graphics.SetRenderTarget(destTexture);
GL.PushMatrix();
GL.LoadOrtho();
// mat.SetTexture("_MainTex", sourceTexture); // 在材质里面就已经设置好贴图了
// mat.SetColor("_Color", color); // 取消颜色设置渲染,只用贴图颜色 [2017/5/8 09:05:53 --By aq_1000]
_BrushMaterial.SetPass(0);
GL.Begin(GL.QUADS);
GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(left / TEX_SIZE, top / TEX_SIZE, 0);
GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(right / TEX_SIZE, top / TEX_SIZE, 0);
GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(right / TEX_SIZE, bottom / TEX_SIZE, 0);
GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(left / TEX_SIZE, bottom / TEX_SIZE, 0);
GL.End();
GL.PopMatrix();
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
fixed4 decal = 0.0f;
if (i.texcoord.y >= 0.25f && i.texcoord.y <= 0.75f)
{
decal = tex2D(_DecalTex, half2(i.texcoord.x, (i.texcoord.y - 0.25f) * 2.0f));
}
return lerp(col, decal, decal.a);
}
private void _Summon()
{
m_bShow = false;
_SummonObj.GetComponent().Play("Summon", 0);
Renderer render = _SummonObj.GetComponentInChildren();
render.material.SetTexture("_DecalTex", texRender);
StartCoroutine(WaitForSummon());
GameObject effect = GameObject.FindGameObjectWithTag("SummonEffect");
effect.GetComponent().enabled = true;
}
private IEnumerator WaitForSummon()
{
// suspend execution for 5 seconds
yield return new WaitForSeconds(1.5f);
Tweener tweener = _SummonObj.transform.DOScale(new Vector3(0.001f, 0.001f, 0.001f), 1f);
tweener.SetEase(Ease.Linear);
tweener.OnComplete(() =>
{
_ScaleEnd();
});
}
private void _ScaleEnd()
{
Camera.main.gameObject.GetComponent().enabled = true;
Tweener tweener = Camera.main.transform.DOMove(new Vector3(0f, 8f, 14f), 0.75f);
tweener.SetEase(Ease.Linear);
tweener.OnComplete(() =>
{
_CameraMoveEnd();
});
}
private void _CameraMoveEnd()
{
Camera.main.gameObject.GetComponent().enabled = false;
// 召唤怪物
Singleton.Instance.CreateBoss("m_01_boss1", new Vector2(0, 0), null);
}
编写人物移动代码
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Animator))]
public class RunnerController : MonoBehaviour
{
//public Variable
public enum Direction
{
Forward = 90,
Backward = 270,
}
public float maxSpeed;
public float MoveSpeed = 0;
public float Z;
public float JumpForce;
public float Gravity;
public bool PlayerDead;
//private variable
private CharacterController Controller;
private Animator animator;
private Direction direction = Direction.Forward;
private float H;
private float V;
private bool OnGround = true;
private bool Jump;
private float JSpeed;
void Awake()
{
//rigidbody = this.GetComponent();
Controller = this.GetComponent();
animator = this.GetComponent();
}
void Update ()
{
if(!PlayerDead)
{
if(this.transform.position.z != Z)
{
Vector3 Position = this.transform.position;
Position.z = Z;
this.transform.position = Position;
}
H = Input.GetAxis("Horizontal");
V = Input.GetAxis("Vertical");
//AniamtorState();
if(Controller.isGrounded)
{
OnGround = true;
Jump = false;
animator.SetBool("Jump",false);
if(Input.GetKeyDown(KeyCode.J))
{
if(V > 0.3)
{
JSpeed = 1.3f * JumpForce;
}
else
{
JSpeed = JumpForce;
}
Jump = true;
animator.SetBool("Jump", true);
}
}
else
{
OnGround = false;
if(!OnGround)
{
Controller.Move(-Vector3.up * Gravity * Time.deltaTime);
}
}
}
else
{
animator.SetBool("Dead",true);
animator.SetFloat("speed", 0);
animator.SetFloat("Slider", 0);
animator.SetBool("Jump", false);
}
}
void FixedUpdate()
{
JumpUp();
Move();
}
void Move()
{
//先计算朝向
if(H >= 0.3)
{
if(MoveSpeed == 0)
{
SetFacingDirection(Direction.Forward);
}
if(direction == Direction.Forward)
{
if(MoveSpeed < maxSpeed)
{
MoveSpeed += 1.0f;
//state = State.Walk;
}
else
{
MoveSpeed = maxSpeed;
//state = State.Run;
}
}
}
else if(H <= -0.3)
{
if(MoveSpeed == 0)
{
SetFacingDirection(Direction.Backward);
}
if(direction == Direction.Backward)
{
if(MoveSpeed < maxSpeed)
{
MoveSpeed += 1.0f;
//state = State.Walk;
}
else
{
MoveSpeed = maxSpeed;
//state = State.Run;
}
}
}
if((direction == Direction.Forward && H < -0.3 && MoveSpeed != 0)
|| (direction == Direction.Backward && H > 0.3 && MoveSpeed != 0))
{
MoveSpeed -= 1.0f;
if(MoveSpeed <= 0)
{
MoveSpeed = 0;
//state = State.Idle;
}
}
if(Mathf.Abs(H) < 0.3 && MoveSpeed != 0)
{
MoveSpeed -= 0.5f;
if(MoveSpeed <= 0)
{
MoveSpeed = 0;
//state = State.Run;
}
}
transform.Translate(Vector3.forward * MoveSpeed * Time.deltaTime);
animator.SetFloat("Speed", MoveSpeed);
animator.SetFloat("Slider", V);
}
void JumpUp()
{
if(Jump)
{
JSpeed -= 2 * Gravity * Time.deltaTime;
Controller.Move(Vector3.up * Time.deltaTime * JSpeed);
}
}
void SetFacingDirection(Direction dir)
{
if(direction != dir)
{
transform.Rotate(Vector3.up * (direction - dir));
direction = dir;
}
}
void OnTriggerEnter(Collider _collider)
{
if(_collider.gameObject.tag == "Enemy")
{
PlayerDead = true;
}
}
}
后面的下个文章在再写