이미지 드래그 하기우리가 흔히 rpg 게임에서 보면 아이템, 스킬 등의 아이콘을 드래그 할 수 있다. 드래그 했을 경우 아이템이 반투명하게 딸려오게되고 특정 행동을 할 수 있게된다.우리가 할 최종 목표는 아이템이나 스킬등을 드래그해서 큇슬롯에 등록하고 사용해보도록 하자. 일단 먼저 이미지를 드래그하기 위한 이벤트를 바인드 해주어야한다._icon.gameObject.BindEvent((e) =>{ if (itemData == null) return; dragObj = Managers.Resource.Instantiate("UI/UI_DragObj"); dragIcon = Util.FindChild(dragObj, "Icon"); if (dragIcon == null) return; ..
Unity/온라인 RPG
아이템을 착용해봤으니 이제 가지고 있는 스탯 포인트를 이용해 스탯을 찍고 공격력을 높이는 작업을 해보자.흐름StatUI 에서 원하는 스탯의 상승 버튼을 누르면 상승 요청 패킷을 보낸다.서버에서 각종 검증(실제로 올릴 수 있는 스킬 포인트가 있는지 등)한 후 스탯을 올리고 스탯의 종합적인 정보를 클라에게 전달해준다. 이는 브로드캐스트가 아닌 본인 한명에게만 보낸다.받은 클라이언트는 결과 값을 자신의 실제 Stat에 적용한다.스탯 상승 요청GetButton((int)Buttons.StrUpButton).gameObject.BindEvent((e) => { MakeChagneStatPacket("Str"); });GetButton((int)Buttons.DexUpButton).gameObject.BindEve..
이전 포스팅에서는 몬스터를 처치하면 확률에 따른 드랍테이블로부터 아이템을 획득할 수 있었다.이제 획득한 아이템을 장비에 착용해보자.아이템 착용하기 흐름간단하게 흐름을 알고가자.인벤토리에 존재하는 아이템을 클릭 시 착용 요청 패킷을 보냄. 패킷의 내용은 어떤 아이템인지(DbID), 누가 착용 요청을 했는지를 포함한다.패킷을 받은 서버는 아이템을 착용하기 위해 다양한 로직을 검수한다.착용 요청한 장비와 같은 부위를 착용하고 있다면 착용중인 장비를 인벤토리로 옮긴다.그리고 그 결과를 DB 쓰레드에 넘겨주고 클라이언트에게 장비 해제 패킷을 보낸다.마지막으로 착용 요청 받은 장비를 Equip 장비에 추가하고 인벤에서 제거한다. 이 역시DB 쓰레드에게 넘겨주고 패킷을 만들어 클라에게 알려준다.패킷을 받은 클라이언트..
이번 포스팅은 몬스터가 사망했을 때, 일정확률로 아이템을 드랍하고 플레이어가 주워 인벤에 넣는 과정을 설명한다.흐름전체적은 플로우는 다음과 같다.몬스터가 공격을 받았을 때(서버에서 처리), Hp가 0 이하인지 체크한다.Hp가 0 이하라면 몬스터마다 가지고 있는 드랍 정보 중 하나를 랜덤하게 가져온다.(null 포함)null이 아닐 경우 ObjectManager에 가져온 DropItem을 추가한다.DropItem을 필드에 Spawn한다. Spawn은 Player나 Monster와 같이 동일하게 진행된다.Spawn 패킷을 받은 모든 클라이언트는 받은 위치에 DropItem prefab을 생성한다.플레이어의 콜라이더가 DropItem의 콜라이더하고 트리거 중일 때, z 키를 누르면 획득 패킷을 서버로 보낸다...
지난 포스팅까지는 플레이어와 몬스터간의 전투까지 진행했다.이제 몬스터가 죽은 후 아이템을 떨구면 플레이어가 습득하는 과정이 필요한데 이를 위해서 먼저 Inventory창이 필요할거 같아 먼저 제작한다.Inven을 만드는 김에 각종 다른 UI 까지 동시에 제작해보자.InventoryUI인벤토리의 구성은 창을 드래그할 수 있는 Title과 아이템들을 담을 수 있는 Grid 그리고 골드로 구성되어 있다.여기에 나와있는 값들은 전부 서버에서 데이터를 긁어와서 채워주어야만 한다.using System;using System.Collections;using System.Collections.Generic;using System.Linq;using UnityEngine;public class UI_Inventory ..
지난 포스팅에 이어서 10일 정도의 시간이 흘렀는데 몬스터 로직을 구성하는데 생각보다 많은 시간을 써서 이제야 포스팅하게 됐다.전투 시스템(플레이어)플레이어의 공격은 대체적으로 이전 포스팅 중 다뤘었다. 그 중 실제 타격만 제외하고 구성했었는데 실제로 타격하는 코드를 작성해보자.이전과 달라진 점이 있다면 공격 모션과 실제 타격을 분리했다는 점이다.공격마다 특정한 모션이 있을 거고 실제 타격되는 시점이 존재할 것이다. 그렇기 때문에 실제 칼을 휘두르는 모션 패킷 따로 데미지를 입히는 패킷 따로 보내는 형식으로 수정했다.public void OnClickMouseInputEvent(){ _moveTime += Time.deltaTime; if (Input.GetMouseButton(1) && _m..
몬스터 움직임몬스터 움직임에대해 처리하기 위한 방법을 꽤나 많이 고민했다.우리는 플레이어의 움직임을 처리할 때, 서버에서 길 찾기를 하지 않고 Unity NavMesh의 도움을 받아 서버에서 좌표에 대한 검증만 하고 실질적인 길 찾기는 본인에게 맡기고 있었다. 그 이유는 아무래도 개인 노트북이나 pc로 하기에 서버에 대한 연산량을 줄이고, 길찾기를 위한 맵에 정보를 추출하지 않아도 된다는 이점이 있기 때문이었다.여기까지는 문제가 되지 않을 수 있다. 하지만, 몬스터는 다르다. 우리가 위의 방법을 할 수 있었던 이유는 플레이어 당 한개의 클라이언트라는 보장이 있었기 때문에 길 찾기를 떠넘길 수 있었다. 그렇다면 몬스터의 길 찾기는 누가해줘야할까?당연히 현실에 존재하는 모든 rpg 게임은 서버쪽에서 연산을 ..
애니메이션 동기화 이번 포스팅에서는 캐릭터의 공격을 만들고 애니메이션을 동기화 해보자. 기획상의 문제긴 하지만 나는 마우스 왼쪽 클릭을 하면 일반 공격 2종 중 하나가 랜덤하게 나가는 방향으로 정했다. 스킬같은 경우도 애니메이션이 있지만 이는 나중에 처리할 예정이다. 기존에 있던 MouseInput을 받아주는 곳에 코드를 추가해준다. public void OnClickMouseInputEvent() { _moveTime += Time.deltaTime; if (Input.GetMouseButton(1) && _moveTime >= 0.3f) { if (State == CreatureState.Skill) return; Ray ray = cm.ScreenPointToRay(Input.mousePositio..
캐릭터 이동 동기화 rpg 게임에서 꽃이라고 할 수 있는 캐릭터 이동 동기화를 맞춰보겠다. 지난 포스팅에 작성한 맵이 쉐이더 문제로 다른 맵으로 교체하고 새로 bake 해줬다. 이동 동기화의 순서는 다음과 같다. 클라이언트 A가 이동을 원하는 위치 vector를 서버에게 C_Move 라는 패킷으로 보낸다. C_Move 패킷을 받은 서버는 그 위치가 올바른 위치인지 판단하고 올바르지 않다면 S_Banish 패킷을 보낸다. 만약 올바른 위치라면 이동하는 좌표와 ObjectId를 포함한 S_Move 패킷을 모든 플레이어에게 Broadcast 한다. S_Move 패킷을 받은 클라이언트 A, B 등 모든 플레이어는 움직임을 원하는 object를 Id를 통해 찾아낸다. 찾아낸 객체를 _agent.SetDestina..
맵 맵 같은 경우에 미적 감각이 전혀 없는 나로서는 Terrain의 사용법만 익히고 에셋을 통해 제작하였다. 기본적인 초원과 물, 나무로 이루어져있다. Navigation 내비게이션은 유니티에서 제공하는 길 찾기 ai이다. 자세한 내용은 유니티 포럼에서 찾을 수 있는데 여기서는 가볍게 어떻게 사용하고자 하는지에 대해 알아보자. 내비게이션은 2022 이후 버전과 이전 버전으로 나뉜다. 이전 버전이 자료가 훨씬 많고 많은 사람들이 이용하고 있다. 필자는 2022 이후 버전을 다뤄볼 계획이다. 오른쪽에 있는 것이 2022 이전버전이고 왼쪽에 있는 것이 신 버전이다. 메뉴만 봐도 2개의 창이 줄어들었으며 특히 제일 중요한 Bake가 없어진 것이 특이점이다. Bake란 길 찾기를 위해 필드에 존재하는 mesh를 ..