[Unity] 자습서 3장 - 캐릭터 제작(Mac)

2023. 2. 21. 19:27·개발/Unity
목차
  1. 스크립트 생성
  2. 캐릭터 이동 구현
  3. Time.deltaTime
  4. 애니메이션
  5. 무기 장착
  6. 그림자
  7. Follow Camera 로직

이번 장에서는 플레이어 캐릭터를 제작하고 C# 스크립트를 작성하여 이동 로직을 구현할 것이다. 우선 다운받은 Player 게임오브젝트를 하이러키 뷰로 드래그하여 배치한다. 이제 스크립트를 작성하여 이동을 구현할 것인데 유니티는 C# 언어를 지원하기 때문에 visual studio 와 visual studio code를 이용할 수 있다. 필자는 vscode를 이용하여 해보고 싶었지만, 자동완성이 안되고 monosharp 오류 등 이상한 문제가 계속 생겨 머리가 아파져서 그냥 visual studio for mac 을 쓰기로 하였다. (윈도우는 visual studio 2019)

코드 에디터를 선택하였으면 Unity 설정에서도 변경을 해주어야 하는데, [Unity] -> [Preferences] -> [External Tools] 섹션에서 External Script Editor를 원하는 에디터로 설정해주면 된다.

 

 

스크립트 생성

