블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2801)
Unity3D (857)
Script (91)
Extensions (16)
Effect (3)
NGUI (81)
UGUI (9)
Physics (2)
Shader (37)
Math (1)
Design Pattern (2)
Xml (1)
Tips (201)
Link (23)
World (1)
AssetBundle (25)
Mecanim (2)
Plugins (80)
Trouble Shooting (70)
Encrypt (7)
LightMap (4)
Shadow (4)
Editor (12)
Crash Report (3)
Utility (9)
UnityVS (2)
Facebook SDK (2)
iTween (3)
Font (13)
Ad (14)
Photon (2)
IAP (1)
Google (8)
Android (51)
iOS (45)
URP (2)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (234)
협업 (61)
3DS Max (3)
Game (12)
Utility (140)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

Unity의 동적 글꼴을 사용하여 텍스트를 그릴 때 두 개의 UI 인터페이스가 열리면 그 뒤에 있는 텍스트가 깨집니다(완전히 엉망이 됨). 내가 사용하는 UI 플러그인은 Daikon Forge입니다. 라벨 업데이트 메커니즘으로 인해 최종 성능이 깨진 텍스트 표시보다 나쁠 수 있습니다. 텍스트 컨트롤이 계속 새로 고쳐지고 열릴 새 인터페이스가 표시되지 않을 가능성이 큽니다.

         이것은 근본적으로 Unity의 동적 글꼴 구현이 충분히 똑똑하지 않다는 사실 때문입니다. 이론적으로 NGUI에도 이러한 문제가 있습니다. 동적 글꼴을 사용하고 많은 텍스트를 렌더링하는 한.

         NGUI와 Daikon Forge는 동적 글꼴인 텍스트를 그릴 때 내부적으로 Unity의 글꼴을 사용합니다. RequestCharactersInTexture 함수를 사용하여 글꼴에 텍스트 정보 업데이트를 요청한 다음 GetCharacterInfo를 사용하여 렌더링할 텍스트 정보를 가져옵니다. GetCharacterInfo를 호출할 때 RequestCharactersInTexture를 통해 모든 텍스트가 요청되었는지 확인하십시오.

         요청 시점에 Font 내부에 유지되는 텍스처가 충분하지 않으면 textureRebuildCallback의 콜백이 트리거되어 Font를 사용하는 외부 객체에 내부 텍스처가 업데이트되었고 외부 객체를 새로 고쳐야 함을 알립니다.

        Unity 글꼴의 기본 텍스처 크기는 256x256이며 순수 영어 글꼴의 경우에는 충분합니다. 하지만 한자나 일본어 같은 동양글꼴은 전혀 부족하다. 앞에서 언급한 두 플러그인은 텍스트를 그릴 때 단락을 요청하는 데 사용되며, Unity의 새로 고침 콜백이 트리거되면 모든 텍스트 컨트롤이 새로 고쳐집니다. 이렇게 하면 글꼴이 쉽게 깨질 수 있습니다. 정상적인 상황에서는 한 번에 많은 텍스트를 요청하지 않으며 사용된 텍스처는 256x256을 초과하지 않으며 Unity는 텍스처 크기를 자동으로 확장하지 않습니다. 그리고 콜백 함수에서 글꼴을 다시 새로 고칠 때 텍스처가 충분하지 않아 다른 새로 고침 콜백을 트리거하기 쉽습니다. 따라서 중단되고 지속적으로 새로 고쳐지는 상황을 표시하기 위해 텍스트 컨트롤이 전송됩니다.

        문제의 원인을 알면 해결책이 나옵니다. 충분한 텍스트를 요청하는 한 Unity는 내부적으로 텍스처 크기를 자동으로 확장하므로 지속적인 새로 고침 상황을 피할 수 있습니다. 한자 2000자 텍스트를 준비했는데, 텍스트 정보 요청 후 내부 텍스쳐를 기본적으로 게임에 충분한 크기인 1024x1024 크기로 확장했습니다. 어느 날 이것이 충분하지 않다고 생각되면 한자를 더 준비하고 질감을 2048x1024로 확장하십시오.

 

static string chineseTxt = null;
public UnityEngine.Font baseFont;

