목록Categories (1099)
KoreanFoodie's Study
Unreal unresolved external symbol 에러 오랜만에 언리얼을 켰는데 다음과 같은 에러가 발생했다. 일반적으로, 크게 두 가지로 나뉘는데.... 1. 함수를 선언만 하고 구현을 안함 링커에서 에러가 났다는 건, 링킹 과정에서 적절한 함수를 찾지 못했다는 의미이기도 하다. 따라서 선언만 해놓고 실제로 구현을 하지 않은 메소드가 있는지 체크해보도록 하자! 근데 이 경우는 구현이 안된 함수가 있다고 알려줘서 쉬운데... 2. 적절한 모듈을 추가하지 않음 사실 이 경우가 매우매우 빡친다. 왜냐하면 명시적으로 원인이 드러나지 않기 때문이다. 하지만 에러로그를 잘 보면 힌트를 찾을 수 있는데... 실제 예시를 보자. 위 경우에서는, 잘 보면 LNK2019 에러에서 BehaviorTree 관련에..
플레이어 캐릭터 애니메이션 설정하기 특정 동작을 할 때 특정 애니메이션이 재생되도록 하는 기능은 애니메이터 컨트롤러와 애니메이터를 통해 가능하다. 먼저 애니메이터 컨트롤러를 생성하자. Project 창에서 생성 가능하다. 애니메이터 창으로 이동해 보자. 이전에 만든 애니메이션 클립들이 뜨게 된다. 특정 동작을 기본 상태로 정의하고 싶을 때는 Set as Layer Default State 로 설정하면 된다. 우클릭 후 Make Transition 을 통해 상태를 전이시킬 수 있다. Any State 상태에서 전환을 할 경우, 특정 조건을 만족하면 무조건 특정 상태로 전이가 된다. Exit 의 경우 상태 머신의 동작이 종료되는 출구를 의미한다. 전이가 언제 발동될지의 조건은 애니메이터 컨트롤러의 파라미터를..
캐릭터 애니메이션 클립 만들기 먼저, 애니메이션 창을 연다. Player 오브젝트를 클릭 후, Create 를 누른다. 그 후, 우리가 만드려는 애니메이션에 필요한 스프라이트들을 Animation 창으로 드래그&드랍한다. 그럼 다음과 같이 해당하는 키프레임 위에 스프라이트들이 올라가는데, Samples 값을 조절해 속도를 조절할 수 있다. Samples 의 값은 1초당 스프라이트가 얼마나 자주 교체되는지를 의미한다. 이제 Die 애니메이션 클립을 만들어 보자. Run 에서 Create New Clip... 을 누르고, Die.anim 으로 저장한다. 마찬가지로 Samples 값을 설정한다. Die 의 경우 딱 한 번만 재생될 것이므로 루프를 해제한다. 이제 다음으로는 FSM (유한 상태 머신) 을 이용해..
유니티에서 오디오 (소리) 재생하기 유니티에서 플레이어가 소리를 내도록 만들고 싶을 때는, 오디오 소스 컴포넌트를 붙이면 된다. 그 후, 스크립트에서 사용할 AudioClip 과 AudioSource 변수를 정의하고, 플레이어 스크립트의 AudioClip 변수에 적절한 오디오 소스 파일을 드래그&드랍해서 넣어준 다음, 실제 타이밍에 맞게 Play 나 PlayOneShot 등의 메소드를 활용하면 된다! 혹은 다음과 같이 구현해도 된다 : // 오디오 소스 컴포넌트에 내장된 클립을 변경 playerAudioPlayer.clip = deathClip; playerAudioPlayer.Play(); 오디오 소스 컴포넌트가 재생하는 소리는 오디오 리스너 컴포넌트가 듣는다. MainCamera 의 경우, Audio..
스프라이트 자르기 픽셀 아트 이미지를 이용해서, 간단한 스프라이트 애니메이션을 만들어 보자. 예를 들어, 다음과 같이 캐릭터가 죽는 스프라이트가 한꺼번에 한 파일로 들어왔다고 해 보자. Inspector 창에서 Sprite Mode 를 Multiple 로 바꾼 다음,Sprite Editor 를 열자. 스프라이트 에디터 왼족 상단에 Slice 에서 Grid By Cell Size 를 클릭한다. 그 후 적절한 사이즈로 스프라이트를 자르면 다음과 같이 스프라이트가 잘린 것을 확인할 수 있다! 오른쪽 상단의 Apply 를 누른 후 종료하자.
지역 공간과 전역 공간 위의 큐브는 y 축을 기준으로 회전을 가해졌다. 현재 트랜스폼의 좌표계는 지역공간으로 나와 있는데, 이를 전역 공간 (게임 월드를 기준) 으로 바꿔서 옮겨볼 수도 있다. 지역 공간은 부모 오브젝트를 기준으로 하며, 오브젝트 공간은 자기 자신을 기준으로 한다. 지역 공간이 부모 오브젝트를 기준으로 하기 때문에, 큐브 A 의 자식 큐브 B 를 설정한 후 큐브 A 를 회전하면, 큐브 B 의 공간도 회전된 상태로 트랜스폼이 이동과 회전이 이루어질 것이다. 인스펙터 창에 표시되는 위치, 회전, 스케일은 지역 공간 기준으로 측정된 값이다. 평행이동과 회전 예제 // 기본적으로 지역 공간을 기준으로 평행이동 transform.Translate(new Vector3(0, 1, 0) * Time...
Udemy 관련 개념 정리 및 Dev Log 를 기록하고 있습니다! 유니티 Awake 와 Start 차이 유니티에서 Awake 와 Start 는 둘 다 초기화를 담당한다. 그런데 어떤 차이가 있는 걸까? Awake() : 모든 변수와 게임의 상태를 초기화하기 Awake 는 일반적으로 게임이 시작되기 전에 호출 (start 보다 먼저 호출) 되며, 모든 오브젝트가 초기화되고 호출된다. 따라서 GameObject.FindWithTag 를 이용해 해당 게임 오브젝트를 요처하거나 다른 오브젝트와 안전하게 상호작용기 가능하다. [주의] : 각 게임 오브젝트의 Awake() 는 랜덤 순서로 실행되므로, 스크립트간의 참조(reference) 를 설정하기 위해 Awake 를 사용하고, 정보를 보내고 받는 경우에는 St..
Udemy 관련 개념 정리 및 Dev Log 를 기록하고 있습니다! 유니티에서 일시정지하기 유니티에서는 일시 정지 기능을 어떻게 구현하면 될까? 먼저 결론만 말하자면, Time.timeScale 값을 조절하여 Time.deltaTime 을 0 으로 만드는 방식을 이용하면 된다. void PauseGame () { Time.timeScale = 0; } void ResumeGame () { Time.timeScale = 1; } 이런 방식을 이용하면, 각 게임 오브젝트들의 Update 내 함수에서 Time.deltaTime 에 의존하는 모든 동작이 멈추게 된다. 이 말은즉슨, Time.deltaTime 에 의존하지 않는 녀석들의 경우에는 여전히 일시정지라는 본연의 목적과 다른 동작을 할 수 있음을 의미한다..
유니티 공부 노트 Touch Input 이용시 에러? 분명히 에디터에서는 마우스 클릭 입력으로 잘 동작했는데, 모바일로 빌드하니 제대로 작동을 하지 않아 원인을 파악하던 중, Input 관련에 문제가 있다는 것을 알게 되었다. 기존에는 터치 입력을 다음과 같이 구현했었는데... (후략) if (Input.GetTouch(0).phase == TouchPhase.Began) { JumpButtonPressed(); } 근데 이 경우, argumentexception: index out of bounds 에러가 발생했었다. 이는 터치 자체가 없는데, Input 에서 Touch 의 첫번째 인덱스를 가져오려 해서 생긴 문제였다. 따라서 다음과 같이 간단히, Touch 배열이 비어있지 않은지 체크해주기만 하면 된..
Udemy 강좌를 들으며 내용 복습을 위해 기록하는 글입니다 유니티 #1-4 : tag 사용하기 유니티는 tag 를 이용해 게임 오브젝트를 쉽게 식별할 수 있다. 예를 들어, 플레이어가 충돌하면 점수를 올리는 코드를 짠다고 가정해 보자. private void OnCollisionEnter(Collision other) { if (other.gameObject.tag == "Player") { GetComponent().material.color = Color.red; gameObject.tag = "Hit"; } } 위 코드는 플레이어와 해당 오브젝트가 충돌을 하면 색깔을 빨간색으로 바꾸고, 현 게임 오브젝트의 태그를 Hit 으로 변경한다. 이때, 충돌한 오브젝트가 플레이어인지 아닌지 판단을 하기 위해..