다음으로 스크립트를 생성한다. 프로젝트 뷰에서 오른쪽 마우스를 클릭 후 [Create] -> [C# Script]를 선택하여 스크립트를 하나 생성한다. 이름은 PlayerCtrl 이라고 주었다. 스크립트를 더블 클릭하면 선택한 에디터로 열리게 된다. 스크립트는 C# 클래스의 기본 구조와 Start, Update 함수가 포함된 스크립트가 자동으로 작성된 상태이다.

 

유니티에서 Start 함수와 Update 함수는 가장 기본적인 함수이자 이벤트 함수이다. Start 함수는 Update 함수가 호출되기 전에 한 번만 호출된다. Update 함수는 프레임마다 호출되는 함수로 주로 게임의 핵심 로직을 작성한다. 한 가지 주의할 점으로 스크립트의 파일명을 바꾸었으면 스크립트 안의 클래스 이름도 똑같이 바꾸어 주어야 한다는 것이다. 그렇지 않으면 에러가 발생한다!

 

캐릭터 이동 구현

GetAxis 메서드를 이용하여 상하좌우 화살표에서의 입력값을 받아 반환하고, 마우스의 좌우 이동 값을 받아와 반환한다. 화살표를 누르면 해당 방향으로 이동하고 마우스를 좌우로 움직이면 그 방향으로 캐릭터가 회전한다.


      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour
{
// 컴포넌트를 캐시 처리할 변수
private Transform tr;
// 이동 속도 변수 (public으로 선언되어 인스펙터 뷰에 노출됨)
public float moveSpeed = 10.0f;
// 회전 속도 변수
public float turnSpeed = 80.0f;
// Start is called before the first frame update
void Start()
{
// Transfrom 컴포넌트를 추출해 변수에 대입
tr = GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
float r = Input.GetAxis("Mouse X");
//Debug.Log("h=" + h);
//Debug.Log("v=" + v);
// 전후좌우 이동 방향 벡터 계산
Vector3 moveDir = (Vector3.forward * v) + (Vector3.right * h);
// Translate 함수를 사용한 이동 로직
tr.Translate(moveDir.normalized * moveSpeed * Time.deltaTime);
// Vector3.up 축을 기준으로 turnSpeed 만큼의 속도로 회전
tr.Rotate(Vector3.up * turnSpeed * Time.deltaTime * r);
}
}

Time.deltaTime

Time.deltaTime은 이전 프레임의 시작 시각부터 현재 프레임이 시작되는 시각의 차(델타)를 말한다. 즉 이전 프레임부터 현재 프레임까지 걸린 시간의 차이다. 같은 소스 코드지만 프레임 레이트가 다른 환경에서 실행하면 속도가 달라지는 문제가 발생한다. 이 문제는 Time.deltaTime을 곱하는 것을 해결할 수 있다. 프레임 레이트가 서로 다른 기기에서도 개발자가 정한 일정한 속도로 이동시킬 수 있는 것이다.

 

애니메이션

다운받은 애니메이션 리소스를 통해 캐릭터 애니메이션을 구현해보자. 프로젝트 뷰의 Player 모델을 선택한 후 인스펙터 뷰에서 Rig 탭을 선택하고 Animation Type 속성을 Legacy 로 설정한다.

 

다운받은 애니메이션 리소스에서 Idle(일반 상태), RunB(뒤로 이동), RunF(앞으로 이동), RunL(왼쪽 이동), RunR(오른쪽 이동) 다섯 가지 애니메이션의 Wrap Mode 속성을 Loop로 설정하고 하이러키 뷰에서 Player를 선택한 후 Animation 컴포넌트에 드래그 한다.

 

 

마지막으로 애니메이션 이 변경될 때 이를 부드럽게 연결해주기 위해 애니메이션 블렌딩 기능을 사용하였다. 스크립트 하단에 PlayerAnim 함수를 생성하고 anim.CrossFade 함수를 이용하여 애니메이션의 변화가 부드럽게 이어지도록 하였다. CrossFade 함수는 두 개의 인자를 받는데 첫 번째 인자는 변경할 애니메이션 클립의 명칭이며, 두 번째 인자는 다른 애니메이션 클립으로 페이드아웃 되는 시간을 의미한다.


      
void PlayerAnim(float h, float v)
{
if (v >= 0.1f)
anim.CrossFade("RunF", 0.25f); // 전진 애니메이션 실행
else if (v <= -0.1f)
anim.CrossFade("RunB", 0.25f); // 후진 애니메이션 실행
else if (h >= 0.1f)
anim.CrossFade("RunR", 0.25f); // 오른쪽 이동 애니메이션 실행
else if (h <= -0.1f)
anim.CrossFade("RunL", 0.25f); // 왼쪽 이동 애니메이션 실행
else
anim.CrossFade("Idle", 0.25f); // 정지 시 Idle 애니메이션 실행
}

 

무기 장착

다음으로는 캐릭터에게 무기를 장착시켜준다. Idle 상태의 애니메이션은 총을 들고 있는 동작을 취하고 있으므로 다운받은 리소스에서 총 모델을 골라 하이러키 뷰의 Player를 펼치면 나오는 pelvis안의 Rweaponholder 에 드래그 해준다. pelvis 는 관절 정보를 담고 있는 게임오브젝트로서 인체로 치면 골반을 의미한다.

 

무기 장착후 Idle 애니메이션 실행 상태

 

그림자

유니티는 Direntional Light, Point Light, Spotlight 세 가지 광원에 대해 실시간 그림자를 지원한다. 하지만 실시간 그림자는 처리 비용이 매우 크다. 실시간 그림자보다 시각적인 효과는 덜 하지만, 그래도 입체감을 낼 수 있는 가벼운 그림자 처리를 평면 메시를 이용하여 구현해 보자. 

-Cast Shadows: 빛을 받아서 자신의 그림자를 만들 것인지 결정하는 속성&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -Receive Shadows: 다른 그림자에 들어갔을 때 표면에 그림자의 영향을 받는지 아닌지

먼저 플레이어의 Cast Shadows를 off, Receive Shadows의 체크를 해제하고 총 역시 마찬가지로 그림자가 없어지게끔 해제한다. Player의 자식으로 Quad 오브젝트를 하나 추가하고 이름을 Shadow로 바꿔준다. 다운받은 리소스에서 그림자 역할을 할 텍스처를 Quad에 드래그하여 적용해준 뒤 Shadow(Quad)를 선택하여 Shader를 [Mobile] -> [Particles] -> [Multiply]로 변경하면 자연스러운 그림자 효과가 표현된다.

 

평면 메시를 이용한 방식은 부하가 적은 방법으로 많이 사용되지만, 게임 스테이지에 굴곡이 있거나 경사로가 있다면 그림자가 다른 메시에 묻혀 제대로 표현되지 않는다는 단점이 있다.

 

Follow Camera 로직

이제 카메라가 주인공 캐릭터를 따라가는 기능을 구현할 차례이다. 새로운 스크립트를 생성하고 다음과 같이 코드를 작성하였다.

<FollowCam.cs>


      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowCam : MonoBehaviour
{
// 따라가야 할 대상을 연결할 변수
public Transform targetTr;
// Main Camera 자신의 Transform 컴포넌트
private Transform camTr;
// 따라갈 대상으로부터 떨어질 거리
[Range(2.0f, 20.0f)]
public float distance = 10.0f;
// Y축으로 이동할 높이
[Range(0.0f, 10.0f)]
public float height = 2.0f;
void Start()
{
// Main Camera 자신의 Transform 컴포넌트를 추출
camTr = GetComponent<Transform>();
}
private void LateUpdate()
{
// 추적해야 할 대상의 뒤쪽으로 distance만큼 이동
// 높이를 height만큼 이동
camTr.position = targetTr.position
+ (-targetTr.forward * distance)
+ (Vector3.up * height);
// Camera를 피벗 좌표를 향해 회전
camTr.LookAt(targetTr.position);
}
}

 

카메라 이동을 부드럽게 하기 위해 Vector3.SmoothDamp 함수를 이용하여 코드를 수정해 주었다. 


      
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowCam : MonoBehaviour
{
// 따라가야 할 대상을 연결할 변수
public Transform targetTr;
// Main Camera 자신의 Transform 컴포넌트
private Transform camTr;
// 따라갈 대상으로부터 떨어질 거리
[Range(2.0f, 20.0f)]
public float distance = 10.0f;
// Y축으로 이동할 높이
[Range(0.0f, 10.0f)]
public float height = 2.0f;
// 반응 속도
public float damping = 10.0f;
// 카메라 LookAt의 Offset 값
public float targetOffset = 2.0f;
// SmoothDamp에서 사용할 변수
private Vector3 velocity = Vector3.zero;
void Start()
{
// Main Camera 자신의 Transform 컴포넌트를 추출
camTr = GetComponent<Transform>();
}
private void LateUpdate()
{
// 추적해야 할 대상의 뒤쪽으로 distance만큼 이동
// 높이를 height만큼 이동
Vector3 pos = targetTr.position
+ (-targetTr.forward * distance)
+ (Vector3.up * height);
// 구면 선형 보간 함수를 사용해 부드럽게 위치를 변경
// camTr.position = Vector3.Slerp(camTr.position, // 시작 위치
// pos, // 목표 위치
// Time.deltaTime * damping); // 시간 t
// SmoothDamp를 이용한 위치 보간
camTr.position = Vector3.SmoothDamp(camTr.position, // 시작 위치
pos, // 목표 위치
ref velocity, // 현재 속도
damping); // 목표 위치까지 도달할 시간
// Camera를 피벗 좌표를 향해 회전
camTr.LookAt(targetTr.position + (targetTr.up * targetOffset));
}
}

 

이렇게 주인공 캐릭터 생성과 애니메이션 적용, 카메라 세팅을 완료하였다. 책을 읽고 따라한 내용이라 이해가 되지 않는 부분도 많아서 다시 복습을 해야 되겠다.

'개발 > Unity' 카테고리의 다른 글

[Unity] 자습서 6장 - 적 캐릭터 구현  (0) 2023.02.28
[Unity] 자습서 5장 - 코루틴, 오디오  (0) 2023.02.24
[Unity] 자습서 4장 - 총 발사 로직(Mac)  (0) 2023.02.22
[Unity] 자습서 2장 - 게임 스테이지 제작(Mac)  (0) 2023.02.21
[Unity] 자습서 1장 - Unity 시작하기(Mac)  (0) 2023.02.20
  1. 스크립트 생성
  2. 캐릭터 이동 구현
  3. Time.deltaTime
  4. 애니메이션
  5. 무기 장착
  6. 그림자
  7. Follow Camera 로직
'개발/Unity' 카테고리의 다른 글
  • [Unity] 자습서 5장 - 코루틴, 오디오
  • [Unity] 자습서 4장 - 총 발사 로직(Mac)
  • [Unity] 자습서 2장 - 게임 스테이지 제작(Mac)
  • [Unity] 자습서 1장 - Unity 시작하기(Mac)
Majangnan
Majangnan
  • Majangnan
    개발 모코코
    Majangnan
  • 전체
    오늘
    어제
    • 분류 전체보기 (61)
      • 개발 (60)
        • C# (10)
        • SQL (3)
        • Unity (8)
        • Unreal (10)
        • C++ (2)
        • Server (1)
        • DX11 (8)
        • 알고리즘 (17)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 깃허브
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Mecanim
    blueprint
    백준
    sql
    Unity
    3dlight
    상속
    dx3d
    블루프린트
    슈팅게임
    코딩테스트
    MAC
    c++
    DX11
    UnReal
    C#
    언리얼
    DirectX11
    프로그래머스
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Majangnan
[Unity] 자습서 3장 - 캐릭터 제작(Mac)

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.