public void FixBrokenWord()
{
    if (chineseTxt == null) 
    {
        TextAsset txt = Resources.Load("config/chinese") as TextAsset;
        chineseTxt = txt.ToString();
    }

    baseFont.RequestCharactersInTexture(chineseTxt);
    Texture texture = baseFont.material.mainTexture; // Font的内部纹理
    Debug.Log(string.Format("texture:{0} {1}", texture.width, texture.height)); // 纹理大小
}


그 중 baseFont는 NGUI나 Daikon Forge의 텍스트 렌더링 컨트롤에 사용되는 UnityEngine.Font입니다.baseFont를 초기화할 때 FixBrokenWord 함수를 호출합니다(한 번만 호출하면 됨). 일반적으로 사용되는 한자 목록이 포함된 텍스트를 읽은 다음(인터넷에서 일반적으로 사용되는 한자 목록에서 복사하기만 하면 됨) 이 텍스트의 정보를 요청하면 내부 텍스처가 자동으로 확장됩니다.

 

[출처] https://blog.csdn.net/e295166319/article/details/54861275

 

Unity动态字体文字破碎的解决方法(Dynamic Font Broken)_起个名字真的好难啊的博客-CSDN博客

 使用Unity的动态字体绘制文字的时候,打开两个ui界面的时候,后面的文字会显示破碎(完全乱掉)。我使用的ui插件是Daikon Forge,由于其label的更新机制问题,最终表现的结果可能比一个文本显

blog.csdn.net

 

반응형
Posted by blueasa
, |

게임도중 핸드폰에서 Home 키를 눌러 배경화면으로 이동 후 Server와 끊기기를 기다리고 다시 Server와 리커넥팅 되도록 해서 팝업 떴는데.. Font가 깨졌다. 뭐지..

 

....

 

UILabel 에서 DynamicFont 가 이상한 것 같다는 사수님의 말을 듣고 구글링하고 임시 해결방안으로 Font 스크립트에 접근해 미리(반강제?) 쓸 텍스트스트링을 넣어줌으로 해결을 하였다!! 코드는 대충 이렇다! 

 

Font fc_Font_KR = GameObjectUtil.FindChildComponentByName<UILabel>(MainUIManager.Instance.uiMsgBox.transform, "Txt.Desc").trueTypeFont;//(MainUIManager.Instance.uiMsgBox.transform, "Txt.Desc");

fc_Font_KR.RequestCharactersInTexture(Utility.GetStringFromTBL(250091), 16, FontStyle.Normal);

 

주요 함수는 Font.RequestCharactersInTexture(string str, size, FontStyle); 

 

함수 공부는 개인적으로.. 는..

 

구글링을 하던중 .. 좋은 지식 공유

 

https://www.facebook.com/be2ls/posts/644653395565677

 

밑에는 내용 !

-------------------------------------------------------------------------------------------------------------

 

* 유니티에서 Dynamic Font의 글자 사라짐 문제 대응 방법

유니티에서 지원하는 Dynamic Font는 상당히 편리하다.
기존에 한글 폰트를 화면에 표시하려면,
한글 유니코드에 해당하는 모든 글자를 폰트 텍스쳐에 담아놓고
써야해서, 메모리 낭비가 컸고, 글자 크기도 크게 하기가 힘들었다.

반면 Dynamic Font는 그때 그때 사용하는 글자들만 폰트 텍스쳐에 그려두고 사용하기 때문에
메모리 낭비가 적고, 폰트를 크게 표시할 수 있다는 장점이 있다.

하지만, 유니티 자체의 버그인지 특정 폰의 문제인지 몇몇 폰에서 플레이를 하다보면,
글자들이 깨지거나, 일부 글자가 아예 표시되지 않는 버그가 발견되고 있고,
현재까지 배포된 유니티 버전에서는 아직 해결되지 않은 것으로 보인다.

해결 방법을 구글링 해보았지만, 아직 완벽한 해결책은 없는 것 같아서
직접 여러가지 실험을 해보고 대응 방법을 찾아보았다.

1. Dynamic Font의 텍스쳐 관리 방식

맨 처음 게임이 실행되면 기본 폰트 텍스쳐 크기는 256*256이다.
여기에 글자들이 추가되면서 글자를 추가할 공간이 없을 때
256*256이 256*512, 512*512, 그 다음에는 512*1024 이런식으로 텍스쳐 크기가 증가한다.

