목차

반응형

목차

목표

캐논 오브젝트 세팅

마우스 드래그 벡터 구하기

벡터와 변환된 각도 확인

각도 변환 설명

회전 각도 제한

일정 거리 이상 드래그 해야 발사 가능하도록 하기

전체 소스

 

 

목표

시연

만들고자 하는 결과물이다. 드래그 방향과 반대로 캐논 오브젝트가 가리키도록 하고 일정 거리 이상 드래그를 해야 발사가 가능하도록 한다.

 

캐논 오브젝트 세팅

다음과 같이 Circle에 Square로 포신을 만들고 Laser 오브젝트는 Square로 매우 얇고 길게 해서 만든다.

캐논 오브젝트는 단순히 플레이어에게 방향을 나타내주기만하고 게임에 영향을 주는 물리적인 요소는 전혀 없다.

 

다음과 같이 되도록 z축의 값을 차례대로 정해준다.

 

Cannon 스크립트를 생성하고 넣어준다.

맨아래 소스를 복사해서 넣는다.

 

인스펙터에서 Cannon 스크립트의 Laser에 생성한 Laser 오브젝트를 넣는다.

 

마우스 드래그 벡터 구하기

왼쪽 이미지를 보면 클릭하고 왼쪽 아래로 드래그를 하면 빨간색의 벡터만큼 크기(길이)와 방향성을 갖는다.

우리가 필요한 것은 반대방향의 벡터다. 반대방향의 벡터를 캐논 오브젝트에서 값을 가질 수 있도록 한다.

 

if (Input.GetMouseButtonDown(0))
{
originPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
IsMouseClicked = true;
}

최초로 마우스를 클릭하면 originPosition 벡터에 현재 카메라에 클릭된 위치를 world 좌표계로 바꿔서 저장한다.


currentMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
그리고 현재 마우스 위치를 currentMousePosition에 저장한다.

드래그를 하고 있다는 가정하에 계속해서 최초로 클릭한 곳의 위치와 현재 마우스의 위치의 차이를 구해야한다.


diffVector = (currentMousePosition - originPosition) * -1;
diffVectorManitude = diffVector.magnitude;
diffNormalVector = diffVector.normalized;

위에서 설명한대로 -1을 곱해서 방향을 반대로 해준다.

diffVectorManitude 는 벡터의 길이값을 환산해주는 것이고

diffNormalVector 는 캐논 오브젝트의 방향을 결정짓도록 하는 방향벡터의 단위벡터다.

 

벡터와 변환된 각도 확인

 

위와 같이 로그를 찍으면 다음과 같이 나온다.

 

차례대로

최초 마우스 클릭 위치

현재 마우스 위치

위치의 차

x,y좌표계 기준 벡터와 x축이 이루는 각도

 

 

각도 변환 설명


float rot_z = Mathf.Atan2(diffNormalVector.y, diffNormalVector.x) * Mathf.Rad2Deg;
currentDegree = Mathf.Clamp(rot_z - 90, -65, 65);

rot_z로 x축과 벡터가 이루는 각도를 계산하였는데 실제로 사용하기 위해서는 -90도를 더해줘야한다.

그 이유는 유니티에서의 벡터를 각도로 변환한 축이 위쪽으로 뻗어있기 때문이다.

 

위의 이미지를 보면 -90도가 일반적으로 우리가 생각하는 x,y축에서 x축이다.

즉 0도 = -90도 라고 대입을 해봤을때

만약에 방향벡터를 각도로 변환했을때 20도라면 -70도를 가져야 우리가 생각하는 상식선에서의 x,y 축 좌표계 방향이 나온다.

 

회전 각도 제한

드래그를 위쪽으로 하면 캐논이 아래를 가리키는데 그렇게 못하도록 최대 최소 각도를 제한해야한다.

diffVectorManitude = diffVector.magnitude;

currentDegree = Mathf.Clamp(rot_z - 90, -65, 65);

Mathf.Clamp를 사용해서 -65도와 65도 사이의 값만 가지도록 하였다.

-65도와 65도는 임의의 값이라서 마음대로 지정해도 된다.

-65도와 65도는 수기로 각도를 바꾸면서 이쯤이면 되겠다 싶은 값이다.

 

일정 거리 이상 드래그 해야 발사 가능하도록 하기

diffVectorManitude > 5;

위에서 계산한 벡터의 크기가 특정 값 이상일때만 즉 드래그를 어느정도 해야 발사가 가능하도록 할것인데 diffVectorManitude 가 일정값 이상일때 조건식을 사용하면 된다.

 

전체 소스

Cannon.cs

using UnityEngine;

public class Cannon : MonoBehaviour
{
    //최초 클릭 위치벡터
    private Vector3 originPosition;
    //현재(나중) 클릭 위치벡터
    private Vector3 currentMousePosition;
    //마우스가 클릭되었는지 여부
    private bool IsMouseClicked;
    //마우스 드래그 벡터
    private Vector3 diffVector;
    //마우스 드래그 벡터의 방향벡터
    private Vector3 diffNormalVector;
    //마우스 드래그 세기
    private float diffVectorManitude;
    //마우스 드래그 한 벡터 방향에 대한 z축 각도
    private float currentDegree;
    //발사 가능 여부
    private bool fireConfirm;
    //레이저 오브젝트
    [SerializeField] private GameObject Laser;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            originPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            IsMouseClicked = true;
        }
        else if (Input.GetMouseButtonUp(0))
        {
            Laser.SetActive(false);
            IsMouseClicked = false;    
            if (fireConfirm)
            {
                //발사처리
                Debug.Log("발사!");
            }
        }


        if (IsMouseClicked)
        {
            //카메라 기준 마우스 클릭 벡터 계산
            currentMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            
            //마우스 드래그 한 벡터 역방향
            diffVector = (currentMousePosition - originPosition) * -1;
            diffVectorManitude = diffVector.magnitude;
            diffNormalVector = diffVector.normalized;
            
            Debug.Log(originPosition);
            Debug.Log(currentMousePosition);
            Debug.Log(diffVector);

            //방향벡터의 x,y값으로 탄젠트를 이용하여 각도로 전환
            float rot_z = Mathf.Atan2(diffNormalVector.y, diffNormalVector.x) * Mathf.Rad2Deg;
            Debug.Log(rot_z);
            
            //드래그 거리가 충분하고 드래그를 위에서 아래쪽으로 했을때
            if (CheckHasPower() && rot_z>0)
            {
                //최소 -65도 최대 65도, 0도가 위방향이기때문에 -90도를 해줘서 오른쪽 방향이 되도록 한다.
                currentDegree = Mathf.Clamp(rot_z - 90, -65, 65);
                transform.rotation = Quaternion.AngleAxis(currentDegree, Vector3.forward);
                fireConfirm = true;
                Laser.SetActive(true);
            }
            else
            {
                fireConfirm = false;
                Laser.SetActive(false);
            }
        }
    }

    private bool CheckHasPower()
    {
        return diffVectorManitude > 5;
    }
}

 

JJTAN 개발 리뷰 시리즈

1. 프로토타입 수준의 오브젝트 및 환경 설정
2. 공 발사하는 캐논 설정
3. 인풋 설정, 공 발사
4. 장애물 생성
5. 장애물 적합한 사이즈 찾기
6. 장애물 색깔 그라데이션
7. 위험한 상황 줌인
8. 사망 판정
9. 데이터 저장과 이어하기
10. 한번 더 하기

추가 개발
튕기는 반사각 계산

반응형