사용자 도구

사이트 도구


사이드바

카테고리

language:unity:ngui:0-ngui-basic

2D, 3D UI

  • 2D : 평면 형식의 뷰
  • 3D : 퍼스펙티브 형식의 뷰로 카메라와의 거리에 따라 크기에 영향을 받는다.

2D와 3D ui는 혼용이 가능하다.

2D 와 3D UI의 보여지는 우선 순위

UICameraDepth 설정에 의해 먼저 보여질 것이 결정 된다.

  • 3D 카메라의 Depth2, 2D 카메라의 Depth1 면 3D카메라의 UI가 더 앞에 배치 된다.
  • 반대의 경우가 필요하다면 Depth값을 바꿔서 어느쪽이 먼제 보이게 할지 결정 할 수 있다.
Depth 값이 큰 카메라쪽의 물체가 먼저 보이게 된다.

윈도우 형식의 UI 만들기

3D UI를 한개 만든다. 의례적으로,

  • UI 3D » Camera » Ancher » Panel 등등 생기는데 이것들은 2D 방식의 UI에서 더 활용 되는 것으로 Panel을 사용해서 크기를 맞추는 더라도 카메로와의 거리를 확인하면서 작업해야 한다.

윈도우의 중심은 Add New Child로 빈 오브젝트를 만들고, UI 요소들을 자식으로 추가하면 관리하기 편하다.

  • Add New Child로 중심 오브젝트를 설정한다.
  • 빈오브젝트를 잘 활용해서 윈도우 계층구조를 만든다.
    ngui-hierarchy.jpg

NGUI에서 사용할 비트맵 폰트 만들기

Bitmap font generator로 비트맵 폰트를 만든다.

FontSetting
Bit Depth 를 8로 맞추면 폰트 외곽 부분이
제대로 처리 되지 않아서 글자가 이상하게 나오게 된다.

이렇게 그리다 만듯한…
Export Options
텍스쳐 크기를 1024×1024로 변경했는데, NGUI폰트 생성기가 한장만 인식하는 것 같아서 하나만으로 생성. 256×256이면 글자가 이상해지지 않을까?

폰트 파일을 저장합니다. ( Save bitmap font as )

  • 미리 보기 화면으로 보면 하얗게 보이지만 글자가 흰색이고 배경이 투명해서 이렇게 나오지만, 그리고 이렇게 보여야 정상.
  • 이미지를 확대해서 보면 글자가 보인다.
  • 확장자를 fnt 에서 txt로 변경. 유니티에서 fnt 파일을 인식하지 못해서 변경이 필요.

Assets으로 등록

  • 텍스쳐 파일 옵션을 바꾼다. 안바꿔도 되는지 확실해 모르겠네…

NGUI로 폰트 만들기

  • 먼저 폰트 메뉴 선택
  • 폰트 정보 선택

중요 컴포넌트와 스크립트

UICamera

= Event Receiver Mask : UI 입력을 받을 레이어를 설정한다. 
= : 이 레이어를 따로 하지 않으면, (기본은 Default) UI 요소를 선택했을때 화면에서도 UI 반응이 그대로 전달된다. 

UILabel

[RrGgBb]<텍스트>[-] 형식으로 UILabel의 텍스트에 색상을 줄 수 있다.

[ff0000]붉은 글씨[-]를
붉은 글씨

Tip, tip

NGUI + iTweenPath

좀 희한한 현상,

  • iTweenPath를 Scene 에서 추가할때,
  • iTweenPath를 사용하는 오브젝트가 이 iTweenPath-begin 위치보다 더 z 축으로 뒤에 있으면
  • UITexture를 사용하는 오브젝트의 Z 축이 엉망이 되서,
    가장 위에 노출된다. 다른 오브젝트가 가려버린다.

헐.. 왜 그럴까. 아무튼 Z 축을 조정하면 잘 나오니 문제 없지만.

이게..

  • 원래 이렇게 잘 보여야 하는데 (숫자 999부분, 동전 부분은 UITexture)
  • 이렇게 iTweenPath를 사용하는 오브젝트의 위치가 begin 앞쪽인데,
  • begin 뒤쪽으로 이동하면
  • 숫자부분이 UITexture 뒤에 가려진다.

NGUI : 플로팅 텍스트

  • 오브젝트를 따라다니는 텍스트
  • 플로팅 score 를 구현하는데 쓰는 방법

NGUI를 사용해서 요런 기능을 추가한다.

동작 시나리오1

  1. 화면을 임의 클릭
  2. 해당 위치에 '+1 coin' 이라는 라벨이 나타난다.
  3. '+1 coin'은 위로 움직이면서 적당한 시간이 되면 사라진다.

동작 시나리오2

  1. 화면상의 임의 오브젝트에 '+1 coin'라는 라벨이 오브젝트 살짝 위쪽으로 따라다닌다.

