ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Rollick 개발 일지] 04. 플레이어 움직이기, 점수 계산하기
    카테고리 없음 2023. 10. 27. 21:36

    지난 시간에는 장애물이 무작위로 나오는 기능을 구현하였다.

     

    이제 게임에 걸맞는 핵심 기능 중 하나인 유저의 드래그에 맞춰 플레이어가 움직이는 기능을 구현할 예정이다.

     

    	private void Update()
        {
        	MoveSkateBoard();
        }
        
        private void MoveSkateBoard()
        {
            Ray ray = _mainCam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
    
            if (Input.GetMouseButton(0) && Physics.Raycast(ray, out hit, 100, _roadMask))
            {
                Vector3 pos = new Vector3(transform.position.x, transform.position.y, hit.point.z);
                transform.position = pos;
            }
        }

    기능 구현 자체는 간단하다. 유저가 마우스를 누르고 있을 경우에 레이를 쏴 레이가 도로 안에 있다면 스케이트 보드의 

    좌표를 레이의 hit.point 좌표와 동기화 시켜주면 된다.

     

    하지만 이렇게만 코드를 작성할 경우 예시 화면과 같이 유저가 드래그를 꾹 누른 상태로 손가락을 화면 밖으로 빼면 보드 역시 화면 밖으로 나가는 문제가 있다. 

     

    private void MoveSkateBoard()
        {
            Ray ray = _mainCam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
    
            if (Input.GetMouseButton(0) && Physics.Raycast(ray, out hit, 100, _roadMask))
            {
                Vector3 pos = new Vector3(transform.position.x, transform.position.y, hit.point.z);
                if (pos.z <= -_limitZ || pos.z >= _limitZ)
                {
                    pos = transform.position;
                }
                
                transform.position = pos;
            }
        }

    수정된 코드이다. 히어라키 창에서 입력한 _limitZ값을 한계로 보드가 더욱 움직이지 않을 것이다.

    잘 작동하는 모습이다. (점수 추가 구현을 위해서 UIToolkit을 이용하여 UI를 추가했다.)

     

    점수 기능을 구현하겠다. 

    장애물과 근접한 상태로 아슬아슬하게 피하면 점수가 오르게 만들 예정이다.

    먼저 콜라이더를 두 개 부착하였다. 보드의 앞쪽에 붙어 있는 것은 아슬아슬하게 피했냐를 판단할 콜라이더,

    몸체쪽에 붙어있는 콜라이더는 장애물이 닿으면 게임 오버인 데드존이다. 

     

    보드의 앞쪽 콜라이더에 장애물이 닿아있는 상태에서 보드를 움직여 피한다면 점수를 지급할 것이다.

    private void MoveSkateBoard()
        {
            Ray ray = _mainCam.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
    
            if (Input.GetMouseButton(0) && Physics.Raycast(ray, out hit, 100, _roadMask))
            {
                Vector3 pos = new Vector3(transform.position.x, transform.position.y, hit.point.z);
                if (pos.z <= -_limitZ || pos.z >= _limitZ)
                {
                    pos = transform.position;
                }
                dir = (pos - transform.position).normalized;
                transform.position = pos;
            }
        }

    먼저 보드가 움직이고 있는지를 판단하기 위해 dir = (pos - transform.position); 을추가하였다. 

     

    보드는 Z좌표만 이동하기 때문에 dir.z가 0이 아니라면 움직이고 있다는 뜻이다.

     

    private void OnTriggerStay(Collider other)
        {
            if (other.CompareTag("Obstacle") && !_isRoll && !CompareTag("Range"))
            {
                Vector3 pos = other.ClosestPointOnBounds(transform.position);
                Rollick(pos);
            }
        }
        
        private void Rollick(Vector3 pos)
        {
            isHit = true;
            if (dir.z == 0) return;
            cis.GenerateImpulse();
            ScoreManager.Instance.AddScore(5000);
            ScoreManager.Instance.LookToAddScore(5000, pos);
            _isRoll = true;
        }
        
        private void OnTriggerExit(Collider other)
        {
            if (other.CompareTag("Obstacle") && _isRoll && !CompareTag("Range"))
            {
                _isRoll = false;
                isHit = false;
            }
        }

    닿아 있는 상태라면 OnTriggerStay가 호출된다. 닿아있는 콜라이더가 Obstacle태그가 있으며 _isRoll 상태가 아니며

    데드존 콜라이더의 오브젝트에 Range 태그를 붙여 콜라이더를 구별했다.

     

    위의 조건이 만족하면 닿은 위치와 함께 Rollick함수를 호출한다.

     

    Rollick 함수에선 dir.z가 0이 아니라면 미리 만들어둔 ScoreManager에 점수를 증가시킨다.

     

     

    잘 동작하는 모습이다.

     

    다음 포스팅에서 뵙겠습니다.

     

Designed by Tistory.