Related Posts Plugin for WordPress, Blogger...

6-12 Finishing Login User Interface

本章要繼續完成登入畫面,接著來佈置登入按鈕的部分吧。在Loing Window按右鍵,選擇UI/Button。

預設的按鈕真的很醜。

接著自己修改背景圖片跟Text的屬性,Text的部分可以參考我的設定。

設定好以後如下圖,但仍舊覺得文字只有單一白色實在太單調,跟按鈕的配色也不太合。

這邊介紹幾個好用的Script,待會提供原始碼,Gradient.cs可以替UI元件建立漸層色,如下圖設定。

接著文字就會有漸層色了。

然後再使用NicerOutline.cs可以建立外邊框,如下圖設定。

文字的外邊框也做出來了,是否好看很多了呢。

接著替Button建立一個Image名為Press Overlay,這是我要用來自訂Button按下去時的陰影。

將陰影放進來後的結果如下圖,會將整個按鈕跟文字都蓋過去。

接著將Press Overlay拖拉進Button的Target Graphic中,並將Normal Color跟Highlighted Color的Alpha值設為0。這樣一來在普通狀態以及滑鼠移動到按鈕上的狀態,都不會將顯示這個陰影,只要按下去的時候才會出現。

設定完成如下圖。

以下提供Gradient跟NicerOutline的原始碼。
Gradient.cs:

using UnityEngine;
using System.Collections.Generic;

namespace UnityEngine.UI
{
 [AddComponentMenu("UI/Effects/Gradient")]
#if UNITY_5_2 || UNITY_5_3_OR_NEWER
    public class Gradient : BaseMeshEffect
#else
    public class Gradient : BaseVertexEffect
#endif
    {
        [SerializeField] private Color topColor = Color.white;
  [SerializeField] private Color bottomColor = Color.black;

#if UNITY_5_2 || UNITY_5_3_OR_NEWER
        public override void ModifyMesh(VertexHelper vertexHelper)
        {
            if (!this.IsActive())
                return;

            List list = new List();
            vertexHelper.GetUIVertexStream(list);

            ModifyVertices(list);  // calls the old ModifyVertices which was used on pre 5.2

   vertexHelper.Clear();
            vertexHelper.AddUIVertexTriangleStream(list);
        }
#endif

#if UNITY_5_2 || UNITY_5_3_OR_NEWER
        public void ModifyVertices(List vertexList)
#else
        public override void ModifyVertices(List vertexList)
#endif
        {
            if (!this.IsActive())
    return;
   
   int count = vertexList.Count;
   float bottomY = vertexList[0].position.y;
   float topY = vertexList[0].position.y;
   
   for (int i = 1; i < count; i++)
   {
    float y = vertexList[i].position.y;
    if (y > topY)
    {
     topY = y;
    }
    else if (y < bottomY)
    {
     bottomY = y;
    }
   }
   
   float uiElementHeight = topY - bottomY;
   
   for (int i = 0; i < count; i++)
   {
    UIVertex uiVertex = vertexList[i];
    uiVertex.color = uiVertex.color * Color.Lerp(bottomColor, topColor, (uiVertex.position.y - bottomY) / uiElementHeight);
    vertexList[i] = uiVertex;
   }
  }
 }
}


NicerOutline.cs:

/// Credit Melang
/// Sourced from - http://forum.unity3d.com/members/melang.593409/

using System.Collections.Generic;

