유니티 부트켐프 2012 에서 발표 한 쉐이더 중.

유니티 부트켐프 2012 에서 발표 한 쉐이더 중.
쿨타임 쉐이더. 입니다.

모듈 베이스로 되어 있지 않아 일단 관련 된 파일만 따로 올립니다.
참고정도 하시면 될 듯 합니다.

GUIClock.Shader


Shader "_Game/GUIClock"
{
Properties
{
_MainTex("Base (RGB) Trans (A)", 2D) = "white" {}
_DummyTex("Null Texture", 2D) = "white" {}

}
SubShader
{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "LightMode" = "Always" }
Lighting Off
//BindChannels {
// Bind "Vertex", vertex
// Bind "texcoord", texcoord0
// Bind "Color", color
// Bind "normal", normal
//}

Blend SrcAlpha OneMinusSrcAlpha
Pass
{

CGPROGRAM
#pragma vertex Vert
#pragma fragment Frag
#pragma fragmentoption ARB_precision_hint_fastest

sampler2D _MainTex;
sampler2D _DummyTex;
const fixed4 _Colorlessness = fixed4(0,0,0,0);

struct VSIn
{
    float4 vertex : POSITION;
    fixed2 texcoord : TEXCOORD0;
    fixed4 color : COLOR;
};

struct FSIn
{
    float4  pos : SV_POSITION;
    fixed2  uv : TEXCOORD0;
float2 pixel : TEXCOORD1;
fixed4 clock : COLOR0;
};

FSIn Vert( VSIn vIn )
{
    FSIn vOut;
vOut.pixel = vIn.vertex.xy;
    vOut.pos = mul( UNITY_MATRIX_MVP, vIn.vertex );
    vOut.uv = vIn.texcoord;
vOut.clock = vIn.color;
    return vOut;
}

half4 Frag( FSIn fIn ) : COLOR
{
int isVisible = 0;
float  radius = atan2( fIn.pixel.x, fIn.pixel.y );
//float radius = acos( dot( float2( 0, 1 ), fIn.pixel ) );
if( radius < 0 )
radius += 6.2832f;

// ClockType{ VISIBIE_CW, VISIBLE_CCW, INVISIBLE_CW, INVISIBLE_CCW }
//isVisible = fIn.clock.x < fIn.clock.y ?
//!( radius < fIn.clock.x || fIn.clock.y < radius ) : !( fIn.clock.y < radius && radius < fIn.clock.x );
half startTick = fIn.clock.x * 10f;
half endTick = fIn.clock.y * 10f;

//if( startTick <= lastTick )
// isVisible = !( radius <= fIn.clock.x || fIn.clock.y <= radius );
//else
// isVisible = !( fIn.clock.y < radius && radius < fIn.clock.x );

fixed4 color = fixed4(0,0,0,0);
//if( !( radius <= fIn.clock.x || fIn.clock.y <= radius ) )
// color =  tex2D( _MainTex, fIn.uv ) * fIn.color;
if( startTick <= endTick )
isVisible = ( startTick < radius && radius < endTick );
else
isVisible = !( endTick <= radius && radius <= startTick );

if( isVisible )
color =  tex2D( _MainTex, fIn.uv ) * fIn.clock.a;

return color;
}

ENDCG

}

}
Fallback off
}


---------------------------------------------------------------------------------

UIClock Editor.cs


using UnityEngine;
using System.Collections;

