##はじめに
3D系のRPGゲームなどでよくみる、キャラクタの足元にある円形のマーカーをUnityのシェーダで書いてみます。
##床用のシェーダー
まずはRadiusShaderという名前で新しくシェーダーを作ります。
Shader "Custom/RadiusShader" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Center("Center", Vector) = (0,0,0,0)
_Radius("Radius",Float) = 0.5
_RadiusColor("Radius Color",Color) = (1,0,0,1)
_RadiusWidth("Radius Width",Float) = 2
_RadiusPower("RadiusPower",Range(0,10)) = 2
_RadiusSpeed("RadiusSpeed",Range(0,100)) = 50
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
float3 _Center;
float _Radius;
fixed4 _RadiusColor;
float _RadiusWidth;
float _RadiusPower;
float _RadiusSpeed;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
float d = distance(_Center, IN.worldPos);
float tempRadiusWidth = _RadiusWidth * abs(sin(_Time * _RadiusSpeed));
if(d > _Radius && d < _Radius + tempRadiusWidth)
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb + _RadiusColor * pow(d/(_Radius+tempRadiusWidth),_RadiusPower);
else
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
FallBack "Diffuse"
}
Properties{}では以下のようなパラメータを設定しています。
- _MainTex : ベーステクスチャ
- _Center : マーカー中心位置
- _Radius : マーカーの半径
- _RadiusColor : マーカーの色
- _RadiusWidth : マーカーの太さ
- _RadiusPower : マーカーのグラデーションの強さ
- _RadiusSpeed : マーカーの拡大縮小アニメーションのスピード
基本的にはサーフェースシェーダーとして作っています。
このシェーダーを使ったMaterialを作成し、床面となるPlaneやTerrainなどに設定します。
##キャラクタ用のC#スクリプト
次にキャラクター(ここではSphere)に以下のスクリプトをはりつけます。床用のMaterialのパラメータをランタイムで変更するために必要です。
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class RadiusCenter : MonoBehaviour {
public Material radiusMaterial;
public Color color = Color.white;
public float radius = 10f;
public float radiusWidth = 2f;
public float power = 5f;
public float speed = 60f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
radiusMaterial.SetVector ("_Center", transform.position);
radiusMaterial.SetColor ("_RadiusColor", color);
radiusMaterial.SetFloat ("_Radius", radius);
radiusMaterial.SetFloat ("_RadiusWidth", radiusWidth);
radiusMaterial.SetFloat ("_RadiusPower", power);
radiusMaterial.SetFloat ("_RadiusSpeed", speed);
}
}
主に、キャラクタに円形のマーカーがついてくるために、Update()の中でマテリアルのパラメータを操作しています。