ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CCI - 02 - 플레이어 이동 구현
    팀업 프로젝트/C.C.I

    안녕하세요.

    오늘은 플레이어 이동 구현에 대해 알아볼 예정입니다.

     

    플랫폼은 모바일 환경으로 정하였고

    개발 환경은 Unity입니다.

    조이 스틱의 패드 역할을 하게 될 Sprite입니다.

    조이 스틱의 컨트롤러 역할을 하게 될 Sprite입니다.

    간단한 원형 이미지를 받아와 터치 패드를 구현했습니다.

     


    TochPad를 제어하기 위한 TochPad 스크립트를 새로 생성하였습니다.

     

    _touchPad : 조이스틱 패드 안에 엤는 컨트롤러입니다.

    일반적인 3차원 공간에 있는 Transform이 아닌 Canvers상에 존재하는 위치이기에

    RectTransform을 받아와 주는 모습입니다.

     

    _dragRadius : 조이스틱 패드의 반지름입니다. 

    (가운데를 기준점을 잡고 움직일 위치의를 잡았습니다.)

     

    _startPos : 터치 컨트롤러의 시작 지점입니다.

    시작 지점을 기준점으로 잡아 컨트롤러가 어느 방향에 위치해 있는지

    알 수 있으며 버튼이 눌린 상태에서 떼어지면 시작 지점, 즉 기준점으로 되돌아갑니다.

     

    _buttonPressed : 조이스틱 컨트롤러가 (터치/클릭) 됐는지

    체크할 불 변수입니다. 

    true = 터치 / false = 놓임

    상태를 의미할 것입니다.

     

     _player : 플레이어에게 입혀진 PlayerMovement 스크립트를 받아올 변수입니다.

    조이스틱 컨트롤러의 값을 PlayerMovement로 건네 주어

    그 값을 사용해 플레이어를 움직이게 만들 것입니다.


    시작 시 1회 실행되는 Start 함수와

     

    컨트롤러가 눌렸는지 체크할 ButtonDown / ButtonUp 함수입니다.

     

    Start 함수에서는 RectTransform(Canvas상 위치)를 받아왔으며

    이 초기 위치를 _startPos로 받았습니다.

     

    ButtonDown과 ButtonUp 함수는

    간단히 _buttonPressed를 true/false로 나타내 

    눌렸는지 안 눌렸는지 체크를 합니다.

     

    함수의 실행은

    둘 다 public으로 선언하여서

    터치 패드의 Event Trigger 컴포넌트를 추가해

     

    Pointer Down과 Pointer Up에서 실행되게 하였습니다.

     

    또한 PC환경에서 실행될 앞으로 작성할 HandleInput 함수의 인자

     

    좌표값을 시작점(기준점)인 _startPos로 건네 주 없습니다.

    또한 FixedUpdate함수에서

    일반 상황과 모바일 일대의 상황을 나누어

    함수를 따로 구현하였습니다.

     

    매 프레임마다 실행되는 Update 함수가 아닌

    프레임과 독립적으로 같은 시간의 간격으로 호출되는 정기적임을 위함입니다.

     

    HandleInput의 인자에 마우스를 이용해 Screen을 바로 출력한 값을 넣어주었습니다.

    HandleInput의

     

    첫 번째 조건문인 if-else문에서는

     

    _buttonPressed를 이용해 버튼이 눌렸는지 안 눌렸는지 판단을 해주었습니다.

     

     

    만일 버튼이 눌려져 있는 상태로 if문에 들어온다면

     

    기준 좌표로부터 input(입력받은 좌표)가 얼마나 떨어져 있는지

     

    방향을 구해 줍니다.

     

    이후 다시 한번 if-else문에서

     

    거리를 비교하는 것은 sqrMagnitude로 계산했습니다.

    (거리를 측정하는 데엔 Distance, magitude, sqrMagnitude 3가지가 있습니다.

    Distance와 magitude는 과정 및 결과가 같지만 편의를 위해 Distance를 제공을 하며

    sqrMagnitude는 제곱의 값을 리턴하며, 루트 연산을 하지 않아 연산 속도가 더 빠르고

    정확한 거리는 몰라도 단순 거리를 비교하는 데 사용된다고 학습했습니다.)

     

    즉 입력 지점이 패드의 최대치보다 크다면

     

    방향 거리를 1로 만든 후 방향 컨트롤러를 최대치만큼 움직이게 해 주었으며

     

    반대로 else문에서는 최대치가 아닐 시의 조건이 성립하여

     

    현재 입력 좌표에 방향키를 이동시켜 주었습니다.

     


    만일 _buttonPressed가 눌리지 않았을 시 실행될 else문에서는

     

    _touchPad(방향 컨트롤러)의 위치를 시작점으로 이동시켜 주며

     

    이후

     

    현재 컨트롤러와 기준 지점의 차이를 방향을 유지한

     

    채로 방향만 구해 normDiff에 받아 주었으며

     

    _player(PlayerMovement)가 연결이 되어 있다면

     

    OnStickChanged함수에 방향을 전달해 주었습니다.


    OnStickChanged의 함수가 있는

     

    플레이어의 실질적인 이동을 담당하는 PlayerMovement 스크립트입니다.

    playerMoveSpeed : 플레이어의 움직임 스피드입니다.

    playerJumpSpeed : 플레이어의 점프 시 스피드입니다.

     

    isJump : 플레이어가 점프 중인지 체크할 불 변수입니다.

    isDie : 플레이어가 죽었는지 체크할 불 변수입니다.

     

    h / v : Horizontal과 Vertical의 앞 글자를 따서 만든 

    TouchPad에서 받아온 좌표값을 받아 사용할 float 변수입니다.

     

    playerRigid : 플레이어의 리지드 바디입니다.

    (플레이어의 움직임 및 점프는, 피격 등 리지드 바디를 이용해 연출하였습니다.)

     

    playerAni : 플레이어의 애니메이터를 담아올 변수입니다.

     

    followCam : 플레이어를 보여줄 카메라입니다.

     

    movement : 플레이어의 움직임을 받아와 실행할 

    (현재는 테스트용 변수입니다.)

     

    이어서 Start함수입니다.

     

    각 선언 변수에 필요한 컴포넌트들을 받아와 주었습니다.

     

    방향 컨트롤러에서 변경이 일어나면 호출되는 함수입니다.

    (실질적인 플레이어의 움직임은 이 좌표값(터치패드 컨트롤러)에 의해 움직이게 됩니다.)

     

     PlayerMovement의 Update함수입니다.

     

    좀 나중에 추가된 if문이 있는데, 따로 삭제하지 않고

     

    하나씩 살펴보겠습니다.

     

    첫 번째 조건문인! isDie 즉, 플레이어가 죽지 않았을 때만 움직임이 가능합니다.

    플레이어가 죽은 뒤 쓰러진 채로 움직이는 것을 방지하기 위하여 조건을 걸어주었습니다.

     

    두 번째 playerAni는 animator를 제어하기 전 이 컴포넌트가 없다면 실행이 안됩니다.

    혼자 작업하는 것이 아닌 팀업 작업이기에, 담당은 제가 했지만 혹시 모를 상황을 대비했습니다.

    playerAni.SetFloat("Speed", (h * h + v * v)) 단순 애니메이터에 속도 값만 전달하여 주었습니다.

     

    세 번째 gameObject.layer == 11의 조건문은 레이어가 11일 때만 동작되게 하는 구현입니다.

    플레이어가 피격이 된다면 일정 시간 동안 레이어가 바뀌게 되는데, 이 레이어가 바뀌게 된다면 

    일정 시간동안 무적 판정을 갖게 해 주었습니다. 이후 일정 시간이 돌아가면 레이어는 다시 11번으로 바뀝니다.

    즉 피격을 당한 상황이거나 레이어가 바뀌어져 있는 상황에 움직임을 방지했습니다.

     

    플레이어의 이동 구현은 RigidBody의 velocity를 이용했으며, 현재 velocity의 값을 Vector speed로 받아와

    x축과 z 축에 받아온 좌표값 * 지정한 스피드를 곱해 주었습니다.

     

    마지막으로 (h!= 0f && v!= 0f)의 조건문은

     

    받아온 좌표값 h와 v가 모두 0이 아니라면 방향 전환을 위해

     

    transform의 rotation값에 

     

    해당 벡터 방향을 바라보는 회전상태를 반환하는 LookRotation을 이용해 Quaternion으로 변환된 값을 넣어 주었습니다.

    캐릭터의 방향 전환을 즉시 이뤄지게 하기 위함이며, 애니메어테 전달되지 않고 자체적으로 해결하기 위함입니다.

     

    00 : 21초

    이것으로 플레이어가 조이스틱으로 움직이는 부분을 알아보았습니다!!

     

    다음 글에서는 점프 버튼 및 미니맵 구현 동작을 살펴보겠습니다.


    감사합니다.

     

    '팀업 프로젝트 > C.C.I' 카테고리의 다른 글

    CCI - 04 - Hp  (0) 2022.05.13
    CCI - 03 - 버튼 & Mini Map (UI)  (0) 2022.05.12
    CCI - 01 - 에셋 및 기획 단계  (0) 2022.05.12
    CCI - UI항목 별도 정리  (0) 2022.05.10
    CCI - 제작중 - (추가10)★★★★★  (0) 2022.05.10

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net