2016-11-16 07:48:44 +08:00
/// Credit Brad Nelson (playemgames - bitbucket)
/// Modified Gradient effect script from http://answers.unity3d.com/questions/1086415/gradient-text-in-unity-522-basevertexeffect-is-obs.html
/// <summary>
/// -Uses Unity's Gradient class to define the color
/// -Offset is now limited to -1,1
/// -Multiple color blend modes
///
/// Remember that the colors are applied per-vertex so if you have multiple points on your gradient where the color changes and there aren't enough vertices, you won't see all of the colors.
/// </summary>
using System.Collections.Generic ;
namespace UnityEngine.UI.Extensions
{
2017-05-05 21:25:48 +08:00
[AddComponentMenu("UI/Effects/Extensions/Gradient2")]
2016-11-16 07:48:44 +08:00
public class Gradient2 : BaseMeshEffect {
[SerializeField]
Type _gradientType ;
[SerializeField]
Blend _blendMode = Blend . Multiply ;
[SerializeField]
[Range(-1, 1)]
float _offset = 0f ;
[SerializeField]
UnityEngine . Gradient _effectGradient = new UnityEngine . Gradient ( ) { colorKeys = new GradientColorKey [ ] { new GradientColorKey ( Color . black , 0 ) , new GradientColorKey ( Color . white , 1 ) } } ;
#region Properties
public Blend BlendMode {
get { return _blendMode ; }
2017-06-05 01:19:14 +08:00
set
{
_blendMode = value ;
graphic . SetVerticesDirty ( ) ;
}
2016-11-16 07:48:44 +08:00
}
public UnityEngine . Gradient EffectGradient {
get { return _effectGradient ; }
2017-06-05 01:19:14 +08:00
set
{
_effectGradient = value ;
graphic . SetVerticesDirty ( ) ;
}
2016-11-16 07:48:44 +08:00
}
public Type GradientType {
get { return _gradientType ; }
2017-06-05 01:19:14 +08:00
set
{
_gradientType = value ;
graphic . SetVerticesDirty ( ) ;
}
2016-11-16 07:48:44 +08:00
}
public float Offset {
get { return _offset ; }
2017-06-05 01:19:14 +08:00
set
{
_offset = value ;
graphic . SetVerticesDirty ( ) ;
}
2016-11-16 07:48:44 +08:00
}
# endregion
public override void ModifyMesh ( VertexHelper helper ) {
if ( ! IsActive ( ) | | helper . currentVertCount = = 0 )
return ;
List < UIVertex > _vertexList = new List < UIVertex > ( ) ;
helper . GetUIVertexStream ( _vertexList ) ;
int nCount = _vertexList . Count ;
switch ( GradientType ) {
case Type . Horizontal : {
float left = _vertexList [ 0 ] . position . x ;
float right = _vertexList [ 0 ] . position . x ;
float x = 0f ;
for ( int i = nCount - 1 ; i > = 1 ; - - i ) {
x = _vertexList [ i ] . position . x ;
if ( x > right ) right = x ;
else if ( x < left ) left = x ;
}
float width = 1f / ( right - left ) ;
UIVertex vertex = new UIVertex ( ) ;
for ( int i = 0 ; i < helper . currentVertCount ; i + + ) {
helper . PopulateUIVertex ( ref vertex , i ) ;
vertex . color = BlendColor ( vertex . color , EffectGradient . Evaluate ( ( vertex . position . x - left ) * width - Offset ) ) ;
helper . SetUIVertex ( vertex , i ) ;
}
}
break ;
case Type . Vertical : {
float bottom = _vertexList [ 0 ] . position . y ;
float top = _vertexList [ 0 ] . position . y ;
float y = 0f ;
for ( int i = nCount - 1 ; i > = 1 ; - - i ) {
y = _vertexList [ i ] . position . y ;
if ( y > top ) top = y ;
else if ( y < bottom ) bottom = y ;
}
float height = 1f / ( top - bottom ) ;
UIVertex vertex = new UIVertex ( ) ;
for ( int i = 0 ; i < helper . currentVertCount ; i + + ) {
helper . PopulateUIVertex ( ref vertex , i ) ;
vertex . color = BlendColor ( vertex . color , EffectGradient . Evaluate ( ( vertex . position . y - bottom ) * height - Offset ) ) ;
helper . SetUIVertex ( vertex , i ) ;
}
}
break ;
2017-04-18 04:46:33 +08:00
case Type . Diamond : {
float bottom = _vertexList [ 0 ] . position . y ;
float top = _vertexList [ 0 ] . position . y ;
float y = 0f ;
for ( int i = nCount - 1 ; i > = 1 ; - - i ) {
y = _vertexList [ i ] . position . y ;
if ( y > top ) top = y ;
else if ( y < bottom ) bottom = y ;
}
float height = 1f / ( top - bottom ) ;
helper . Clear ( ) ;
for ( int i = 0 ; i < nCount ; i + + ) helper . AddVert ( _vertexList [ i ] ) ;
float center = ( bottom + top ) / 2f ;
UIVertex centralVertex = new UIVertex ( ) ;
centralVertex . position = ( Vector3 . right + Vector3 . up ) * center + Vector3 . forward * _vertexList [ 0 ] . position . z ;
centralVertex . normal = _vertexList [ 0 ] . normal ;
centralVertex . color = Color . white ;
helper . AddVert ( centralVertex ) ;
for ( int i = 1 ; i < nCount ; i + + ) helper . AddTriangle ( i - 1 , i , nCount ) ;
helper . AddTriangle ( 0 , nCount - 1 , nCount ) ;
UIVertex vertex = new UIVertex ( ) ;
for ( int i = 0 ; i < helper . currentVertCount ; i + + ) {
helper . PopulateUIVertex ( ref vertex , i ) ;
vertex . color = BlendColor ( vertex . color , EffectGradient . Evaluate (
Vector3 . Distance ( vertex . position , centralVertex . position ) * height - Offset ) ) ;
helper . SetUIVertex ( vertex , i ) ;
}
}
break ;
case Type . Radial : {
float left = _vertexList [ 0 ] . position . x ;
float right = _vertexList [ 0 ] . position . x ;
float bottom = _vertexList [ 0 ] . position . y ;
float top = _vertexList [ 0 ] . position . y ;
float x = 0f ;
float y = 0f ;
for ( int i = nCount - 1 ; i > = 1 ; - - i ) {
x = _vertexList [ i ] . position . x ;
if ( x > right ) right = x ;
else if ( x < left ) left = x ;
y = _vertexList [ i ] . position . y ;
if ( y > top ) top = y ;
else if ( y < bottom ) bottom = y ;
}
float width = 1f / ( right - left ) ;
float height = 1f / ( top - bottom ) ;
helper . Clear ( ) ;
float centerX = ( right + left ) / 2f ;
float centerY = ( bottom + top ) / 2f ;
float radiusX = ( right - left ) / 2f ;
float radiusY = ( top - bottom ) / 2f ;
UIVertex centralVertex = new UIVertex ( ) ;
centralVertex . position = Vector3 . right * centerX + Vector3 . up * centerY + Vector3 . forward * _vertexList [ 0 ] . position . z ;
centralVertex . normal = _vertexList [ 0 ] . normal ;
centralVertex . color = Color . white ;
int steps = 64 ;
for ( int i = 0 ; i < steps ; i + + )
{
UIVertex curVertex = new UIVertex ( ) ;
float angle = ( float ) i * 360f / ( float ) steps ;
float curX = Mathf . Cos ( Mathf . Deg2Rad * angle ) * radiusX ;
float curY = Mathf . Sin ( Mathf . Deg2Rad * angle ) * radiusY ;
curVertex . position = Vector3 . right * curX + Vector3 . up * curY + Vector3 . forward * _vertexList [ 0 ] . position . z ;
curVertex . normal = _vertexList [ 0 ] . normal ;
curVertex . color = Color . white ;
helper . AddVert ( curVertex ) ;
}
helper . AddVert ( centralVertex ) ;
for ( int i = 1 ; i < steps ; i + + ) helper . AddTriangle ( i - 1 , i , steps ) ;
helper . AddTriangle ( 0 , steps - 1 , steps ) ;
UIVertex vertex = new UIVertex ( ) ;
for ( int i = 0 ; i < helper . currentVertCount ; i + + ) {
helper . PopulateUIVertex ( ref vertex , i ) ;
vertex . color = BlendColor ( vertex . color , EffectGradient . Evaluate (
Mathf . Sqrt (
Mathf . Pow ( Mathf . Abs ( vertex . position . x - centerX ) * width , 2f ) +
Mathf . Pow ( Mathf . Abs ( vertex . position . y - centerY ) * height , 2f ) ) * 2f - Offset ) ) ;
helper . SetUIVertex ( vertex , i ) ;
}
}
break ;
2016-11-16 07:48:44 +08:00
}
}
Color BlendColor ( Color colorA , Color colorB ) {
switch ( BlendMode ) {
default : return colorB ;
case Blend . Add : return colorA + colorB ;
case Blend . Multiply : return colorA * colorB ;
}
}
public enum Type {
Horizontal ,
2017-04-18 04:46:33 +08:00
Vertical ,
Radial ,
Diamond
2016-11-16 07:48:44 +08:00
}
public enum Blend {
Override ,
Add ,
Multiply
}
}
}