NGUI 사용 흐르는 문자열 만들기
가. 흐르는 문자열 만들기
- 사용 조건 : NGUI가 있어야 함.
나. 코드
- NGUI UILabel.cs 파일내에 있는 overflow enum 값에 FlowText 라는 값을 추가해준다.
해당 옵션이 되어져 있을 경우 글자가 흐르게 할 예정이다.
1 2 3 4 5 6 7 8 | public enum Overflow { ShrinkContent, ClampContent, ResizeFreely, ResizeHeight, FlowText, } | cs |
- UILabel.cs 파일 의 OnStart에 해당 라벨이 흐르게 되는 옵션을 가지고 있는지 체크하도록 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | protected override void OnStart () { base.OnStart(); // Legacy support if (mLineWidth > 0f) { mMaxLineWidth = Mathf.RoundToInt(mLineWidth); mLineWidth = 0f; } if (!mMultiline) { mMaxLineCount = 1; mMultiline = true; } // Whether this is a premultiplied alpha shader mPremultiply = (material != null && material.shader != null && material.shader.name.Contains("Premultiplied")); #if DYNAMIC_FONT // Request the text within the font ProcessAndRequest(); #endif if (overflowMethod == Overflow.FlowText) { gameObject.GetComponent<UILabel>().CheckTextLength(); } } | cs |
※ 용도에 따라 다르게 하겠지만 여러 나라의 언어를 사용 할 예정이였어서 스크립트에서 문자열을 각나라에 맞도록 바 꾸었을 시 문자열 길이가 본래 사이즈보다 초과된다면 흐르게 만들려 했기 때문에 CheckTextLength라는 이름을 하게 되었다.
- UILabel.cs에 문자열이 바뀌거나 했을 때도 작동할 수 있게 아래를 추가해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public string text { get { return mText; } set { if (mText == value) return; if (string.IsNullOrEmpty(value)) { if (!string.IsNullOrEmpty(mText)) { mText = ""; if (overflowMethod == Overflow.FlowText) { gameObject.GetComponent<UILabel>().text = ""; } MarkAsChanged(); ProcessAndRequest(); } } else if (mText != value) { mText = value; if (overflowMethod == Overflow.FlowText) { gameObject.GetComponent<UILabel>().text = value; } MarkAsChanged(); ProcessAndRequest(); } if (overflowMethod == Overflow.FlowText) { gameObject.GetComponent<UILabel>().CheckTextLength(); } if (autoResizeBoxCollider) ResizeCollider(); } } | cs |
- 아래 함수도 추가로 UILabel.cs에 넣어준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | public void CheckTextLength() { if (this.transform.parent != null) { if (this.transform.parent.name.Contains("FlowTextPanel")) { ResetPosition(); return; } else if (this.transform.parent.parent != null) { if (this.transform.parent.parent.name.Contains("FlowTextPanel")) { ResetPosition(); return; } } } if (this.overflowMethod != Overflow.FlowText) { return; } if (this.pivot == Pivot.Center || this.pivot == Pivot.Left) { Vector2 oriSize = new Vector2(this.width, this.height); this.MakePixelPerfect(); Vector2 fullSize = new Vector2(this.width, this.height); this.overflowMethod = UILabel.Overflow.FlowText; this.width = (int)oriSize.x; this.height = (int)oriSize.y; if (oriSize.x < fullSize.x) { GameObject obj = new GameObject(); obj.name = "FlowTextPanel"; LabelFlow flow = obj.AddComponent<LabelFlow>(); UIPanel uipanel = obj.AddComponent<UIPanel>(); uipanel.clipping = UIDrawCall.Clipping.SoftClip; uipanel.clipSoftness = new Vector2(0, 0); uipanel.SetRect(0, 0, this.width, this.height * 1.2f); uipanel.clipOffset = new Vector2(this.width / 2f, 0); Rigidbody rigid = obj.AddComponent<Rigidbody>(); rigid.isKinematic = true; obj.layer = LayerMask.NameToLayer("UI"); CommonUtils.SetParent(this.transform.parent, obj.transform); if (this.pivot != Pivot.Left) { this.pivot = Pivot.Left; } obj.transform.localPosition = new Vector3(this.transform.localPosition.x, this.transform.localPosition.y, 0); GameObject FirstLabel = Instantiate(this.gameObject); FirstLabel.gameObject.SetActive(false); CommonUtils.SetParent(obj, FirstLabel); FirstLabel.gameObject.SetActive(true); this.gameObject.SetActive(false); CommonUtils.SetParent(FirstLabel, this.gameObject); this.gameObject.SetActive(true); FirstLabel.GetComponent<UILabel>().MakePixelPerfect(); this.MakePixelPerfect(); flow.Text.Add(FirstLabel.transform); flow.Text.Add(this.transform); flow.fWidth = this.width; flow.ResetPosition(); } } } public void ResetPosition() { LabelFlow flow = transform.parent.GetComponent<LabelFlow>(); if (flow == null) { if (transform.parent.parent != null) { flow = transform.parent.parent.GetComponent<LabelFlow>(); } } if (flow != null) { flow.ResetPosition(); } } | cs |
- LabelFlow.cs 파일을 만들어 아래 내용을 추가해준다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | using UnityEngine; using System.Collections; using System.Collections.Generic; public class LabelFlow : MonoBehaviour { public float ScrollSpeed =30f; public float WGap = 5f; public float fWidth = 0.0f; public List<Transform> Text = new List<Transform>(); Vector3 OriPos = Vector3.zero; bool IsActive = true; float fTime = 0.0f; void OnDisable() { IsActive = false; } void Update() { if(!IsActive) { ResetPosition(); } if (fWidth != Text[0].GetComponent<UILabel>().width) { fWidth = Text[0].GetComponent<UILabel>().width; ResetPosition(); } if ((fTime += Time.deltaTime) >= 0.01f) { if (Text[0].localPosition.x <= -OriPos.x - Text[0].GetComponent<UILabel>().width - WGap) { Transform temp = Text[0]; Vector3 pos = Text[0].localPosition; pos.x += Text[0].GetComponent<UILabel>().width + WGap; CommonUtils.SetParent(Text[0].parent, Text[1]); Text[1].localPosition = pos; Text.Remove(Text[0]); Text.Add(temp); CommonUtils.SetParent(Text[0], Text[1]); Text[1].transform.localPosition = Text[0].localPosition + new Vector3(Text[0].GetComponent<UILabel>().width + WGap, 0, 0); } Vector3 temppos = Text[0].localPosition; temppos.x -= ScrollSpeed * Time.deltaTime; Text[0].localPosition = temppos; } } public void ResetPosition() { Text[0].localPosition = OriPos; Text[1].transform.localPosition = Text[0].localPosition + new Vector3(Text[0].GetComponent<UIWidget>().localSize.x + WGap, 0, 0); IsActive = true; } public void ChangeText(string _text) { foreach(Transform label in Text) { UILabel uilabel = label.GetComponent<UILabel>(); if ( label.name.Contains("Clone")) { uilabel.text = _text; } uilabel.MakePixelPerfect(); } } } | cs |
다. 문자열이 흐르는 조건
1. 게임이 실행되고 스크립트 상에서 문자열을 변경하였는데 OverFlow값이 FlowText이고 문자열의 길이가
라벨의 크기 보다 클 경우.
2. 게임이 실행 되었을 때 문자열의 길이가 라벨의 크기보다 클 경우.
- 위 두 경우에 문자열이 흐르게 되었다.
라. 주의
- 해당 코드를 사용하는 UI는 프리팹으로 만들어 진 것을 스폰시켜서 사용하는 방법을 할것.
그렇게 하지 않으면 라벨 앞에 생성된 클립핑용 패널까지 저장될 수 있음.
- 언어가 변경되어 텍스트 길이가 줄어들 시 UI를 파괴했다가 다시 생성하는 것을 추천 않그럴 경우
위와 마찬가지로 생성된 클립핑 패널과 문자열 흐르는 것이 멈추지 않음.
마. 결과
- 실행 과 동시에 보라색 클립핑용 패널이 생성되는 것을 볼 수 있다.