language:unity:ngui:0-ngui-basic
차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판이전 판 | |||
language:unity:ngui:0-ngui-basic [2013/10/15 23:09] – [Tip, tip] kieuns | language:unity:ngui:0-ngui-basic [2024/04/23 22:45] (현재) – 바깥 편집 127.0.0.1 | ||
---|---|---|---|
줄 1: | 줄 1: | ||
+ | ====== 2D, 3D UI ====== | ||
+ | * 2D : 평면 형식의 뷰 | ||
+ | * 3D : 퍼스펙티브 형식의 뷰로 카메라와의 거리에 따라 크기에 영향을 받는다. | ||
+ | 2D와 3D ui는 혼용이 가능하다. | ||
+ | |||
+ | ===== 2D 와 3D UI의 보여지는 우선 순위 ===== | ||
+ | |||
+ | **UICamera**의 **Depth** 설정에 의해 먼저 보여질 것이 결정 된다. | ||
+ | |||
+ | * 3D 카메라의 **Depth** 가 **2**, 2D 카메라의 **Depth**가 **1** 면 3D카메라의 UI가 더 앞에 배치 된다. | ||
+ | * 반대의 경우가 필요하다면 Depth값을 바꿔서 어느쪽이 먼제 보이게 할지 결정 할 수 있다. | ||
+ | |||
+ | < | ||
+ | **Depth** 값이 큰 카메라쪽의 물체가 먼저 보이게 된다. | ||
+ | </ | ||
+ | ====== 윈도우 형식의 UI 만들기 ====== | ||
+ | |||
+ | 3D UI를 한개 만든다. 의례적으로, | ||
+ | |||
+ | * UI 3D >> Camera >> Ancher >> Panel 등등 생기는데 이것들은 2D 방식의 UI에서 더 활용 되는 것으로 Panel을 사용해서 크기를 맞추는 더라도 카메로와의 거리를 확인하면서 작업해야 한다. | ||
+ | |||
+ | 윈도우의 중심은 **Add New Child**로 빈 오브젝트를 만들고, UI 요소들을 자식으로 추가하면 관리하기 편하다. | ||
+ | |||
+ | * **Add New Child**로 중심 오브젝트를 설정한다. \\ {{: | ||
+ | * 빈오브젝트를 잘 활용해서 윈도우 계층구조를 만든다. \\ {{: | ||
+ | |||
+ | ====== NGUI에서 사용할 비트맵 폰트 만들기 ====== | ||
+ | |||
+ | * 비트맵 폰트 생성기 : [[http:// | ||
+ | * 1.13 version : {{: | ||
+ | |||
+ | **Bitmap font generator**로 비트맵 폰트를 만든다. | ||
+ | |||
+ | |< 70% 30% >| | ||
+ | | FontSetting | ||
+ | | ::: | Bit Depth 를 8로 맞추면 폰트 외곽 부분이 \\ 제대로 처리 되지 않아서 글자가 이상하게 나오게 된다. | | ||
+ | | ::: | {{: | ||
+ | | Export Options | ||
+ | | ::: | 텍스쳐 크기를 1024x1024로 변경했는데, | ||
+ | |||
+ | 폰트 파일을 저장합니다. ( Save bitmap font as ) | ||
+ | * {{: | ||
+ | * 미리 보기 화면으로 보면 하얗게 보이지만 글자가 흰색이고 배경이 투명해서 이렇게 나오지만, | ||
+ | * 이미지를 확대해서 보면 글자가 보인다. \\ {{: | ||
+ | * 확장자를 fnt 에서 txt로 변경. 유니티에서 fnt 파일을 인식하지 못해서 변경이 필요. | ||
+ | |||
+ | **Assets**으로 등록 | ||
+ | * 텍스쳐 파일 옵션을 바꾼다. 안바꿔도 되는지 확실해 모르겠네...\\ {{: | ||
+ | |||
+ | NGUI로 폰트 만들기 | ||
+ | * 먼저 폰트 메뉴 선택 \\ {{: | ||
+ | * 폰트 정보 선택 \\ {{: | ||
+ | |||
+ | ====== 중요 컴포넌트와 스크립트 ====== | ||
+ | |||
+ | ===== UICamera ===== | ||
+ | = Event Receiver Mask : UI 입력을 받을 레이어를 설정한다. | ||
+ | = : 이 레이어를 따로 하지 않으면, (기본은 Default) UI 요소를 선택했을때 화면에서도 UI 반응이 그대로 전달된다. | ||
+ | {{: | ||
+ | |||
+ | ====== UILabel ====== | ||
+ | |||
+ | %%[RrGgBb]< | ||
+ | |||
+ | | < | ||
+ | |||
+ | ====== Tip, tip ====== | ||
+ | |||
+ | ===== NGUI + iTweenPath ===== | ||
+ | |||
+ | 좀 희한한 현상, | ||
+ | |||
+ | * iTweenPath를 Scene 에서 추가할때, | ||
+ | * iTweenPath를 사용하는 오브젝트가 이 iTweenPath-begin 위치보다 더 z 축으로 뒤에 있으면 | ||
+ | * UITexture를 사용하는 오브젝트의 Z 축이 엉망이 되서, \\ 가장 위에 노출된다. 다른 오브젝트가 가려버린다. | ||
+ | |||
+ | 헐.. 왜 그럴까. 아무튼 Z 축을 조정하면 잘 나오니 문제 없지만. | ||
+ | |||
+ | 이게.. | ||
+ | * 원래 이렇게 잘 보여야 하는데 (숫자 999부분, 동전 부분은 UITexture) \\ {{: | ||
+ | * 이렇게 iTweenPath를 사용하는 오브젝트의 위치가 begin 앞쪽인데, | ||
+ | * begin 뒤쪽으로 이동하면 \\ {{: | ||
+ | * 숫자부분이 UITexture 뒤에 가려진다. \\ {{: | ||
+ | |||
+ | ====== NGUI : 플로팅 텍스트 ====== | ||
+ | * 오브젝트를 따라다니는 텍스트 | ||
+ | * 플로팅 score 를 구현하는데 쓰는 방법 | ||
+ | |||
+ | NGUI를 사용해서 요런 기능을 추가한다. | ||
+ | |||
+ | 동작 시나리오1 | ||
+ | - 화면을 임의 클릭 | ||
+ | - 해당 위치에 '+1 coin' 이라는 라벨이 나타난다. | ||
+ | - '+1 coin' | ||
+ | 동작 시나리오2 | ||
+ | - 화면상의 임의 오브젝트에 '+1 coin' | ||
+ | |||
+ | 유의사항 | ||
+ | - NGUI의 3D UI는, 화면상에 오브젝트가 너무 작게 나왔다. 아직은 잘 모르겠다. | ||
+ | |||
+ | ===== 준비 작업 ===== | ||
+ | |||
+ | - NGUI의 2D UI를 추가 | ||
+ | - "Panel (2D)" | ||
+ | - ' | ||
+ | - 빈 오브젝트, | ||
+ | - 화면 \\ {{: | ||
+ | - floating 에 대한 스크립트를 붙일 테스트 오브젝트 추가, ' | ||
+ | |||
+ | ===== 오브젝트 따라 다니는 라벨 ===== | ||
+ | |||
+ | 프로그래밍으로 동적 추가도 가능하고, | ||
+ | * [[http:// | ||
+ | |||
+ | 순서 | ||
+ | |||
+ | * 오브젝트에 붙일, NGUI Label을 하나 추가. (이름, FloatingTextLabel) | ||
+ | * FloatingText2D.cs 를 FloatingTextLabel 라벨이 추가한다. | ||
+ | * TargetObject에 따라다닐 오브젝트를 추가 ( 위에서 만든, ' | ||
+ | * WorldCamera 에 메인 카메라 추가 | ||
+ | * GUI Camera에 NGUI에 추가된 카메라 추가 | ||
+ | * Default Size에는 .. 그대로 유지. \\ 여기 값은 확대 배율이므로 숫자 1이면 그대로, \\ 1을 기준으로 줄이거나 늘린다. | ||
+ | |||
+ | 실행해보면 오브젝트를 따라다니는 라벨이 보인다. 결과 화면, | ||
+ | |||
+ | {{: | ||
+ | ===== 임의 위치에 나타나서, | ||
+ | |||
+ | * ' | ||
+ | * 이 스크립트는, | ||
+ | * 테스트용 오브젝트를 만들어서 스크립트를 가져다 붙여도 동작하므로 테스트 가능. | ||
+ | |||
+ | 코드로 FloatingTextUp2D 생성할 때는, | ||
+ | * 임의 빈 오브젝트 추가 ( 이름은 스크립트와 같은 걸로 만들었다. ) | ||
+ | * 이 오브젝트에 아래 스크립트를 붙여서, 다른 곳에서 사용할 수 있게 준비해 둔다. | ||
+ | * fire() 함수를 부르면 스크립트가 clickedPos_ 위치부터 위로 움직인다. | ||
+ | |||
+ | ++++ NotifyHandler.cs | | ||
+ | <code csharp> | ||
+ | using UnityEngine; | ||
+ | using System.Collections; | ||
+ | public class NotifyHandler : MonoBehaviour { | ||
+ | public Camera mainCamera; | ||
+ | public Camera guiCamera; | ||
+ | public GameObject prefab; | ||
+ | public void fire( Vector3 clickedPos_ ) | ||
+ | { | ||
+ | GameObject _gameObj = Instantiate( prefab, clickedPos_, | ||
+ | // No mean yet, just align as child | ||
+ | SomeTools.AppendChildAndReset( gameObject, _gameObj ); | ||
+ | // run floating script | ||
+ | FloatingTextUp2D _floatTxtUp = _gameObj.GetComponent< | ||
+ | _floatTxtUp.initAndStartMoving( clickedPos_, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | NotifyHandler 에 임의 메시지 보내기. | ||
+ | * 화면을 아무곳이나 클릭하면, | ||
+ | * NotifyHandler.fire()를 호출한다. | ||
+ | |||
+ | ++++ UIInputReactor | | ||
+ | <code csharp> | ||
+ | using UnityEngine; | ||
+ | using System.Collections; | ||
+ | public class UIInputReactor : MonoBehaviour { | ||
+ | void Update() | ||
+ | { | ||
+ | if( Input.GetButtonDown(" | ||
+ | // 화면을 임의 클릭해서, | ||
+ | Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); | ||
+ | RaycastHit hit; | ||
+ | if( Physics.Raycast(ray, | ||
+ | // NotifyHandler 오브젝트에 메시지 발송 (fire 실행) | ||
+ | GameObject _obj = GameObject.Find(" | ||
+ | _obj.SendMessage( " | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | 결과화면, | ||
+ | |||
+ | {{: | ||
+ | |||
+ | ===== 사용한 프로젝트 화면 ===== | ||
+ | |||
+ | {{: | ||
+ | ===== 사용한 스크립트 ===== | ||
+ | |||
+ | 오브젝트를 따라다니는 라벨 | ||
+ | |||
+ | ++++ FloatingText2D.cs | | ||
+ | <file csharp FloatingText2D.cs> | ||
+ | using UnityEngine; | ||
+ | using System.Collections; | ||
+ | |||
+ | public class FloatingText2D : MonoBehaviour | ||
+ | { | ||
+ | private UILabel | ||
+ | private Vector3 __pos; | ||
+ | private Transform __t; | ||
+ | |||
+ | |||
+ | public bool followTarget = true; | ||
+ | public Vector3 defaultSize = new Vector3(1, | ||
+ | |||
+ | public GameObject targetObject; | ||
+ | public Camera worldCamera; | ||
+ | public Camera guiCamera; | ||
+ | public TweenPosition tweenPos; | ||
+ | |||
+ | |||
+ | public void init( string text_, GameObject gameObj_ ) | ||
+ | { | ||
+ | this.text = text_; | ||
+ | this.target = gameObj_; | ||
+ | } | ||
+ | |||
+ | public void init( string text_, Color clr_, GameObject gameObj_ ) | ||
+ | { | ||
+ | this.color = clr_; | ||
+ | this.text = text_; | ||
+ | this.target = gameObj_; | ||
+ | } | ||
+ | |||
+ | public void spawnAt( GameObject targetObj_, Vector3 size_, Transform parent_ ) | ||
+ | { | ||
+ | target = targetObj_; | ||
+ | __t.parent = parent_; | ||
+ | defaultSize = size_; | ||
+ | } | ||
+ | |||
+ | public void followingObject() | ||
+ | { | ||
+ | __pos = worldCamera.WorldToViewportPoint( targetObject.transform.position ); | ||
+ | __pos = guiCamera.ViewportToWorldPoint( __pos ); | ||
+ | |||
+ | __pos.z = 0f; | ||
+ | transform.position = __pos; | ||
+ | } | ||
+ | |||
+ | // Use this for initialization | ||
+ | void Awake() | ||
+ | { | ||
+ | __t = transform; | ||
+ | __label = GetComponent< | ||
+ | } | ||
+ | |||
+ | void Start() | ||
+ | { | ||
+ | if( guiCamera == null ) | ||
+ | guiCamera = NGUITools.FindCameraForLayer( gameObject.layer ); | ||
+ | |||
+ | __label.transform.localScale = new Vector3( __t.transform.localScale.x * defaultSize.x, | ||
+ | } | ||
+ | |||
+ | void LateUpdate() | ||
+ | { | ||
+ | if( followTarget ) followingObject(); | ||
+ | } | ||
+ | |||
+ | // property | ||
+ | // | ||
+ | public string text | ||
+ | { | ||
+ | get { return __label.text; | ||
+ | set { __label.text = value; } | ||
+ | } | ||
+ | |||
+ | public Color color | ||
+ | { | ||
+ | get { return __label.color; | ||
+ | set { __label.color = value; } | ||
+ | } | ||
+ | |||
+ | public Vector3 size | ||
+ | { | ||
+ | get { return __label.transform.localScale; | ||
+ | set { __label.transform.localScale = value; } | ||
+ | } | ||
+ | |||
+ | public TweenPosition tweenPosition | ||
+ | { | ||
+ | get { | ||
+ | TweenPosition _tp = GetComponent< | ||
+ | if( _tp == null ) _tp = targetObject.AddComponent< | ||
+ | return _tp; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public GameObject target | ||
+ | { | ||
+ | get { return targetObject; | ||
+ | set { | ||
+ | targetObject = value; | ||
+ | worldCamera = NGUITools.FindCameraForLayer( targetObject.layer ); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | 특정 위치에서 나타나서 위로 이동하는 라벨. 아래 부분에 업데이트 된 코드 있다. | ||
+ | |||
+ | ++++ FloatingTextUp2D.cs | | ||
+ | <file csharp FloatingTextUp2D.cs> | ||
+ | using UnityEngine; | ||
+ | using System.Collections; | ||
+ | |||
+ | public class FloatingTextUp2D : MonoBehaviour { | ||
+ | private UILabel __label; | ||
+ | private Vector3 __pos; | ||
+ | private Vector3 __initPos; | ||
+ | | ||
+ | public Camera guiCamera = null; | ||
+ | public Camera worldCamera = null; | ||
+ | | ||
+ | public GameObject targetObject = null; | ||
+ | public int tweenTime = 2; | ||
+ | public int tweenDistance = 50; | ||
+ | |||
+ | // class spec function | ||
+ | // | ||
+ | public void destroySelf() { | ||
+ | Destroy( gameObject ); | ||
+ | } | ||
+ | |||
+ | public void initAndStartMoving( Vector3 initPos_, Camera mainCam_ = null, Camera guiCam_ = null ) | ||
+ | { | ||
+ | if( mainCam_ != null ) worldCamera = mainCam_; | ||
+ | if( guiCam_ != null ) guiCamera = guiCam_; | ||
+ | startMoveUp( initPos_, 2, 50 ); | ||
+ | } | ||
+ | |||
+ | public void startMoveUp( Vector3 initPos_, int tweenDuration_, | ||
+ | { | ||
+ | __initPos = initPos_; | ||
+ | calculatePosition( initPos_ ); | ||
+ | |||
+ | TweenPosition _tp = this.tweenPosition; | ||
+ | _tp.duration = tweenDuration_; | ||
+ | _tp.from = transform.localPosition; | ||
+ | _tp.to = _tp.from + Vector3.up * tweenEnd_; | ||
+ | _tp.eventReceiver = gameObject; | ||
+ | _tp.callWhenFinished = " | ||
+ | } | ||
+ | |||
+ | public void calculatePosition( Vector3 pos_ ) | ||
+ | { | ||
+ | __pos = worldCamera.WorldToViewportPoint( pos_ ); | ||
+ | __pos = guiCamera.ViewportToWorldPoint( __pos ); | ||
+ | __pos.z = 0f; | ||
+ | transform.position = __pos; | ||
+ | } | ||
+ | |||
+ | // Unity3d reaction function | ||
+ | // | ||
+ | public void Awake() { | ||
+ | __label = GetComponent< | ||
+ | } | ||
+ | |||
+ | void Start() | ||
+ | { | ||
+ | if( guiCamera == null ) guiCamera = NGUITools.FindCameraForLayer( gameObject.layer ); | ||
+ | if( worldCamera == null ) worldCamera = Camera.mainCamera; | ||
+ | __label.MakePixelPerfect(); | ||
+ | if( targetObject != null ) { | ||
+ | startMoveUp( targetObject.transform.position, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Property helper | ||
+ | // | ||
+ | public TweenPosition tweenPosition { | ||
+ | get { | ||
+ | TweenPosition _tp = GetComponent< | ||
+ | if( _tp == null ) _tp = gameObject.AddComponent< | ||
+ | return _tp; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | ====== FloatingTextUp2D ====== | ||
+ | |||
+ | UILabel을 화면 어딘가( 프로그램 지정 )에서 위쪽으로 흘려 보내는 스크립트. | ||
+ | |||
+ | ===== 기본 사용법 ===== | ||
+ | |||
+ | - 빈 오브젝트를 만든다. or UILabel을 추가한다. >> 오브젝트를 objFTUp 이라고 부르기로 하고. | ||
+ | - objFTUp 에 FloatingTextUp2D 를 추가한다. | ||
+ | - objFTUp을 prefab 으로 만들어서, | ||
+ | |||
+ | 추가 수정 사항 | ||
+ | - [[language: | ||
+ | |||
+ | 수정해야할 것 | ||
+ | * UILabel을 상속 받아서 새로운 클래스로 다시 정리. | ||
+ | * UILabel와 TweenPosition 클래스에 종속되어 있기 때문에, 따로 사용은 불가능. | ||
+ | |||
+ | UILabel 크기 조정 | ||
+ | * scaleByScreen : 현재 화면 크기 대비 몇 %의 크기로 표시할 것인지 설정. 0 ~ 1 사이의 값으로 설정. \\ 0 : 원래크기, | ||
+ | |||
+ | ===== UILabel 로부터 가져와서 사용한 부분 ===== | ||
+ | |||
+ | ==== Vector2 getUILabelSize() ==== | ||
+ | |||
+ | 폰트 픽셀 크기를 얻어와서, | ||
+ | |||
+ | <code csharp> | ||
+ | // 지정폰트 픽셀크기를 구해서(보통 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:: | ||
+ | |||
+ | <code csharp> | ||
+ | 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 | | ||
+ | <file csharp FloatingTextUp2D.cs> | ||
+ | using UnityEngine; | ||
+ | using System.Collections; | ||
+ | |||
+ | [RequireComponent( typeof( TweenPosition ) )] | ||
+ | public class FloatingTextUp2D : MonoBehaviour | ||
+ | { | ||
+ | public enum Side | ||
+ | { | ||
+ | Left, | ||
+ | Right, | ||
+ | Center, | ||
+ | NoOutOfScreen, | ||
+ | NoTouch | ||
+ | } | ||
+ | |||
+ | private UILabel mLabel; | ||
+ | private Vector3 mObjPos; | ||
+ | |||
+ | public Camera guiCamera = null; | ||
+ | public Camera worldCamera = null; | ||
+ | public GameObject targetObject = null; | ||
+ | public float tweenDuration = 2.5f; | ||
+ | public float tweenDistance = 350f; | ||
+ | public Side startSide = Side.NoOutOfScreen; | ||
+ | /// < | ||
+ | /// move up by Percent from -1 ~ 1. 0 is middle of scrren. If this is false, tweenDistance used to end of tween moving. | ||
+ | /// </ | ||
+ | public bool moveUpByPercent = false; | ||
+ | /// < | ||
+ | /// how much move up? this value from -1 to 1. 0 is middle of screen. | ||
+ | /// </ | ||
+ | [Range(-1, 1)] | ||
+ | public float moveUpPercent = 0f; | ||
+ | /// < | ||
+ | /// Auto Scale by screen width. if zero, use original size. if 1, full width. | ||
+ | /// </ | ||
+ | [Range( 0, 1 )] | ||
+ | public float scaleByScreen = 0f; | ||
+ | /// < | ||
+ | /// If scaleByScreen not setted. use this. | ||
+ | /// </ | ||
+ | //public Vector2 defaultSize = new Vector2( 1, 1 ); | ||
+ | |||
+ | public void destroySelf() | ||
+ | { | ||
+ | Destroy( gameObject ); | ||
+ | } | ||
+ | |||
+ | // get UILabel width, height roughly. code from UILabel.MakePixelPerfect() | ||
+ | public Vector2 getUILabelSize() | ||
+ | { | ||
+ | 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 = mLabel.font.size * pixelSize; | ||
+ | scale.y = scale.x; | ||
+ | scale.z = 1f; | ||
+ | |||
+ | return (mLabel.relativeSize * scale.x); | ||
+ | } | ||
+ | |||
+ | public Vector3 fixPosition( Vector3 value_ ) | ||
+ | { | ||
+ | Rect rect = new Rect(); | ||
+ | rect = guiCamera.pixelRect; | ||
+ | |||
+ | if( startSide != Side.NoTouch ) | ||
+ | { | ||
+ | Vector3 _tmpPos = guiCamera.WorldToScreenPoint( value_ ); | ||
+ | Vector2 _labelSize = getUILabelSize(); | ||
+ | float _middleX = Mathf.Abs( _labelSize.x * mLabel.pivotOffset.x ); | ||
+ | |||
+ | if( startSide == Side.Center ) | ||
+ | { | ||
+ | _tmpPos.x = (rect.xMin + rect.xMax) * 0.5f; | ||
+ | } | ||
+ | else if( startSide == Side.Left ) | ||
+ | { | ||
+ | _tmpPos.x = (rect.xMin + _middleX); | ||
+ | } | ||
+ | else if( startSide == Side.Right ) | ||
+ | { | ||
+ | _tmpPos.x = (rect.xMax - _middleX); | ||
+ | } | ||
+ | else if( startSide == Side.NoOutOfScreen ) | ||
+ | { | ||
+ | if( (_tmpPos.x - _middleX) < rect.xMin ) _tmpPos.x = rect.xMin + _middleX; | ||
+ | if( (_tmpPos.x + _middleX) > rect.xMax ) _tmpPos.x = rect.xMax - _middleX; | ||
+ | } | ||
+ | |||
+ | value_ = guiCamera.ScreenToWorldPoint( _tmpPos ); | ||
+ | } | ||
+ | return value_; | ||
+ | } | ||
+ | |||
+ | public void adjustPosition( Vector3 pos_ ) | ||
+ | { | ||
+ | mObjPos = worldCamera.WorldToViewportPoint( pos_ ); | ||
+ | mObjPos = guiCamera.ViewportToWorldPoint( mObjPos ); | ||
+ | |||
+ | mObjPos = fixPosition( mObjPos ); | ||
+ | |||
+ | mObjPos.z = 0f; | ||
+ | transform.position = mObjPos; | ||
+ | } | ||
+ | |||
+ | 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 = ((guiCamera.pixelWidth / mLabel.relativeSize.x) * scaleByScreen); | ||
+ | scale.y = scale.x; | ||
+ | scale.z = 1f; | ||
+ | |||
+ | Vector2 actualSize = mLabel.relativeSize * scale.x; | ||
+ | |||
+ | int x = Mathf.RoundToInt( actualSize.x / pixelSize ); | ||
+ | int y = Mathf.RoundToInt( actualSize.y / pixelSize ); | ||
+ | |||
+ | Vector3 pos = mLabel.cachedTransform.localPosition; | ||
+ | pos.x = Mathf.FloorToInt( pos.x / pixelSize ); | ||
+ | pos.y = Mathf.CeilToInt( pos.y / pixelSize ); | ||
+ | pos.z = Mathf.RoundToInt( pos.z ); | ||
+ | |||
+ | if( mLabel.cachedTransform.localRotation == Quaternion.identity ) | ||
+ | { | ||
+ | if( (x % 2 == 1) && (mLabel.pivot == UILabel.Pivot.Top || mLabel.pivot == UILabel.Pivot.Center || mLabel.pivot == UILabel.Pivot.Bottom) ) pos.x += 0.5f; | ||
+ | if( (y % 2 == 1) && (mLabel.pivot == UILabel.Pivot.Left || mLabel.pivot == UILabel.Pivot.Center || mLabel.pivot == UILabel.Pivot.Right) ) pos.y -= 0.5f; | ||
+ | } | ||
+ | |||
+ | pos.x *= pixelSize; | ||
+ | pos.y *= pixelSize; | ||
+ | |||
+ | mLabel.cachedTransform.localPosition = pos; | ||
+ | mLabel.cachedTransform.localScale = scale; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public void startMoveUp( Vector3 initPos_, float tweenDuration_, | ||
+ | { | ||
+ | adjustScale(); | ||
+ | adjustPosition( initPos_ ); | ||
+ | |||
+ | TweenPosition _tp = this.tweenPosition; | ||
+ | _tp.eventReceiver = gameObject; | ||
+ | _tp.callWhenFinished = " | ||
+ | _tp.from = transform.localPosition; | ||
+ | |||
+ | if( moveUpByPercent ) | ||
+ | { | ||
+ | _tp.to = Vector3.up * (Screen.height * 0.5f) * moveUpPercent; | ||
+ | _tp.to.x = _tp.from.x; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | _tp.to = _tp.from + Vector3.up * tweenEnd_; | ||
+ | } | ||
+ | |||
+ | if( tweenDuration_ != 0 ) | ||
+ | { | ||
+ | _tp.duration = tweenDuration_; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public void initAndStartMoving( Vector3 initPos_, Camera mainCam_ = null, Camera guiCam_ = null ) | ||
+ | { | ||
+ | if( mainCam_ != null ) worldCamera = mainCam_; | ||
+ | if( guiCam_ != null ) guiCamera = guiCam_; | ||
+ | |||
+ | startMoveUp( initPos_, tweenDuration, | ||
+ | } | ||
+ | |||
+ | // Unity3d reaction function | ||
+ | |||
+ | public void Awake() | ||
+ | { | ||
+ | mLabel = GetComponent< | ||
+ | |||
+ | } | ||
+ | |||
+ | void Start() | ||
+ | { | ||
+ | if( guiCamera == null ) { | ||
+ | guiCamera = NGUITools.FindCameraForLayer( gameObject.layer ); | ||
+ | } | ||
+ | if( worldCamera == null ) { | ||
+ | worldCamera = Camera.mainCamera; | ||
+ | } | ||
+ | |||
+ | if( targetObject != null ) { | ||
+ | startMoveUp( targetObject.transform.position, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | public TweenPosition tweenPosition | ||
+ | { | ||
+ | get { | ||
+ | TweenPosition _tp = GetComponent< | ||
+ | if( _tp == null ) _tp = gameObject.AddComponent< | ||
+ | return _tp; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ++++ | ||
+ | |||
+ | ====== TweenAlapha ====== | ||
+ | |||
+ | ===== 케이스 1 ===== | ||
+ | |||
+ | GameObject에 TweenAlpha를 컴포넌트로 추가한 다음, 필요할때마다 사용하고 싶을때 | ||
+ | |||
+ | * TweenAlpha 컴포넌트를 얻는다. | ||
+ | * from과 to 값을 설정한다. | ||
+ | * enabled 에 true를 입력하는 시점에서 TweenAlpha가 시작된다. | ||
+ | <code csharp> | ||
+ | // debugMenu가 show_ 플래그에 따라 화면에 보이거나 사라지거나 하는 동작이 있을때, | ||
+ | // true 면 alpha 값이 0 에서 1로 (점점 보여지도록), | ||
+ | // 애니메이션 시작되면서 알파 값이 적용 되도록한다. | ||
+ | // 느릴려나..? | ||
+ | public void debugMenuOn( bool show_ ) | ||
+ | { | ||
+ | AnimationState _animState = debugWindow.animation[" | ||
+ | TweenAlpha _tweenAlpha = debugWindow.GetComponent< | ||
+ | _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( " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 케이스2 ===== | ||
+ | |||
+ | GameObject에 TweenAlpha를 컴포넌트로 추가한 다음, 필요할때마다 사용하고 싶을때 2 | ||
+ | |||
+ | 다른 케이스. \\ 스크립트 내에서 컴포넌트로 추가된 TweenAlpha를 불러와서 코드로 시작하게 하는 | ||
+ | |||
+ | <code csharp> | ||
+ | float _from = 1f; | ||
+ | float _to = 0f; | ||
+ | float _duration = 0.2f; | ||
+ | |||
+ | TweenAlpha _ta = mBackground.GetComponent< | ||
+ | _ta.Reset(); | ||
+ | _ta.eventReceiver = gameObject; // Tween이 종료되면, | ||
+ | _ta.callWhenFinished = " | ||
+ | _ta.from = _from; | ||
+ | _ta.to = _to; | ||
+ | _ta.duration = _duration * 2f ; | ||
+ | _ta.Play( true ); // play! 파라미터가 false면 반대로 플레이 된다고 하는데 확인 하진 않음. | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Quick 으로 빨리 쓰고 싶을때 ===== | ||
+ | 컴포넌트로 추가되어 있지 않아도 자동 추가하며, | ||
+ | <code csharp> | ||
+ | //- TweenAlpha : quick example | ||
+ | TweenAlpha _ta = mBackground.GetComponent< | ||
+ | _ta.duration = 0.5f; | ||
+ | _ta.from = 1; | ||
+ | _ta.to = 0; | ||
+ | </ |