[3일차] 왜 자동 전투 시스템이 도입됐을까? Reference ① 리니지2M ② 오토체스 RPG게임들이 PC/콘솔 시장에서 모바일 시장으로 변하면서 세밀한 전투가 점점 어려워지기 시작했습니다. 손가락으로 터치하면 화면이 가려지기도 하고, 키보드를 사용할 때보다 피로도도 크거든요 그리고 모바일 유저들 대다수는 직장인들로 게임에 많은 시간 투자를 못하지만 사냥을 통해서 성장을 계속 하고 싶어했죠 전투의 재미를 느끼는 것보다 본인의 캐릭터가 강해지기를 원하다보니 개발자들도 이를 알아채고 "자동 전투" 시스템이라는 어마어마한 파장을 일으킬 시스템을 만들어냅니다. 자동 전투는 몬스터를 한 마리 한 마리 정성껏 잡아대던 전투와는 다르게, 버튼 하나만 누르면 자동으로 공격하고 스킬을 사용하며 몬스터를 사냥하죠. 그..
[2일차] 왜 캐릭터의 전투/비전투 상태 체크가 필요한걸까? Reference ① 메이플스토리 전투 시스템이 있는 게임을 플레이하다보면, 전투 상태를 체크하는 경우를 자주 볼 수 있습니다. 오늘 레퍼인 메이플스토리의 경우 마지막 전투 이후 5초 정도 전투 상태 유지를 하고, 숨을 헐떡이는 듯한 애니메이션을 실행하죠. 그리고 비전투 상태 즉, 평화 상태로 복구되어 기본 Idle 애니메이션을 실행합니다. 다른 전투 기획서들을 볼 때, 캐릭터 상태를 전투/비전투 상태로 구분하는 것을 종종 볼 수도 있죠. 그럼 왜?? 캐릭터 상태를, 그것도 전투 중인 지를 주기적으로 체킹하는걸까요? 여러 의도를 생각해봤습니다! 전투의 집중 (유저 편의성) 2000년대 초반 게임을 생각해봤을 때, 전투 상태를 체킹하는 것은 유저..
[1일차] 왜 프롬식 소울라이크에서는 HP 수치를 실시간으로 보여주지 않을까? Reference ① Elden Ring ② P의 거짓 ③ 메이플스토리 ④ 로스트아크 프롬소프트의 소울 게임들과 프롬식 소울라이크 게임을 플레이하다보면, HP를 보여주는 방식이 다른 게임들과는 다르게 조금 특별하다는 것을 알 수 있습니다. 바로, 전투 중에 MaxHP와 CurrentHP를 수치적으로 보여주지 않고 그래픽으로만 보여준다는 점입니다. 또한 캐릭터를 성장시켜 HP 관련 파라미터를 올리면, HP Bar의 길이를 늘리는 것으로 표시하죠. 물론 캐릭터 스탯창에서 구체적인 수치를 확인할 수 있지만, 스탯 창은 화면을 전부 가리는 팝업이기에 전투하면서 확인하는 것은 사실상 불가능합니다. 캐릭터가 몬스터를 공격할 때는 데미지가..
INTRO VR 전시 프로젝트를 진행하면서 5분 동안 유저의 이동이 없을 때 시작 Scene으로 이동하는 기능을 개발하게 되었다. 기존 Input System을 이용한다면 UnityEngine 내부에 있는 Input.anyKeyDown을 이용하면 간단히 구현할 수 있지만, XR Interaction Toolkit Package를 사용하면서 새로운 Input System에 대해서는 작동하지 않았다. 그래서 transform.position과 Coroutine을 이용하여 Input System없이 간단하게 구현해보았다. CONTENT 먼저, TimeSceneChagne.cs의 전체 코드는 아래와 같다. using System.Collections; using System.Collections.Generic;..
UnityEngine 내 Color를 사용할 때 주의해야할 점이 있다. 드로잉 월드를 제작하면서 로컬이 색깔을 선택하고 서버로 보낼 때, 선택한 색깔의 r,g,b,a 값을 number로 보냈다. 서버에서는 받은 data를 로컬을 제외한 다른 플레이어에게 보내며, 데이터를 받은 다른 플레이어들은 Color을 아래와 같이 설정했었다. Connector.Instance.DrawStartRes = (data: { sessionId: string; lineWidth: number; color_r: number; color_g: number; color_b: number; color_a: number; }) => { const line = Manager.Resource.Instantiate("Prefabs\\Lin..
유니티에서 옵저버 패턴을 사용하여 프로그래밍한 것은 매우 중요한데, 만약 두 개의 컴포넌트가 서로의 정보(변수, 메서드 등)를 공유해야하는 상황에서 서로 결합(tightly-coupled)되어있다면, 서로가 영향을 미치기에 하나의 컴포넌트를 수정하면 다른 컴포넌트에서 에러가 발생하기에 수정에 불리하다. 이는 객체지향 원칙에 걸맞지 않는 상황인 것이다. 디자인 패턴 중 옵저버 패턴(Observer Pattern)은 시스템을 확장성(Scalable), 유지성(Maintainable), 비결합성(Loosely-coupled) 모두를 충족하게 만들어준다. OOP 코드를 작성할 때, 비결합(Decoupled)으로 코드를 작성해야 에러가 날 확률도 적고 모듈화하기도 쉬우며, 디버깅하기도 쉽다. 아래 코드는 싱글톤 ..
INTRO Unity AI Navigation을 이용하여 플레이어를 추적하는 몬스터 시스템을 Tag를 이용하여 구현하던 도중, 동일한 Tag의 플레이어가 다수일 경우 몬스터는 어떤 플레이어를 우선순위로 따라갈지 궁금해졌다. 여러 테스트를 통해 우선순위 기준이 Tag라는 시스템에 있었다는 것을 알았고, 그 과정에 대해 적어보려고 한다. CONTENT 우선 몬스터 Control에 대한 기본적인 코드를 첨부하면 아래와 같다. using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class MonsterCtrl : MonoBehaviour { private Transform..
INTRO Unity3D를 학습하다보면 이동(Translate)과 회전(Rotation)을 배우게 되는데, 이 때 보간법(Interpolation)을 배우게 된다. 원하는 시작 지점과 끝 지점 사이에 원하는 함수를 사용하여 함숫값이나 근삿값을 구하는 방법이다. 가장 기초적으로 배우는 보간법은 바로 선형 보간법(Linear Interpolation), Lerp이다. 말 그대로 선형, 직선 함수를 사용하여 두 지점 사이에 함숫값을 구하는 보간법인데, 실제로 유니티에서 구현하다보면 선형으로 변하는게 아닌 곡선으로 값이 나올 때가 있다. 의도적으로 그런 효과를 원한다면 괜찮겠지만, 선형(직선) 보간법을 사용한만큼 선형적으로 변해야만 정확하게 사용한 것이다. 언제 그렇고, 어떻게 코드를 작성하면 그런지, 그리고 ..
Base Equippable Actor Class : Implement functionality inside the base equippable actor that you want all equippable items to inherit. - Equip/Unequip functionality - Attach functionality 즉, 장착/미장착 여부와 장착 시 손에 붙이는 가장 베이스 역할을 한다. 아래 클래스들은 이 클래스를 상속받아서 실행한다. Base Weapon Actor Class : Inherits functionality of base equippable so that the functionality can be accessed or overriden. Implement function..
INTRO 언리얼 엔진 5의 Lighting을 학습하던 중 학습하면서, 이전 버전의 언리얼 엔진에서 사용한 Lighting과 Lumen을 비교하여 어떤 장단점이 있는 지 알아보았다. 그 전에 Lumen에 대하여 간단히 살펴보자면, 언리얼 엔진의 Global Illumination과 Reflection에서 추가된 기술로, 미리 Light을 Bake하여 Lightmap을 이용하는 방식이 아닌, Fully Dynamic Realtime Lighting 시스템이다. GPU 연산을 줄이기 위해, 대부분 Static Light로 사용할 수 밖에 없었던 이전과는 다르게 이제는 빛이 움직여도 실시간으로 랜더링되며 이전보다 퀄리티도 좋아지고 연산량도 줄어들게 되었다. 위와 관련된 내용을 직접 UE5의 Level에서 세팅..