유니티 부트켐프 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;
}
}
}
Game Developer Leegoon copyright all right reserved since 2010.
쿨타임 쉐이더. 입니다.
모듈 베이스로 되어 있지 않아 일단 관련 된 파일만 따로 올립니다.
참고정도 하시면 될 듯 합니다.
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
Post a Comment
덧글쓰기 기능 있는거 아시죠? ㅋㅋ