Unity/온라인 RPG

테스트 영상지금까지 약 4개월간 제작한 게임에 대한 테스트 영상이다.https://youtu.be/Ayq_w8Nptmc?feature=shared 유저는 약 1000명 까지는 무리 없이 동작하는 모습을 보였고, 아직 전투에 대한 긴박함은 없지만 RPG 게임에서의 필수적인 요소들은 전부 구현하고 최적화해봤다고 생각한다.얻은 것클라이언트 개발자로 공부를 해오면서 클라이언트를 잘 이해하기 위해서라도 서버에 대한 지식이 필수적이라는 생각이 들어, 온라인 게임을 직접 제작해 보았다. 이 과정에서 단순한 기술 시연을 위한 기능보다 네트워크, 운영체제, 데이터베이스 등 다양한 컴퓨터 과학(CS) 지식이 매우 중요하다는 것을 깨달았다. 개발은 데스크탑과 노트북을 번갈아 가며 진행했는데, 특히 노트북에서 로컬 서버와 유..
RPG 게임에서 보면 필수적으로 있는 것중 하나인 유저들간의 대화이다.대부분의 경우 채팅을 통해 의사소통을 하곤한다.따라서, 채팅을 한번 구현해보자. 채팅의 경우 서버의 역할이 따지고보면 크게 없다 그냥 어떤 플레이어가 어떤 말을 했는지 브로드캐스트 해주는 것이기 때문이다. 물론 전체채팅이나 유저가 매우 많을 경우 최적화가 반드시 필요할 것이다. 이유는 플레이어의 움직임 동기화랑 같은 맥락이다.따라서 필자는 주변에 있는 플레이어들만 대화할 수 있게 구성한다. 채팅 UI검정 배경에 채팅들이 쌓일 것이며 전송을 통해 내가 친 채팅을 보낼 수 있다.물론 InputField에 포커싱에 되어있을 경우엔 엔터를 통해서 포커싱할 수 있으며, 포커싱이 되어 있는 중에는 플레이어의 키 입력을 전부 막는다.(인벤 열기 등..
지난 포스팅에서는 퀘스트를 수락하고 진행과정을 추적하며 클리어하는 시스템을 구축해봤다.이제 퀘스트를 DB에 저장해서 플레이어가 로그인할 때, 퀘스트를 불러와보자.Quest DB 모델[Table("Quest")]public class QuestDb{ public int QuestDbId { get; set; } public int TemplateId { get; set; } public bool IsFinish { get; set; } public bool IsCleard{ get; set; } public int QuestType { get; set; } public ICollection Goals { get; set; } [ForeignKey("Player")] ..
이전 포스팅에서 더이상 컨텐츠를 개발하지 않고 마무리 하기로 했으나, Rpg 게임에서 퀘스트 시스템을 만들지 않는건 예의가 아닌것 같아 퀘스트까지만 만들기로 했다.퀘스트 시스템 흐름 분석퀘스트를 획득하는 시스템을 구상할 때 흐름을 분석해보자.클라이언트 플레이어가 퀘스트 Npc에게 퀘스트를 수락 받음.서버쪽으로 플레이어가 퀘스트를 수락했다고 보냄.실제로 그 Npc가 해당 퀘스트를 가지고 있는지 검증(위치 포함)문제가 없다면 서버쪽 플레이어에게 퀘스트를 추가.그리고 클라이언트 플레이어에게 정상적으로 퀘스트가 추가됐으니 알려줌.클라이언트 플레이어의 퀘스트 매니저에 추가하고 퀘스트 UI 등을 업데이트 해줌.요런 흐름을 가지고 있다. 그렇다면 퀘스트 진행사항을 추적하는 경우는 어떻게 할까?각 퀘스트 타입에 맞는 ..
사운드를 직접 제작하거나 할 수 없기때문에 최대한 저작권 없는 무료 소스들만을 가지고 사운드를 넣어봤다.그래서 원하는 사운드를 구하지 못해 보스전에서의 사운드는 많이 없는 상태이다.이 외에도 추가적인 사운드 들이 존재한다.이것들을 관리하기 위해 사운드 매니저를 만들어준다.SoundManagerusing System.Collections;using System.Collections.Generic;using UnityEngine;public class SoundManager{ AudioSource[] _audioSources = new AudioSource[(int)Define.Sound.MaxCount]; Dictionary _audioClips = new Dictionary(); Dict..
보스 패턴 정하기보스의 패턴을 만드는 방법에는 다양한 방법들이 존재한다.가령 현재 상태에따라 행동을 정한다던지 우선도를 따져서 공격한다던지 등 여러 방법을 통해 구현할 수 있다. 나는 현재 드래곤이 고정형 보스(위치가 변하지 않는 형태)이기에 자신한테 가장 데미지를 많이 입힌 플레이어(위협적인 플레이어)를 선정해 그 플레이어의 위치에 따른 다양한 공격을 하려고한다. 다음과 같은 형태를 가진다.플레이어가 어느 영역에 있는지 판단해 해당 구역을 공격하는 시스템으로 만들 것이다. 따라서 원정대에서 가장 강력한 사람이 어그로를 끌게 되고 그것에 맞춰 공략해야하는 시스템이다. 위 시스템상 한명이 어그로를 독식하고 특정 패턴만 유도한 상태에서 다른 원정대원들이 공격하는 꼼수?를 노릴 수 있지만 드래곤의 어그로는 가..
보스 Scenerpg의 하이라이트라고 할 수 있는 보스 원정대를 만들어보자.일단 먼저 보스가 존재하는 Scene을 따로 분리해서 만들어 줄 것이다. 아무리 오픈월드라고 해도 보스가 있는 곳은 연산 때문에 분리하는게 좋다고 판단했다.대신 보스는 제자리 고정형으로 구성되기 때문에 데디 서버를 이용할 필요는 없을 것이다.맵은 던전 느낌이 나도록 구성한 에셋을 이용했다.밑에 지형에 보스랑 전투를 할 것이고 위 지형에는 보상을 얻는 장소로 사용할 것이다.시네머신 Timeline을 이용해 컷신도 만들어 볼 것이다. 보스 몬스터의 경우는 드래곤으로 결정했다.(역시 rpg는 드래곤이지)컷신보스 컷신은 이런식으로 구성되어 있다.시네머신을 처음 사용해서 약간의 어색함이 존재하지만 크게 어렵지는 않아서 충분히 연습하면 잘 ..
단연코 지금까지 작성한 모든 포스팅중 가장 어려웠다고 말할 수 있다. 지금까지 본인은 최적화를 신경쓰지 않고 맘 편하게 맵에 존재하는 모든 몬스터 정보를 긁어온다던가 플레이어를 찾아 작업을 한다던가 등 비용이 큰 작업을 시원시원하게 하고있었다. 이를 계속하다보니 서버가 슬슬 메모리가 쌓여 버거워하는 모습을 볼 수 있었다.(노트북으로 해서 그런것도 있음...) 그래서 마음먹고 클라이언트와 서버를 최적화 해보겠다. 클라이언트는 오브젝트 풀링으로 서버는 Zone과 VisionCube라는 개념을 도입해서 해결한다.클라이언트 최적화사실 지금까지 작업이 이펙트가 많은것도 아니고 수 많은 객체들이 Spawn되거나 하는것이 아니여서 클라이언트는 무리가 가지 않는다. 하지만 추후 미래를 바라봐서 만약 플레이어가 1000..
이번 포스팅은 Npc를 만들고 Npc와 상호작용을 했을 때, 상점을 열어보겠다.상점을 연 후에 마우스로 더블클릭하면 아이템을 구매하거나 판매할 수 있게 해보자.서버 작업은 사실 별게 없고 기존에 만들어둔 것과 비슷한 맥락이다.NPC 상호작용npc는 다음과 같은 캐릭터를 이용하겠다.이 npc에 충돌은 불가한 콜라이더를 추가해주고 플레이어가 상호작용 범위에 도달했을 때, space바를 누르면 npc 상점이 열리도록 해보자.밑은 MyPlayerController의 일부이다.public float interactionCooldown = 1.5f; private float lastInteractionTime = -1f; public void OnTriggerStay(Collider other){ if (ot..
이제 슬슬 막바지에 다다르고 있는 느낌이 든다.이번 포스팅에서는 아이템을 인벤칸 내에서 이동하는 코드를 작성해보자.아이템 드래그 추가적인 처리아이템 드래그를 해서 이제 큇슬롯에 등록하는 거를 아이템 드래그의 마지막에서 했다.이제 이것을 추가적인 처리를 해주어야한다._icon.gameObject.BindEvent((e) =>{ if (itemData == null) return; if (dragObj == null) return; Managers.Resource.Destroy(dragObj); string name = e.pointerCurrentRaycast.gameObject.name; if (name == null) return; // 아이템 창끼리 인벤 교환 i..
Mintriever
'Unity/온라인 RPG' 카테고리의 글 목록