123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- using UnityEngine;
- using System.Collections;
- using UnityEngine.UI;
- using UnityEngine.EventSystems;
- namespace CurvedUI
- {
- #if !UNITY_5_1 && !UNITY_5_2
- /// <summary>
- /// Creates a recttransform caret with image component that can be curved with curvedUI. Hides inputfield's original caret.
- /// </summary>
- public class CurvedUIInputFieldCaret : MonoBehaviour, ISelectHandler, IDeselectHandler
- {
- //references
- InputField myField;
- RectTransform myCaret;
- Color origCaretColor;
- Color origSelectionColor;
- //variables
- bool selected = false;
- bool selectingText = false;
- //settings
- int lastCharDist = 2;
- void Awake()
- {
- myField = this.GetComponent<InputField>();
- }
- void Update()
- {
- //only update the caret's position when the field is selected.
- if (selected)
- UpdateCaret();
- }
- /// <summary>
- /// On select, set the caret active and start blinker coroutine.
- /// </summary>
- /// <param name="eventData"></param>
- public void OnSelect(BaseEventData eventData)
- {
- if (myCaret == null)
- CreateCaret();
- selected = true;
- myCaret.gameObject.SetActive(true);
- StartCoroutine(CaretBlinker());
- }
- /// <summary>
- /// Hide the caret on deselect.
- /// </summary>
- /// <param name="eventData"></param>
- public void OnDeselect(BaseEventData eventData)
- {
- selected = false;
- myCaret.gameObject.SetActive(false);
- }
- /// <summary>
- /// Simple blinker. Blinks the caret if inputfield is selected and user is not selecting text.
- /// </summary>
- /// <returns></returns>
- IEnumerator CaretBlinker()
- {
- while (selected)
- {
- myCaret.gameObject.SetActive(selectingText ? true : !myCaret.gameObject.activeSelf);
- yield return new WaitForSeconds(0.5f / (float)myField.caretBlinkRate);
- }
- }
- void CreateCaret()
- {
- //lets create a curvedui caret and copy the settings from our input field
- GameObject go = new GameObject("CurvedUICaret");
- go.AddComponent<RectTransform>();
- go.AddComponent<Image>();
- go.AddComponent<CurvedUIVertexEffect>();
- go.transform.SetParent(this.transform);
- go.transform.localScale = Vector3.one;
- (go.transform as RectTransform).anchoredPosition3D = Vector3.zero;
- //(go.transform as RectTransform).pivot = new Vector2(0, 0.5f);
- (go.transform as RectTransform).pivot = new Vector2(0, 1.0f);
- go.GetComponent<Image>().color = myField.caretColor;
- myCaret = go.transform as RectTransform;
- go.transform.SetAsFirstSibling();
- //save original color and hide the original caret
- myField.customCaretColor = true;
- origCaretColor = myField.caretColor;
- myField.caretColor = new Color(0, 0, 0, 0);
- origSelectionColor = myField.selectionColor;
- myField.selectionColor = new Color(0, 0, 0, 0);
- go.gameObject.SetActive(false);
- }
- void UpdateCaret()
- {
- if (myCaret == null)
- CreateCaret();
- //Debug.Log("caret:" + myField.caretPosition + " / focus:"+ myField.selectionFocusPosition + " / anchor:" + myField.selectionAnchorPosition + " / charc:" + myField.textComponent.cachedTextGenerator.characterCount + " / charvis:" + myField.textComponent.cachedTextGenerator.characterCountVisible);
- Vector2 newCaretPos = GetLocalPositionInText(myField.caretPosition);
- //RectTransform originalCaret = (RectTransform)myField.transform.FindChild(myField.name + " Input Caret");
- if (myField.selectionFocusPosition != myField.selectionAnchorPosition) // user is selecting text is those two are not equal.
- {
- selectingText = true;
- Vector2 selectionSize = new Vector2(
- GetLocalPositionInText(myField.selectionAnchorPosition).x - GetLocalPositionInText(myField.selectionFocusPosition).x,
- GetLocalPositionInText(myField.selectionAnchorPosition).y - GetLocalPositionInText(myField.selectionFocusPosition).y
- );
- newCaretPos = selectionSize.x < 0 ? GetLocalPositionInText(myField.selectionAnchorPosition) : GetLocalPositionInText(myField.selectionFocusPosition);
- selectionSize = new Vector2(Mathf.Abs(selectionSize.x), Mathf.Abs(selectionSize.y) + myField.textComponent.fontSize);
- myCaret.sizeDelta = new Vector2(selectionSize.x, selectionSize.y);
- myCaret.anchoredPosition = newCaretPos;
- myCaret.GetComponent<Image>().color = origSelectionColor;
- }
- else { // user is not selecting text, just update the caret position.
- selectingText = false;
- //myCaret.sizeDelta = new Vector2(myField.caretWidth, originalCaret == null ? 10 : originalCaret.rect.height);
- myCaret.sizeDelta = new Vector2(myField.caretWidth, myField.textComponent.fontSize);
- myCaret.anchoredPosition = newCaretPos;
- myCaret.GetComponent<Image>().color = origCaretColor;
- }
- }
- /// <summary>
- /// Returns the position in inputfield's rectransform local space, based on character position in text. Pretty neat actually.
- /// </summary>
- /// <param name="charNo"></param>
- /// <returns></returns>
- Vector2 GetLocalPositionInText(int charNo)
- {
- if (myField.isFocused)
- {
- TextGenerator gen = myField.textComponent.cachedTextGenerator;
- if (charNo > gen.characterCount - 1) //do not go over the text length.
- charNo = gen.characterCount - 1;
- if (charNo > 0)
- {
- UICharInfo charInfo = gen.characters[charNo - 1];
- float x = (charInfo.cursorPos.x + charInfo.charWidth) / myField.textComponent.pixelsPerUnit + lastCharDist;
- float y = (charInfo.cursorPos.y) / myField.textComponent.pixelsPerUnit;
- return new Vector2(x, y);
- }
- else {
- UICharInfo charInfo = gen.characters[charNo];
- float x = (charInfo.cursorPos.x) / myField.textComponent.pixelsPerUnit;
- float y = (charInfo.cursorPos.y) / myField.textComponent.pixelsPerUnit;
- return new Vector2(x, y);
- }
- }
- else return Vector2.zero; // field not focused, return 0,0
- }
- #region SETTERS AND GETTERS
- public Color CaretColor {
- get { return origCaretColor; }
- set { origCaretColor = value; }
- }
- public Color SelectionColor {
- get { return origSelectionColor; }
- set { origSelectionColor = value; }
- }
- public float CaretBlinkRate {
- get { return myField.caretBlinkRate; }
- set { myField.caretBlinkRate = value; }
- }
- #endregion
- #else
- public class CurvedUIInputFieldCaret : MonoBehaviour
- {
- //Unity before 5.3 does not contain methods necessary to curve the input field caret without changing original script.
- #endif
- }
- }
|