public class UIClock : UITexture, IPercentable
{
public enum ClockType{ VISIBIE_CW, VISIBLE_CCW, INVISIBLE_CW, INVISIBLE_CCW }
private float _deltaTime = 0;

protected override string ShaderName{ get{ return "GUIClock"; } }

private bool _isPlaying = false;
public  bool  IsPlaying{ get{ return _isPlaying; } }

public UIBlendAdd uiBlendAdd = null;

[DisplayProperty]
public override Color  Color
{
get{ return _color; }
set
{
_color.a = value.a;

Color color = sharedMesh.colors[0];
color.a = _color.a;
sharedMesh.colors = new Color[]{ color,color,color,color};

}
}

[SerializeField]
private ClockType _eClockType = ClockType.INVISIBLE_CW;
[DisplayProperty]
public  ClockType ClockMode
{
get{ return _eClockType; }
set
{
_eClockType = value;
if( sharedMesh != null )
{
//Vector3[] aTemp = sharedMesh.normalss;
//for( int i = 0; i < aTemp.Length; ++i )
// aTemp[i].z = (int)_eClockType;
// sharedMesh.normalss = aTemp;
LastTickAngle = _lastTickAngle;
StartTickAngle = _startTickAngle;
}
}
}

public bool ChkStartPivot
{
get
{
switch( _eClockType )
{
case ClockType.VISIBIE_CW :
case ClockType.INVISIBLE_CCW :
return true;
default :
return false;
}
}
}
public bool IsVisibleWise{ get{ return _eClockType == ClockType.VISIBIE_CW || _eClockType == ClockType.VISIBLE_CCW; } }
public bool IsClockWise{ get{ return _eClockType == ClockType.VISIBIE_CW || _eClockType == ClockType.INVISIBLE_CW; } }


[SerializeField]
private float _startTickRadius = 0f;
[SerializeField]
private float _startTickAngle = 0f;
[DisplayProperty]
public  float  StartTickAngle
{
get{ return _startTickAngle; }
set
{
GameMath.MinMax( ref value, 0f, 360f );
_startTickAngle = value;
_startTickRadius = GameMath.DegreeToPie( value );

if( ChkStartPivot && sharedMesh != null )
{
   Color[] aColor = sharedMesh.colors;
   for( int i = 0; i < aColor.Length; ++i )
       aColor[i].r = _startTickRadius * 0.1f;
   sharedMesh.colors = aColor;
}

_ResetPercent();
}
}


[SerializeField]
private float _lastTickRadius = GameMath.PIE_DOUBLE;
[SerializeField]
private float _lastTickAngle = 360f;
[DisplayProperty]
public  float  LastTickAngle
{
get{ return _lastTickAngle; }
set
{
GameMath.MinMax( ref value, 0f, 360f );
_lastTickAngle = value;
_lastTickRadius = GameMath.DegreeToPie( value );

if( !ChkStartPivot && sharedMesh != null )
{
   Color[] aColor = sharedMesh.colors;
   for( int i = 0; i < aColor.Length; ++i )
       aColor[i].g = _lastTickRadius * 0.1f;
   sharedMesh.colors = aColor;
}
_ResetPercent();
}
}


[SerializeField]
private float _time = 1f;
[DisplayProperty]
public  float  Time
{
get{ return _time; }
set
{
GameMath.Min( ref value, 0f );
_time = value;
}
}



[SerializeField]
private  float _percent = 0f;
[DisplayProperty]
public float Percent
{
   get{ return _percent; }
   set
   {
GameMath.MinMax( ref value, 0, 1 );
       _percent = value;
       _ResetPercent();
   }
}


private void _ResetPercent()
{
float startTickRadius = _startTickRadius;
if( _lastTickRadius < _startTickRadius )
   startTickRadius -= GameMath.PIE_DOUBLE;

float curTickRadius = Mathf.Lerp( startTickRadius, _lastTickRadius, IsClockWise ? _percent : 1 - _percent );
if( curTickRadius < 0 )
   curTickRadius += GameMath.PIE_DOUBLE;

if( sharedMesh != null )
{
   Color[] aColor = sharedMesh.colors;
   aColor = sharedMesh.colors;
   for( int i = 0; i < aColor.Length; ++i )
   {
       if( ChkStartPivot )
           aColor[i].g = curTickRadius * 0.1f;
       else
           aColor[i].r = curTickRadius * 0.1f;
   }
   sharedMesh.colors = aColor;
}
}


// Percent progress 0 -> 1
public void Play()
{
_deltaTime = 0;
_isPlaying = true;
Percent = 0f;
}


public void Stop()
{
_deltaTime = 0f;
_isPlaying = false;
Percent = 0f;
}


public override void Start()
{
base.Start();

StartTickAngle = _startTickAngle;
LastTickAngle = _lastTickAngle;
ClockMode = _eClockType;
}


public override void GameUpdate()
{
base.GameUpdate();

if( _isPlaying )
{
if( _percent == 1f )
{
_isPlaying = false;
if( uiBlendAdd != null )
uiBlendAdd.Play();
// KHI À̺¥Æ® ³Ö±â
return;
}

if( _deltaTime > _time  )
Percent = 1;
else
Percent = _deltaTime / _time;

_deltaTime += UnityEngine.Time.deltaTime;
}
}

}



-------------------------------------------------------------------------------


UIClockEditor.cs

using UnityEngine;
using UnityEditor;
using System.Collections;

[CustomEditor(typeof(UIClock))]
public class UIClockEditor : UITextureEditor 
{
private UIClock _uiClock = null;
void  OnEnable()
{
_uiClock = target as UIClock;
}

protected override void OnInspectorUpdate()
{
EditorGUILayout.BeginHorizontal();
if( GUILayout.Button( "Play" ) )
_uiClock.Play();
if( GUILayout.Button( "Stop" ) )
_uiClock.Stop();
EditorGUILayout.EndHorizontal();

base.OnInspectorUpdate();

DrawVariable( "uiBlendAdd" );
}

}




Game Developer Leegoon copyright all right reserved since 2010.

Comments