모바일로 빌드를 하면 따로 움직이게 하는 버튼이 없으니 조이스틱을
이용하여 움직이게 하는 것입니다.
그래서 이번 강의는 조이스틱으로 오브젝트 움직이기 입니다.
우선 [GameObject-> 3D Object-> Cube] 을 클릭해주세요.
일단 움직여야할 개체를 만듭니다.
그리고 난뒤에 cube가 만들어지고 따로 2d sprite를 만듭니다.
그리고 각각 이름을 Stick과 Pad라는 이름을 정하게되고 파일을 다운 받아 Resources에 있는 두그림을
넣어주게 됩니다.
그렇게하고 빈 오브젝트를 하나 생성하여 Joystick이라고 이름을 지정하고
Stick과 Pad와 플레이어인 Cube를 안에 넣어줍니다.
그렇게하고 stick이라는 오브젝트에는 tag를 stick이라고 설정해줍니다.
왜냐하면 스크립트상에서 stick이라는 tag를 찾아서 stick을 움직이게해주므로 해야합니다.
그리고 raycast가 찾아야하므로 box collider를 만들어줍니다.
물론 그림에는 없지만 Pad에도 box collider를 만들어줘야합니다.
그렇게하고 scripts에있는 joystick 스크립트를 joystick에 넣어주게됩니다.
그리고 player에는 cube를 stick에는 stick을 pad에는 pad를 넣어주게됩니다.
그리고 speed는 말그대로 속도입니다. 얼마나 빠르게 움직일지 설정합니다. 제가 해 본 결과로는 0.1이 가장 무난했습니다.
더 빠르게 할거면 더 빠르게 하셔도 됩니다.
그리고 checkstick인 bool문은 stick을 손으로 터치 했는지 안했는지 체크를 하기 위함입니다.
자 다음은 joystick의 스크립트 입니다.
using UnityEngine;
using System.Collections;
public class joystick : MonoBehaviour {
public GameObject player; // 플레이어
public float speed; // 플레이어의 움직임 = 속도
public GameObject stick; // 조이스틱 중 움직일 오브젝트
public GameObject pad; // 조이스틱이 벗어나지 못하게 막기 위한 오브젝트
public bool checkstick; // stick이라는 오브젝트가 터치 됐는지 안됐는지 체크 하기 위함
Vector3 Min; // pad의 간격을 알기 위함
Vector3 Max; // 위와 같음
Vector3 Old_Pos; // stick오브젝트의 초기 좌표를 잡기 위함(터치가 끝난 뒤 다시 stick오브젝트가 원위치로 되돌리기 위함)
float radian; // 각도를 구하기 위함(각도를 구하여서 각도를 비교하여 그 각도로 플레이어를 움직이기 위함)
// Use this for initialization
void Start () {
Old_Pos = stick.transform.localPosition; // stick오브젝트 초기 좌표 잡기
Min = pad.transform.position - pad.GetComponent<Collider> ().bounds.size / 2; // pad의 사이즈 구하기 위함
Max = pad.transform.position + pad.GetComponent<Collider> ().bounds.size / 2; // pad의 사이즈 구하기 위함(왜냐하면 이 사이즈보다 stick오브젝트가 넘어가지 못하게 하기 위함)
}
// Update is called once per frame
void Update () {
if(Input.GetTouch(0).phase == TouchPhase.Began) // 터치를 했을 경우
{
RaycastHit hit; // raycast 를 만든다.
Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position); //터치의 좌표를 ray좌표로 잡고
if(Physics.Raycast(ray, out hit)) // 그 ray 좌표로 잡은 좌표가 "stick"이라는 tag가 걸린 오브젝트를 터치 했는지 체크후 맞다면 true로 변환
if(hit.collider.tag == "stick")
checkstick = true;
}
if(Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(0).phase == TouchPhase.Stationary) // 터치 후 움직이거나 고정 했을때 반응
{
if(checkstick) // 체크가 됐을 경우
{
Vector3 touchposition = Input.GetTouch(0).position;
Vector3 worldposition = Camera.main.ScreenToWorldPoint(new Vector2(touchposition.x,touchposition.y));
worldposition.x = Mathf.Clamp(worldposition.x,Min.x,Max.x); // mathf라는 함수는 오브젝트의 좌표를 두 좌표의 범위내에서만 돌아다닐 수 있게 하기 위함
worldposition.y = Mathf.Clamp(worldposition.y,Min.y,Max.y);
//Maftf.Clamp란?Mathf.Clamp(현재좌표,최소좌표,최대좌표) 로 지정하신 좌표축과 좌표축의 움직이는 범위를 정하는 메소드이다.
stick.transform.position = new Vector2(worldposition.x,worldposition.y);
//pad와 stick의 임의의 점 pad_stick과 pad와의 방향 벡터와 stick과 pad와의 방향 벡터를 구한 후 단위벡터로 만든뒤 * 180 / Mathf.PI해서 각도를 구하게 된다.
//AngleBetween이란 두 좌표 사이의 각도를 구한다.
Vector3 pad_stick = new Vector3(pad.transform.position.x,pad.transform.position.y+ 1.0f,pad.transform.position.z);
radian = Vector3.AngleBetween((stick.transform.position - pad.transform.position).normalized, (pad_stick - pad.transform.position).normalized) * 180 / Mathf.PI;
player.transform.position += (stick.transform.position- pad.transform.position).normalized * speed;
}
}
if(Input.GetTouch(0).phase == TouchPhase.Ended)//터치 한 걸 뗄 경우
{
checkstick = false; // 다시 체크를 false로 바꿈
stick.transform.localPosition = Old_Pos; // 원래 잡았던 stick의 초기 좌표로 다시 되돌려 보냄
}
}
}