폰트 텍스쳐에 새로운 글자가 추가되었는데 더이상 추가할 수 있는 공간이 없을 때, 
폰트 텍스쳐가 재정렬되는데, 이 경우 크기가 변경될 수도 있고, 변하지 않을 때도 있다.
더 이상 글자를 추가할 공간이 없을 때, 사용하지 않는 글자들을 정리하기 때문에
정리를 하고 나서 공간이 남는 경우에는 크기가 그대로 유지 된다.
나름 합리적으로 폰트 텍스쳐를 관리하고 있는 것인데,
문제는 특정 폰에서 이 순간에 글자가 사라지는 것이다.

실험을 해본 결과 문제가 되는 폰에서는 폰트 텍스쳐가 리셋되는 순간 크기의 변화가 있으면
정상적으로 표시가 되는데, 사이즈의 변화가 없으면 일부 글자가 표시되지 않는 문제가 발생하고 있었다.

2. 대응 방법

대응방법은 아름답지는 않지만, 단순한 편이다. 
폰트 텍스쳐가 리셋되는 순간 만약 폰트 텍스쳐의 크기가 변경되지 않았다면,
변경될 때까지 폰트 텍스쳐에 존재하지 않는 글자를 계속 추가해주는 것이다.
코딩은 대략 다음과 같다.

1) 유니티의 Font에는 Font.textureRebuildCallback이라는 콜백함수를 등록할 수 있다.
게임 시작 시점에 콜백 함수에 특정 함수를 지정해두면, 폰트 텍스쳐의 리셋 시점에 해당 함수가 
호출된다. 
ex: this.font.textureRebuildCallback = this.SizeChanged;

2) 시작 시점의 폰트 텍스쳐의 크기를 변수로 저장해둔다.

ex: 
this.fontWidth = this.font.material.mainTexture.width;
this.fontHeight = this.font.material.mainTexture.height;

3) 문제는 폰트 텍스쳐 크기가 변하지 않는 경우이기 때문에, 
콜백함수 안에 폰트 텍스쳐의 크기가 기존 크기와 같은지를 체크한다.

ex: 
if (this.font.material.mainTexture.width == this.fontWidth && this.font.material.mainTexture.height == this.fontHeight)
{
...

4) 기존 사이즈와 똑같으면, 한글을 맨처음부터 한글자씩 집어넣는다.
맨 처음 '가'를 font.GetCharacterInfo를 이용해서, 폰트 텍스쳐에 '가' 글자가 들어있는지 확인해서,
들어있지 않다면 font.RequestCharactersInTexture함수를 이용해서, '가'를 추가해준다.
처음에는 5글자 정도를 추가하고, Invoke함수 등을 이용해서 잠시 기다린다.
만약, 추가한 5글자로 인해서, 크기가 커진다면 다시 콜백함수가 호출될 것이고, 그렇다면 글자들이 제대로 보일 것이므로, 
해당 루틴을 끝낸다.
하지만, 커지지 않았다면, 다시 10글자 정도를 추가하고, 그래도 안되면 15글자로 늘리는 방식이다.
이런 루틴을 반복하다보면 어느 순간 폰트 텍스쳐의 크기가 커진다.
(폰트 사이즈가 너무 작고, 폰트 텍스쳐 크기가 굉장히 커서 모든 한글 글자를 포함할 경우라면 무한루프가 될 수도 있을거 같다.)

한글을 자동으로 하나씩 추가하려면, 
아래와 같은 코드를 이용해서, 초중종성의 값을 증가시켜가면 된다.

ushort mUniCodeKoreanBase = 0xAC00;
int iUniCode = mUniCodeKoreanBase + (curFirst * 21 + curMiddle) * 28 + curEnd;
char temp = System.Convert.ToChar(iUniCode);

3. 결론

문제가 있던 폰에서 테스트해 본 결과, 폰트 텍스쳐의 크기가 리셋되는 순간 잠깐 동안 일부 글자가 안보이다가,
곧바로 글자들이 제대로 복구되었다.
아주 깔끔한 해결책은 아니지만, 이정도면 충분히 쓸만하지 않을까 싶다.

어서 빨리 유니티에서 완벽한 패치가 나오면 좋겠다.

-------------------------------------------------------------------------------------------------------------

 

