포폴 개발초기에는 키보드로 테스트하였기에 별 문제없이 테스트했지만
유니티 어플을 통해 스마트폰으로 테스트하려니 가상조이스틱이 필요하게 되었다.
NGUI 튜토리얼에 가상 조이스틱이 있다고 들었는데 찾지를 못 해서 스스로 구현하게 되었는데
조이스틱을 만들 때 기준이 되는 큰원, 내부에 왔다갔다 할 작은 원, 작은원의 최대 위치를 가르킬 빈오브젝트
이렇게 3개의 게임오브젝트를 이용하였다
코드 요약
1. 오브젝트가 눌렸을 때 눌려진 터지번호를 기억하고 update에서 이용한다. 터치번호가 없다면 update에서는 동작을
하지않는다.
2. 기억된 터치번호를 이용하여 터치된 위치를 스크린 좌표에서 직교좌표계로 좌표값으로 변경한다.
3. 변경된 좌표값에 작은원 오브젝트인 Inner_Pad를 이동시킨다. 이동된 작은원과 큰원의 중점을 이용해 벡터를 얻고
그 벡터에 대해 길이와 정규화한 방향벡터를 얻는다.
4. 만약 길이가 미리 정해놓은 최대 길이보다 길다면 강제로 해당 방향벡터의 최대길이 위치로 이동시킨다.
5. 현재길이 / 최대길이 식으로 최대속도 1를 나올 수 있게 하고 해당 방향을 캐릭터 이동에 넘겨준다.
6. 캐릭터 이동에서는 속도와 방향을 얻어 해당방향으로 이동할 수 있도록 한다.
처음에는 포토샵으로 알파채널이 들어간 동그라미 큰것 작은것으로 구현했었으나 인터넷으로 적당한 그림을 찾아서 대충 바꿔놨음.
아래는 개발한 코드들이다.
using UnityEngine; using System.Collections; public class VI_Pad : MonoBehaviour { public Camera UICam = null; public Transform InnerPad = null; Vector3 dir = new Vector3(0,0,0); float distance = 0.0f; float distanceMax = 0.0f; public CharactorMove CharMove = null; bool IsPress = false; int touch_ID = -1; void Awake () { // InnerPad가 null일 경우 스스로 찾음 if (!InnerPad) { InnerPad = GameObject.Find("VI_Pad_Inner").transform; } // CharMove이 null 일 경우 스스로 찾음 if (!CharMove) { CharMove = GameObject.Find("PLAYER").GetComponent<charactormove>(); } // 최대 거리 distanceMax = (transform.position - GameObject.Find("UI Root/UICam/UIPanel/VI_Pad/MaxXpos").transform.position).magnitude; } // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (IsPress && touch_ID > -1) { // Touch 코드 Vector3 touch = Input.GetTouch(touch_ID).position; Vector3 padPos = UICam.ScreenToWorldPoint(new Vector3(touch.x, touch.y, 0)); // 최대 Touch 거리를 넘어섰을 경우 최대거리로 제한 if( (padPos - transform.position).magnitude > distanceMax) { padPos = transform.position + (padPos - transform.position).normalized * distanceMax; } InnerPad.position = padPos; } // 방향벡터 얻기 Vector3 Temp = (InnerPad.position - transform.position).normalized; dir.x = Temp.x; dir.y = 0.0f; dir.z = Temp.y; // 거리 계산 distance = (InnerPad.position - transform.position).magnitude; //Debug.Log(InnerPad.position); // 캐릭터 이동 회전 호출 CharMove.playerMove(dir, distance / distanceMax); } void OnPress(bool _IsPress) { // 패드가 눌렸을 경우 터치의 충돌여부 판단과 충돌된 터치번호를 얻음 IsPress = _IsPress; if( IsPress) { for (int i = 0; i < Input.touchCount; ++i) { Ray ray = UICam.ScreenPointToRay(Input.GetTouch(i).position); RaycastHit2D rayhit = Physics2D.GetRayIntersection(ray, Mathf.Infinity); if (rayhit.collider == this.GetComponent<collider2d>()) { touch_ID = i; } } } } void OnRelease() { IsPress = false; touch_ID = -1; } }
'Programming > Unity' 카테고리의 다른 글
Unity C# Zoom in out (0) | 2015.08.03 |
---|---|
NGUI HUDText 사용 (2) | 2015.07.30 |
NGUI HP Bar 만들기 (0) | 2015.07.30 |
몬스터 FSM 구현 (3) | 2015.07.30 |
유니티(unity) 디버깅 하기 (0) | 2014.01.28 |