namespace UnityEngine.UI
{
 [AddComponentMenu("UI/Effects/Nicer Outline")]
#if UNITY_5_2 || UNITY_5_3_OR_NEWER
    public class NicerOutline : BaseMeshEffect
#else
 public class NicerOutline : BaseVertexEffect
#endif
 {
  [SerializeField]
  private Color m_EffectColor = new Color (0f, 0f, 0f, 0.5f);
  
  [SerializeField]
  private Vector2 m_EffectDistance = new Vector2 (1f, -1f);
  
  [SerializeField]
  private bool m_UseGraphicAlpha = true;
  //
  // Properties
  //
  public Color effectColor
  {
   get
   {
    return this.m_EffectColor;
   }
   set
   {
    this.m_EffectColor = value;
    if (base.graphic != null)
    {
     base.graphic.SetVerticesDirty ();
    }
   }
  }
  
  public Vector2 effectDistance
  {
   get
   {
    return this.m_EffectDistance;
   }
   set
   {
    if (value.x > 600f)
    {
     value.x = 600f;
    }
    if (value.x < -600f)
    {
     value.x = -600f;
    }
    if (value.y > 600f)
    {
     value.y = 600f;
    }
    if (value.y < -600f)
    {
     value.y = -600f;
    }
    if (this.m_EffectDistance == value)
    {
     return;
    }
    this.m_EffectDistance = value;
    if (base.graphic != null)
    {
     base.graphic.SetVerticesDirty ();
    }
   }
  }
  
  public bool useGraphicAlpha
  {
   get
   {
    return this.m_UseGraphicAlpha;
   }
   set
   {
    this.m_UseGraphicAlpha = value;
    if (base.graphic != null)
    {
     base.graphic.SetVerticesDirty ();
    }
   }
  }
  
#if UNITY_EDITOR
  protected override void OnValidate ()
  {
   this.effectDistance = this.m_EffectDistance;
   base.OnValidate ();
  }
#endif

  //
  // Methods
  //
  protected void ApplyShadow (List verts, Color32 color, int start, int end, float x, float y)
  {
   //Debug.Log("verts count: "+verts.Count);
   int num = verts.Count * 2;
   if (verts.Capacity < num)
   {
    verts.Capacity = num;
   }
   for (int i = start; i < end; i++)
   {
    UIVertex uIVertex = verts [i];
    verts.Add (uIVertex);
    
    Vector3 position = uIVertex.position;
    //Debug.Log("vertex pos: "+position);
    position.x += x;
    position.y += y;
    uIVertex.position = position;
    Color32 color2 = color;
    if (this.m_UseGraphicAlpha)
    {
     color2.a = (byte)(color2.a * verts [i].color.a / 255);
    }
    uIVertex.color = color2;
    //uIVertex.color = (Color32)Color.blue;
    verts [i] = uIVertex;
   }
  }

#if UNITY_5_2 || UNITY_5_3_OR_NEWER
        public override void ModifyMesh(VertexHelper vertexHelper)
        {
            if (!this.IsActive())
                return;

            List list = new List();
            vertexHelper.GetUIVertexStream(list);

            ModifyVertices(list);  // calls the old ModifyVertices which was used on pre 5.2

   vertexHelper.Clear();
            vertexHelper.AddUIVertexTriangleStream(list);
        }
#endif

#if UNITY_5_2 || UNITY_5_3_OR_NEWER
        public void ModifyVertices(List verts)
#else
        public override void ModifyVertices(List verts)
#endif
        {
            if (!this.IsActive ())
   {
    return;
   }
   
   Text foundtext = GetComponent();
   
   float best_fit_adjustment = 1f;
   
   if (foundtext && foundtext.resizeTextForBestFit)  
   {
    best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive 
    
   }
   
   float distanceX = this.effectDistance.x * best_fit_adjustment;
   float distanceY = this.effectDistance.y * best_fit_adjustment;
   
   int start = 0;
   int count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, distanceY);
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, -distanceY);
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, distanceY);
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, -distanceY);
   
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, distanceX, 0);
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, -distanceX, 0);
   
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, distanceY);
   start = count;
   count = verts.Count;
   this.ApplyShadow (verts, this.effectColor, start, verts.Count, 0, -distanceY);
  }
 }
}


接著新增帳號跟密碼的輸入框,首先在LoginWindow底下新增Empty GameObject名為Content,然後再新增UI/Input Field。

新增InputField之後,先設定Placeholder,這個是用來顯示『提示文字』用的,設定可以參考如下圖。

接著也替該文字新增Shadow,增加立體感。

然後InputField底下的Text也記得與Placeholder使用相同設定。Text才是真正用來輸入文字的部分,輸入時InputField會自動將Placeholder上的提示文字隱藏。

設定完成後的效果應能如下圖。

接著我在InputField內在新增一個小icon。

接著我們替InputField新增一個Focus Overlay的Image吧,當使用者輸入文字的時候,框框的邊緣會有高亮效果。

新增的效果如下圖。

記得將Focus Overlay拖拉進Target Graphic中,並將Normal Color的Alpha值設為0,基本上設定手法與Button差不多。

這樣的話平時的InputField如下圖。

開始輸入文字的時候就會自動有發光的邊緣了。

然後讓我們把這個設定好的InputField直接Duplicate吧。

由於密碼框的輸入需要使用*字號隱藏,請在InputField的Content Type設定中選擇Password,即可達到這個效果。


剩下這個就自行調整吧,調整好如下圖。

可以使用我上一章提供的UIFlippable.cs將密碼框水平反轉,效果更好看。登入介面完成!

留言