유니티에서 NGUI 플러그인으로 커버플로우 UI 만들기.
Unity3D/NGUI / 2013. 1. 21. 12:07
요즘 제작중인 RPG 게임 GUI 에서 영웅 생성을 위해 캐릭터를 선택하는 UI 를 커버플로우(Cover Flow)로 구성하게 되어 NGUI 를 조금 응용해서 심플하게 구성해봤습니다. 아래 동영상과 유니티 데모를 보시면 대략 어떤 것인지 아실 수 있을 것이며 혹시나 구현 방법에 대해 관심 있는 분들은 첨부 파일을 받아서 패키지 임포트로 유니티에서 가져가 내용을 살펴 보시면 되겠습니다. NGUI 외에도 트위닝 모션을 위해 HOTween 플러그인을 사용하는 코드가 있으나 수정해서 쓰셔도 되겠습니다. 그리고 데모에 보이는 캐릭터 디자인 소스는 에셋 스토어에서 구입한 것이네요. NGUI 플러그인에 이런 기능도 포함되면 좋을 것 같은데 안된다면 아쉽지만 저처럼 이렇게 구현해야 되겠지요.^^ 여러분은 지금 어떤 기능들을 추가해보고 있나요?
[유니티 데모 링크] http://www.hompydesign.com/tmp/coverflow/
[패키지 첨부파일] CoverFlowScroll.unitypackage
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Holoville.HOTween;
using Holoville.HOTween.Plugins;
public class HeroTable : MonoBehaviour {
UISprite[] heros;
Transform mTrans;
bool mIsDragging = false;
Vector3 mPosition, mLocalPosition;
Vector3 mDragStartPosition;
Vector3 mDragPosition;
Vector3 mStartPosition;
public float cellWidth = 160f;
public float downScale = 0.4f;
public int cellTotal = 6;
public int seq = 3;
public UILabel titleLabel;
// Use this for initialization
void Start () {
StartCoroutine( DelayStart(1f) );
}
void Awake(){
mTrans = transform;
mPosition = mTrans.position;
mLocalPosition = mTrans.localPosition;
}
IEnumerator DelayStart(float delayTime) {
yield return new WaitForSeconds(delayTime);
heros = gameObject.GetComponentsInChildren<UISprite>();
SetPosition(false);
}
void SetSequence(bool isRight){
Vector3 dist = mLocalPosition - mTrans.localPosition;
float distX = Mathf.Round(dist.x/cellWidth);
seq = (int)distX;
if (seq >= cellTotal) seq = cellTotal - 1;
if (seq <= 0) seq = 0;
}
void SetPosition(bool isMotion){
Vector3 pos = mLocalPosition;
pos -= new Vector3(seq * cellWidth, 0f, 0f);
if (isMotion) {
TweenParms parms = new TweenParms();
parms.Prop("localPosition", pos);
parms.Ease(EaseType.Linear);
HOTween.To(mTrans, 0.1f, parms);
HOTween.Play();
} else {
mTrans.localPosition = pos;
}
titleLabel.text = heros[seq].spriteName;
}
void Drop () {
Vector3 dist = mDragPosition - mDragStartPosition;
if (dist.x>0f) SetSequence(true);
else SetSequence(false);
SetPosition(true);
}
void OnDrag (Vector2 delta) {
Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
float dist = 0f;
Vector3 currentPos = ray.GetPoint(dist);
if (UICamera.currentTouchID == -1 || UICamera.currentTouchID == 0) {
if (!mIsDragging) {
mIsDragging = true;
mDragPosition = currentPos;
} else {
Vector3 pos = mStartPosition - (mDragStartPosition - currentPos);
Vector3 cpos = new Vector3(pos.x, mTrans.position.y, mTrans.position.z);
mTrans.position = cpos;
}
}
}
void OnPress (bool isPressed) {
mIsDragging = false;
Collider col = collider;
if (col != null) {
Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
float dist = 0f;
mDragStartPosition = ray.GetPoint(dist);
mStartPosition = mTrans.position;
col.enabled = !isPressed;
}
if (!isPressed) Drop();
}
}
using System.Collections;
using System.Collections.Generic;
using Holoville.HOTween;
using Holoville.HOTween.Plugins;
public class HeroTable : MonoBehaviour {
UISprite[] heros;
Transform mTrans;
bool mIsDragging = false;
Vector3 mPosition, mLocalPosition;
Vector3 mDragStartPosition;
Vector3 mDragPosition;
Vector3 mStartPosition;
public float cellWidth = 160f;
public float downScale = 0.4f;
public int cellTotal = 6;
public int seq = 3;
public UILabel titleLabel;
// Use this for initialization
void Start () {
StartCoroutine( DelayStart(1f) );
}
void Awake(){
mTrans = transform;
mPosition = mTrans.position;
mLocalPosition = mTrans.localPosition;
}
IEnumerator DelayStart(float delayTime) {
yield return new WaitForSeconds(delayTime);
heros = gameObject.GetComponentsInChildren<UISprite>();
SetPosition(false);
}
void SetSequence(bool isRight){
Vector3 dist = mLocalPosition - mTrans.localPosition;
float distX = Mathf.Round(dist.x/cellWidth);
seq = (int)distX;
if (seq >= cellTotal) seq = cellTotal - 1;
if (seq <= 0) seq = 0;
}
void SetPosition(bool isMotion){
Vector3 pos = mLocalPosition;
pos -= new Vector3(seq * cellWidth, 0f, 0f);
if (isMotion) {
TweenParms parms = new TweenParms();
parms.Prop("localPosition", pos);
parms.Ease(EaseType.Linear);
HOTween.To(mTrans, 0.1f, parms);
HOTween.Play();
} else {
mTrans.localPosition = pos;
}
titleLabel.text = heros[seq].spriteName;
}
void Drop () {
Vector3 dist = mDragPosition - mDragStartPosition;
if (dist.x>0f) SetSequence(true);
else SetSequence(false);
SetPosition(true);
}
void OnDrag (Vector2 delta) {
Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
float dist = 0f;
Vector3 currentPos = ray.GetPoint(dist);
if (UICamera.currentTouchID == -1 || UICamera.currentTouchID == 0) {
if (!mIsDragging) {
mIsDragging = true;
mDragPosition = currentPos;
} else {
Vector3 pos = mStartPosition - (mDragStartPosition - currentPos);
Vector3 cpos = new Vector3(pos.x, mTrans.position.y, mTrans.position.z);
mTrans.position = cpos;
}
}
}
void OnPress (bool isPressed) {
mIsDragging = false;
Collider col = collider;
if (col != null) {
Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
float dist = 0f;
mDragStartPosition = ray.GetPoint(dist);
mStartPosition = mTrans.position;
col.enabled = !isPressed;
}
if (!isPressed) Drop();
}
}
using UnityEngine;
using System.Collections;
public class HeroItem : MonoBehaviour {
Transform mTrans, mParent;
Vector3 scale;
float cellWidth;
float downScale;
HeroTable hTable;
void Start () {
mTrans = transform;
scale = mTrans.localScale;
mParent = mTrans.parent;
hTable = mParent.GetComponent<HeroTable>();
cellWidth = hTable.cellWidth;
downScale = hTable.downScale;
}
void Update () {
Vector3 pos = mTrans.localPosition + mParent.localPosition;
float dist = Mathf.Clamp(Mathf.Abs(pos.x), 0f, cellWidth);
mTrans.localScale = ((cellWidth - dist*downScale) / cellWidth) * scale;
}
}
using System.Collections;
public class HeroItem : MonoBehaviour {
Transform mTrans, mParent;
Vector3 scale;
float cellWidth;
float downScale;
HeroTable hTable;
void Start () {
mTrans = transform;
scale = mTrans.localScale;
mParent = mTrans.parent;
hTable = mParent.GetComponent<HeroTable>();
cellWidth = hTable.cellWidth;
downScale = hTable.downScale;
}
void Update () {
Vector3 pos = mTrans.localPosition + mParent.localPosition;
float dist = Mathf.Clamp(Mathf.Abs(pos.x), 0f, cellWidth);
mTrans.localScale = ((cellWidth - dist*downScale) / cellWidth) * scale;
}
}
반응형
'Unity3D > NGUI' 카테고리의 다른 글
유니티 NGUI 논리 해상도와 픽셀 퍼펙트 (0) | 2013.09.11 |
---|---|
Unity 4 dynamic font support for NGUI - v2.3.4 (8) | 2013.02.27 |
해상도에 맞게 UI 위치 조절 (0) | 2013.01.04 |
해상도에 맞게 UI Scale (0) | 2013.01.04 |
NGUI: Events(Event Functions) (2) | 2012.12.07 |