유의사항

  1. NGUI의 3D UI는, 화면상에 오브젝트가 너무 작게 나왔다. 아직은 잘 모르겠다.

준비 작업

  1. NGUI의 2D UI를 추가
  2. “Panel (2D)“에, 'Panel'인데 이름을 바꿨다,
    1. 'CoinAddedLabel' 라벨 추가
    2. 빈 오브젝트, 'NotifyHandler' 추가 « 나중에 스크립트 추가를 위한 오브젝트로 사용한다.
    3. 화면
  3. floating 에 대한 스크립트를 붙일 테스트 오브젝트 추가, 'objTest'

오브젝트 따라 다니는 라벨

프로그래밍으로 동적 추가도 가능하고, Hierarchy에 NGUI Label을 추가해서 사용할 수도 있다.

순서

  • 오브젝트에 붙일, NGUI Label을 하나 추가. (이름, FloatingTextLabel)
  • FloatingText2D.cs 를 FloatingTextLabel 라벨이 추가한다.
  • TargetObject에 따라다닐 오브젝트를 추가 ( 위에서 만든, 'objTest'를 추가 )
  • WorldCamera 에 메인 카메라 추가
  • GUI Camera에 NGUI에 추가된 카메라 추가
  • Default Size에는 .. 그대로 유지.
    여기 값은 확대 배율이므로 숫자 1이면 그대로,
    1을 기준으로 줄이거나 늘린다.

실행해보면 오브젝트를 따라다니는 라벨이 보인다. 결과 화면,

임의 위치에 나타나서, 위로 움직이는 라벨

  • 'FloatingTextUp2D.cs'를 붙인 라벨을 만들고, prefab로 만든다.
  • 이 스크립트는, 움직이다가 게임 오브젝트를 삭제하므로 코드상에서 생성해야 한다.
  • 테스트용 오브젝트를 만들어서 스크립트를 가져다 붙여도 동작하므로 테스트 가능.

코드로 FloatingTextUp2D 생성할 때는,

  • 임의 빈 오브젝트 추가 ( 이름은 스크립트와 같은 걸로 만들었다. )
  • 이 오브젝트에 아래 스크립트를 붙여서, 다른 곳에서 사용할 수 있게 준비해 둔다.
  • fire() 함수를 부르면 스크립트가 clickedPos_ 위치부터 위로 움직인다.

NotifyHandler.cs

NotifyHandler 에 임의 메시지 보내기.

  • 화면을 아무곳이나 클릭하면, 해당 위치를 저장해서
  • NotifyHandler.fire()를 호출한다.

UIInputReactor

결과화면,

사용한 프로젝트 화면

사용한 스크립트

오브젝트를 따라다니는 라벨

FloatingText2D.cs

특정 위치에서 나타나서 위로 이동하는 라벨. 아래 부분에 업데이트 된 코드 있다.

FloatingTextUp2D.cs

FloatingTextUp2D

UILabel을 화면 어딘가( 프로그램 지정 )에서 위쪽으로 흘려 보내는 스크립트.

기본 사용법

  1. 빈 오브젝트를 만든다. or UILabel을 추가한다. » 오브젝트를 objFTUp 이라고 부르기로 하고.
  2. objFTUp 에 FloatingTextUp2D 를 추가한다.
  3. objFTUp을 prefab 으로 만들어서, 프로그램에서 사용한다. or 화면에 추가해서 사용한다.

추가 수정 사항

  1. ngui플로팅-텍스트 에 비해서 추가된 것.

수정해야할 것

  • UILabel을 상속 받아서 새로운 클래스로 다시 정리.
  • UILabel와 TweenPosition 클래스에 종속되어 있기 때문에, 따로 사용은 불가능.

UILabel 크기 조정

  • scaleByScreen : 현재 화면 크기 대비 몇 %의 크기로 표시할 것인지 설정. 0 ~ 1 사이의 값으로 설정.
    0 : 원래크기, 1 : 화면 너비만큼 확대.

UILabel 로부터 가져와서 사용한 부분

Vector2 getUILabelSize()

폰트 픽셀 크기를 얻어와서, UILabel의 전체 크기를 구하는 함수. 출력 위치를 화면 안쪽으로 옮길때 사용하므로, 크기 조정된 rect를 리턴할 수 있도록 수정

// 지정폰트 픽셀크기를 구해서(보통 1)
float pixelSize = (mLabel.font.atlas != null) ? mLabel.font.atlas.pixelSize : 1f;
// 스케일 비율에 맞춰 너비를 계산
Vector3 scale = mLabel.cachedTransform.localScale;
// 자동 스케일 기능이 켜져 있으면,
if( scaleByScreen != 0f )
  // (화면크기 / 글자수) * (확대축소비율) = 실제로 출력 되어야 할 너비
  scale.x = ((guiCamera.pixelWidth / mLabel.relativeSize.x) * scaleByScreen);
