[Unity 5] シェーダーをつかってキャラクタの位置のマーカー表示

はじめに

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()の中でマテリアルのパラメータを操作しています。

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.