잉`s 블로그 : 네이버 블로그

I.. N.. G..

blog.naver.com

 

반응형
Posted by blueasa
, |

- ParticleSystem, Spine, TMP 등 Renderer를 가진 오브젝트들을 NGUI 위에 올리고 Depth를 맞추기 위한 소스

  (NGUI Widget의 Depth 제어 부분을 Renderer를 가진 오브젝트에서도 셋팅되도록 함)

- 출처에서는 ParticleSystem용으로 이름을 지어놨는데 어차피 Renderer를 가지고 있는 것들은 다 되는거라 이름 변경함

 

NGUIRendererWidget.cs
0.00MB

 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[AddComponentMenu("NGUI/UI/NGUI Renderer Widget")]
public class NGUIRendererWidget : UIWidget
{
    protected Renderer m_Renderer;
    protected Material m_Mat;

    public override Material material
    {
        get
        {
            return m_Mat;
        }

        set
        {
            if (m_Mat != value)
            {
                RemoveFromPanel();
                m_Mat = value;
                MarkAsChanged();
            }
        }
    }

    protected override void OnEnable()
    {
        Init();
        base.OnEnable();
    }

    protected void Init()
    {
        if (null == m_Renderer)
        {
            m_Renderer = GetComponent<Renderer>();
        }

        if (null == m_Renderer)
        {
            return;
        }

        if (null == material)
        {
            if (false == Application.isPlaying)
            {
                material = m_Renderer.sharedMaterial;
                m_Renderer.sharedMaterial = material;
            }
            else
            {
                material = m_Renderer.material;
                m_Renderer.material = material;
            }
        }
    }

    private void OnWillRenderObject()
    {
        if (null != drawCall && drawCall.finalRenderQueue != material.renderQueue)
        {
            material.renderQueue = drawCall.finalRenderQueue;
        }

        if (Application.isPlaying == true && m_Renderer.material != material)
        {
            m_Renderer.material = material;
        }
    }

    public override void OnFill(List<Vector3> verts, List<Vector2> uvs, List<Color> cols)
    {
        for (int i = 0; i < 4; i++)
        {
            verts.Add(Vector3.zero);
            uvs.Add(Vector2.zero);
            cols.Add(color);
        }
    }
}

 

[출처] https://tenlie10.tistory.com/169

 

[Unity | 유니티] NGUI와 ParticleSystem간 Depth 조정

ParticleSystem에 해당 스크립트를 추가하고 타 NGUI 컴포넌트처럼 Depth값을 조정하면 된다. UIParticleWidget.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..

tenlie10.tistory.com

 

반응형
Posted by blueasa
, |

[NGUI 2020.2.2 사용 중..]

 

NGUI에서 UI가 가릴 때 Game 내 일반 오브젝트에 영향을 안주게 막기 위해서

예전에는 UICamea.hoveredObject를 사용했는데, 이번에 사용해보니 값이 이상하다.

그래서 좀 찾아보니 UICamea.IsOverUI가 있다.

참조 링크의 내용에는 문제가 있는 것처럼 말하긴 하는데 빌드해서 봐도 별다른 문제점은 없어보여서 일단 쓰기로 함.

 

[참조] http://www.tasharen.com/forum/index.php?topic=13282.0

 

UICamea.hoveredObject, UICamera.fallThrough, IsOver UI Problem.

When 3D Object and NGUI Object located same position on viewPort, "if(UICamera.hoveredObject != null)" code only touched NGUI Object. This code is no problem NGUI 3.0.2 version, Editor and Mobile too. But, latest version "UICamera.hoveredObject" is pointed

www.tasharen.com

[다른방식] https://blueasa.tistory.com/2549

 

[펌] NGUI와 일반 오브젝트 구분 피킹법

NGUI 를 사용하면서 GUI에 가린 오브젝트들이 GUI와 같이 클릭되는 현상을 게임 제작하면 많이들 보게됩니다. 그럴때는 아래 소스에서 작동하는 녀석으로 쓰면됩니다. if (UICamera.Raycast (Input.mousePosit

blueasa.tistory.com

 

반응형
Posted by blueasa
, |

NGUI 를 사용하면서 GUI에 가린 오브젝트들이 GUI와 같이 클릭되는 현상을 게임 제작하면 많이들 보게됩니다. 그럴때는 아래 소스에서 작동하는 녀석으로 쓰면됩니다.

 

if (UICamera.Raycast (Input.mousePosition) == true) 
{

        // NGUI 오브젝트가 선택되었음
} else

{

       // 해당 일반 오브젝트 선택되었음

}

 

or

 

if(null == UICamera.hoveredObject)

{

    // 게임쪽 클릭 처리

}

 

본인은 2번째 소스로 쓰다가 최근에 들어서 모바일에서 작동이 잘 안하는 관계로 1번을 사용하고 있습니다.



출처: https://sjcy.tistory.com/entry/NGUI와-일반-오브젝트-구분-피킹법 [Charlotte's web]

 

NGUI와 일반 오브젝트 구분 피킹법

NGUI 를 사용하면서 GUI에 가린 오브젝트들이 GUI와 같이 클릭되는 현상을 게임 제작하면 많이들 보게됩니다. 그럴때는 아래 소스에서 작동하는 녀석으로 쓰면됩니다. if (UICamera.Raycast (Input.mousePosit

sjcy.tistory.com

 

반응형
Posted by blueasa
, |

Re: UI Label line count

« Reply #5 on: July 19, 2013, 07:04:08 PM »

Just count instances of '\n' in the UILabel.processedText

 

 

[출처] www.tasharen.com/forum/index.php?topic=4509.0

 

UI Label line count

how can i get the total number of lines which will be required to show the label if it is limited with max line count. i will try and explain this more suppose i have a label which has suppose 40 lines, now to make label look small i set the Max Line var f

www.tasharen.com

 

[참조] devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=42437

 

데브코리아

한국 게임개발자 커뮤니티

devkorea.co.kr

 
반응형
Posted by blueasa
, |

[링크]

https://qits.tistory.com/m/entry/NGUI-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%8A%90%EB%A0%A4%EC%A7%80%EB%8A%94-%ED%98%84%EC%83%81-%EC%9E%AC%EC%82%AC%EC%9A%A9%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%A7%80-%EC%95%8A%EA%B3%A0-%EA%B8%B0%EB%8A%A5-%EA%B0%9C%EC%84%A0

 

NGUI 스크롤 느려지는 현상 (재사용리스트를 사용하지 않고 기능 개선)

NGUI로 스크롤 을 구현하다보면 Grid를 사용하는 것이 일반적인데, 아이템이 많아지면 느려지는것을 자주 보게 된다. 아이템이 많아지니까 느려지는것은 어찌보면 당연한 일이다. 하지만 그대로 사용할수없으니 해..

qits.tistory.com

 

반응형
Posted by blueasa
, |

[링크] https://redforce01.tistory.com/242

 

[NGUI] Infinite ScrollView (AT)

최근 회사에서 채팅UI의 구조 개선에 대한 이슈가 발생하여 만들어두었던 채팅창을 모두 갈아엎게 되었다. 기존의 채팅 UI구조는 채팅메세지가 들어올 때마다 Instantiate ( ) 가 수행되어 말풍선 UI가 계속해서..

redforce01.tistory.com

 

반응형
Posted by blueasa
, |

[수정] 2021-06-10

Height 값 참조 오류 수정(참조 값 manualHeight -> activeHeight로 변경)

 

[스크립트 파일]

UISafeAreaOffsetController.cs
0.00MB

 

아래 위치와 같이 Anchor의 하위에 GameObject를 하나 만들고,

인스펙터와 같이 Top/Bottom에 따라 만들어진 GameObeject를 Drag&Drop 해서 Link 한다.

 

 

위와 같이 셋팅해 주면 Fan이 Top쪽 Safe Area가 있으면 그에 맞게 좀 더 내려온다

(Bottom은 같은 형태로 List Offset List_Bottom에 Link 해주면 된다.)

 

대충 만들어서 넣어놔서 정리좀 하고 싶지만 다음 기회로..

필요하신 분은 받아서 써보시고 개량해서 공유 좀 해주세요~

 

 

[참조] https://blueasa.tistory.com/2272

반응형
Posted by blueasa
, |

[링크]

https://carrotclub.tistory.com/entry/NGUI-%EC%82%AC%EC%9A%A9-%ED%9D%90%EB%A5%B4%EB%8A%94-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

NGUI 사용 흐르는 문자열 만들기

가. 흐르는 문자열 만들기 - 사용 조건 : NGUI가 있어야 함. 나. 코드 - NGUI UILabel.cs 파일내에 있는 overflow enum 값에 FlowText 라는 값을 추가해준다. 해당 옵션이 되어져 있을 경우 글자가 흐르게 할 예정..

carrotclub.tistory.com

 

반응형
Posted by blueasa
, |