else
  // 그게 아니면 원래 사용하던 방식으로 계산. (예상, 폰트크기가 그대로 scale.x에 반영)
  scale.x = mLabel.font.size * pixelSize;
scale.y = scale.x;
scale.z = 1f;
return (mLabel.relativeSize * scale.x); // 글자수 * 글자당스케일

void adjustScale()

UILabel::MakePixelPerfact()함수를 가져와서, 스케일 조정하는 부분의 코드에서 scaleByScreen 에 희망 확대 비율이 적혀 있으면 그 크기만큼 조정한다.

public void adjustScale() {
// 화면 확대 설정이 없으면, 원래 크기대로 설정한다.
if( scaleByScreen == 0f ) {
  mLabel.MakePixelPerfect();
  return;
}
else if( mLabel.font != null ) {
  float pixelSize = (mLabel.font.atlas != null) ? mLabel.font.atlas.pixelSize : 1f;
  Vector3 scale = mLabel.cachedTransform.localScale;
  //scale.x = mLabel.font.size * pixelSize; // 원래코드
  // 화면 확대 비율만큼 너비를 계산한다.
  scale.x = ((guiCamera.pixelWidth / mLabel.relativeSize.x) * scaleByScreen);
  //
  //... 나머지 부분은 UILabel.MakePixelPerfact()와 같다.
}
}

그외 변경사항

  • void startMoveUp(…) : 위치 결정하기 전에( adjustPosition() 호출 전에 ) adjustScale() 로 크기를 먼저 조정한다.

UILabel에서 중요한 역할을 한 변수들

  • cachedTransform :
    • 처음 시작시의 자신의 크기를 저장해 놓고, 이후 크기 조정시에 계속 참조한다.
    • prefab으로 사용할때는 크기가 자동 조정되지 않아서, MakePixelPerfact()를 한번 호출해서 크기를 조정해줘야 했다.
  • cachedTransform.localScale : 이 값을 조정하면 크기가 변경 되지만, 기준 값이 모호해서 바로는 값 대입하면 원하는대로 잘 안된다.

FloatingTextUp2D.cs

TweenAlapha

케이스 1

GameObject에 TweenAlpha를 컴포넌트로 추가한 다음, 필요할때마다 사용하고 싶을때

  • TweenAlpha 컴포넌트를 얻는다.
  • from과 to 값을 설정한다.
  • enabled 에 true를 입력하는 시점에서 TweenAlpha가 시작된다.
// debugMenu가 show_ 플래그에 따라 화면에 보이거나 사라지거나 하는 동작이 있을때,
// true 면 alpha 값이 0 에서 1로 (점점 보여지도록), false면 그 반대로
// 애니메이션 시작되면서 알파 값이 적용 되도록한다.
// 느릴려나..?
public void debugMenuOn( bool show_ )
{
  AnimationState _animState = debugWindow.animation["menuMoveInside"];
  TweenAlpha _tweenAlpha = debugWindow.GetComponent<TweenAlpha>();
  _tweenAlpha.Reset();
  if( show_ )
  {
    _animState.speed = 1;
    _tweenAlpha.from = 0;
    _tweenAlpha.to = 1;
  }
  else
  {
    _animState.speed = -1;
    _animState.time = _animState.length;
    _tweenAlpha.from = 1;
    _tweenAlpha.to = 0;
  }
  _tweenAlpha.enabled = true;
  debugWindow.animation.Play( "menuMoveInside" );
}

케이스2

GameObject에 TweenAlpha를 컴포넌트로 추가한 다음, 필요할때마다 사용하고 싶을때 2

다른 케이스.
스크립트 내에서 컴포넌트로 추가된 TweenAlpha를 불러와서 코드로 시작하게 하는

float _from = 1f;
float _to = 0f;
float _duration = 0.2f;
 
TweenAlpha _ta = mBackground.GetComponent<TweenAlpha>();
_ta.Reset();
_ta.eventReceiver = gameObject; // Tween이 종료되면, destroySelf() 를 불러, 오브젝트를 삭제한다.
_ta.callWhenFinished = "destroySelf"; 
_ta.from = _from;
_ta.to = _to;
_ta.duration = _duration * 2f ;
_ta.Play( true ); // play! 파라미터가 false면 반대로 플레이 된다고 하는데 확인 하진 않음.

Quick 으로 빨리 쓰고 싶을때

컴포넌트로 추가되어 있지 않아도 자동 추가하며, UIWidget을 계열 오브젝트면 바로 적용 된다.

//- TweenAlpha : quick example
TweenAlpha _ta = mBackground.GetComponent<TweenAlpha>();
_ta.duration = 0.5f;
_ta.from = 1;
_ta.to = 0;
language/unity/ngui/0-ngui-basic.txt · 마지막으로 수정됨: 2022/12/07 22:30 저자 kieuns