C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Server API

ChaYong 2023. 12. 24. 13:04

◎ Rookiss님의 [  C#과 유니티로 만드는 MMORPG 게임 개발 시리즈 ] 관련한 Server API 

- 본 내용은 PC에서 보실 것을 권장해요 -

 

이번에는 rookissGDF에서 서버에서 사용하는 프로퍼티나 함수에 대해서 알아보도록 할게요. 클라이언트는 Managers와 같은 녀석이 있어서 코드 어디에서든 원하는 기능을 긁어와서 사용 할 수 있었지만 서버는 조금 달라요. 때문에 특정 프로퍼티나 함수는 특정 코드 구역 내에서만 사용이 가능해요. 즉 이를 사용하기 위해서는 서버구조를 어느정도 이해를 하고 있어야 사용이 가능하다는 말이에요. 서버구조에 어느정도 익숙해 지신 분들이 코드작성 중 특정 함수들이 기억이 잘 나지 않을때에 아래에 기재된 내용을 사전 같은 느낌으로 사용하시면 좋을 것 같습니다. 


1. 컨피규 매니저

rookissGDF에서는 추후 수정이 편하도록게 파일경로, DB커넥션스트링에 대하여 따로 Json파일로 관리하고 있어요

 

ConfigManager.LoadConfig() : Json파일을 메모리에 올리기

ConfigManager.Config.dataPath : Data폴더의 경로를 가져오기

ConfigManager.Config.connectionString : DB접속문자열을 가져오기


2. 데이타 매니저

클라이언트와 비슷하게 플레이어, 몬스터 등의 데이터시트 정보를 외부 Json파일로 관리를 하죠? 이를 메모리로 올려두었다가 쉽게 그 정보를 가져다 쓰기 위해 만든 매니저에요.

 

DataManager.LoangData() : StatData.json 등 외부 json파일 정보를 메모리에 올리기

DataManager.StatDict : 스탯정보가 담긴 딕셔너리 (키:레벨, 값:스탯정보)

DataManager.SkillDict : 스킬정보가 담긴 딕셔너리 (키:데이터시트번호, 스킬정보)

DataManager.ItemDict : 아이템정보가 담긴 딕셔너리 (키:데이터시트번호, 아이템정보)

DataManager.MonsterDict : 몬스터정보가 담긴 딕셔너리 (키:데이터시트번호, 몬스터정보)


3. DB 관련

우선 rookissGDF에서 우리가 DB관련 함수를 만들어 둔 것부터 적어볼게요.

 

DbTransaction.Instance.SavePlayerStatus_AllInOne(Player p, GameRoom r)

: 플레이어의 현재 HP값을 DB에 저장(함수 하나에서 처리)

DbTransaction.Instance.SavePlayerStatus_Step1(Player player, GameRoom room)

: 플레이어의 현재 HP값을 DB에 저장(함수를 3개로 나누어 처리)

DbTransaction.Instance.RewardPlayer(Player player, RewardData rewardData, GameRoom room)

: 플레이어에게 아이템 보상(DB저장+서버메모리에 아이템추가)

DbTransaction.Instance.EquipItemNoti(Player player, Item item)

: 플레이어의 특정 아이템의 장착상태를 변경

 

그런데 이것만 가지고는 앞으로 컨텐츠 만드는 작업을 진행하실 수가 없으실 거에요. 분명 추가적인 함수를 만들 필요가 생기실 할거에요. 이를 위해 DB를 조작하는 방식에 대하여 조금 더 정리를 해보았어요.

 

일단 현재 DB의 구조를 간략하게 보고 갈게요. rookissGDF에서 사용하는 DB는 총 3개에요.

  • AccountDB : Account테이블  
  • GameDB : Account테이블, Player테이블, Item테이블
  • SharedDB : Token테이블, ServerInfo테이블

 

AccountServer에서는 AccountDB와 SharedDB에 접근이 가능하구요. GameServer에서는 GameDB와 SharedDB에 접근이 가능해요. 그리고 각 DB서버는 각각마다 테이블들을 가지고 있었는데요. 테이블은 쉽게 이해하시자면 엑셀에서 시트를 연상하시면 되요. 

 

AccountServer에서 Db에 새로운 행을 [추가]하는 방법은 아래와 같아요.

// AccountDB의 Account테이블에 새 계정 추가
AccountDb newAccount = new AccountDb()
{
    AccountName = "계정명",
    Password = "비밀번호"
}
_context.Accounts.Add(newAccount);
_context.SaveChangesEx();

// SharedDB의 Token테이블에 새 토큰 추가
TokenDb tokenDb = new TokenDb()
{
    Token = new Random().Next(Int32.MinValue, Int32.MaxValue),
    Expired = DateTime.UtcNow.AddSeconds(600)
};
_shared.Add(tokenDb);
_shared.SaveChangesEx();

// SharedDB의 ServerInfo테이블에 새 서버정보 추가
ServerDb serverDb = new ServerDb()
{
    Name = "서버이름",
    IpAddress = "127.0.0.1",
    Port = 7777,
    BusyScore = 0
};
_shared.Servers.Add(serverDb);
_shared.SaveChangesEx();

 

GameServer에서 Db에 새로운 행을 [추가] 하는 방법은 아래와 같아요.

// GameDB의 Account테이블에 새 계정추가
using(AppDbContext db = new AppDbContext())
{
     AccountDb newAccount = new AccountDb()
    {
        AccountName = "7777777"
    };
    db.Accounts.Add(newAccount)
    db.SaveChangesEx();
}

// GameDB의 Player테이블에 새 플레이어 추가
using(AppDbContext db = new AppDbContext())
{
    PlayerDb newPlayerDb = new PlayerDb()
    {
        PlayerName = "플레이어이름",
        Level = 1,
        Hp = 100,
        MaxHp = 100,
        Attack = 10,
        Speed = 1,
        TotalExp = 0
    };
    db.Players.Add(newPlayerDb);
    db.SaveChangesEx();
}

// GameDB의 Item테이블에 새 아이템 추가
using (AppDbContext db = new AppDbContext())
{
    ItemDb itemDb = new ItemDb()
    {
        TemplateId = 1,
        Count = 1,
        Slot = 1, // 슬롯 번호가 겹치지 않게 주의
        OwnerDbId = 1 // PlayerDbId
    };
    db.Items.Add(itemDb);
    db.SaveChangesEx();
}

// SharedDB의 Token테이블에 새 토큰 추가
using(SharedDbContext shared = new SharedDbContext())
{
    TokenDb tokenDb = new TokenDb()
    {
        Token = new Random().Next(Int32.MinValue, Int32.MaxValue),
        Expired = DateTime.UtcNow.AddSeconds(600)
    };
    shared.Tokens.Add(tokenDb);
    shared.SaveChangesEx();
}

// SharedDB의 ServerInfo테이블에 새 서버정보 추가
using (SharedDbContext shared = new SharedDbContext())
{
    ServerDb serverDb = new ServerDb()
    {
        Name = "서버이름",
        IpAddress = "127.0.0.1",
        Port = 7777,
        BusyScore = 0
    };
    shared.Servers.Add(serverDb);
    shared.SaveChangesEx();
}

 

다음은 DB에 있는 정보를 긁어오는 방법이에요

 

먼저 AccountServer에서 DB 특정 행을 [검색]하는 방법은 아래와 같아요.

// AccountDB의 Accout테이블에서 특정 아이디와 특정 비밀번호에 해당하는 계정 로드
AccountDb account = _context.Accounts
		.Where(a => a.AccountName == "특정아이디" && a.Password == "특정비밀번호")
		.FirstOrDefault();
    
// SharedDB의 Token테이블에서 특정 AccountId에 해당하는 토큰 로드
TokenDb tokenDb = _shared.Tokens
		.Where(t => t.AccountDbId == 특정어카운트ID)
		.FirstOrDefault();
    
// SharedDB의 ServerInfo테이블에서 특정서버명에 해당하는 행을 불러오기
ServerDb serverDb = _shared.Servers
		.Where(s => s.Name == "특정서버명")
		.FirstOrDefault();

 

GameServer에서 DB 특정 행을 [검색]하는 방법은 아래와 같아요.

// GameDB의 Account테이블에서 어카운트네임이 777777에 해당하는 계정 로드
using(AppDbContext db = new AppDbContext())
{
    AccountDb findAccount = db.Accounts
        .Include(a => a.Players) // Player포함해서
        .Where(a => a.AccountName == "777777")
        .FirstOrDefault();
}
            
// GameDB의 Player테이블에서 특정플레이어명으로 플레이어 정보 로드
using(AppDbContext db = new AppDbContext())
{
	PlayerDb findPlayer = db.Players
        .Where(p => p.PlayerName == "특정플레이어명")
        .FirstOrDefault();
}

// GameDB의 Item테이블에서 아이템 주인님의 PlayerDbId가 77인 아이템 정보 로드
using(AppDbContext db = new AppDbContext())
{
	ItemDb findItem = db.Items
        .Where(i => i.OwnerDbId == 77)
        .FirstOrDefault();    
}

// SharedDB의 Token테이블에서 특정 AccountId에 해당하는 토큰 로드
using(SharedDbContext shared = new SharedDbContext())
{
    TokenDb tokenDb = shared.Tokens
        .Where(t => t.AccountDbId == 특정어카운트ID)
        .FirstOrDefault();
}

// SharedDB의 ServerInfo테이블에서 특정서버명에 해당하는 행을 불러오기
using(SharedDbContext shared = new SharedDbContext())
{
    ServerDb serverDb = shared.Servers
        .Where(s => s.Name == "특정서버명")
        .FirstOrDefault();
}

 

Db에 특정값을 [수정]하는 방법은 두 가지에요. 우선 위의 [검색] 방식으로 긁어온 정보에서 일부 값을 수정하고 db.SaveChangesEx()를 빵 때려주면되지만 이럼 db접근 2회라는거... 이 때문에 Disconnected(디스커넥티드) 상태로 [수정]하는 코드를 적어둘게요. 물론 이를 사용하려면 DbId를 알아야 하는 거 아시죠? ㅎㅎ

 

AccountServer에서 디스커넥티드 상태에서 Db의 특정 값을 [수정]하는 방법이에요.

 

// AccountDB의 Account테이블에서 특정 Account의 비밀번호 바꾸기
AccountDb changeAccount = new AccountDb()
{
    AccountDbId = 수정을 원하는 어카운트DbId,
    Password = "변경된 비밀번호"
}
_context.Entry(changeAccount).State = EntityState.Unchanged;
_context.Entry(changeAccount).Property(nameof(changeAccount.Password)).IsModified = true;
_context.SaveChangesEx();


// SharedDB의 Token테이블에서 특정 Token의 만료기간 변경하기
TokenDb changeTD = new TokenDb()
{
    TokenDbId = 수정을 원하는 토큰DbId,
    Expired = DateTime.UtcNow.AddSeconds(600)
};
_shared.Entry(changeTD).State = EntityState.Unchanged;
_shared.Entry(changeTD).Property(nameof(changeTD.Expired)).IsModified = true;
_shared.SaveChangesEx();

// SharedDB의 ServerInfo테이블에서 특정 서버정보의 포트번호 변경하기
ServerDb changeSD = new ServerDb()
{
    ServerDbId = 수정을 원하는 서버DbId,
    Port = 8888,
};
_shared.Entry(changeSD).State = EntityState.Unchanged;
_shared.Entry(changeSD).Property(nameof(changeSD.Port)).IsModified = true;
_shared.SaveChangesEx();

 

GameServer에서 디스커넥티드 상태에서 Db의 특정 값을 [수정]하는 방법이에요.

// GameDB의 Account테이블에서 특정 어카운트의 이름을 어카운트 네임을 수정
using(AppDbContext db = new AppDbContext())
{
     AccountDb changeAccount = new AccountDb()
    {
    	AccountDbId = 수정을 원하는 어카운트DbId
        AccountName = "7777777"
    };
    db.Entry(changeAccount).State = EntityState.Unchanged;
    db.Entry(changeAccount).Property(nameof(changeAccount.AccountName)).IsModified = true;
    db.SaveChangesEx();
}

// GameDB의 Player테이블에서 특정 플레이어의 토탈 경험치 값을 수정
using(AppDbContext db = new AppDbContext())
{
    PlayerDb changePD = new PlayerDb()
    {
        PlayerDbId = 수정을 원하는 플레이어DbId,
        TotalExp = 99999
    };
    db.Entry(changePD).State = EntityState.Unchanged;
    db.Entry(changePD).Property(nameof(changePD.TotalExp)).IsModified = true;
    db.SaveChangesEx();
}

// GameDB의 Item테이블에 특정 아이템의 주인님을 바꾸기
using (AppDbContext db = new AppDbContext())
{
    ItemDb changeID = new ItemDb()
    {
        ItemDbId = 1,
        OwnerDbId = 2 // 바뀔 주인님의 PlayerDbId
    };
    db.Entry(changeID).State = EntityState.Unchanged;
    db.Entry(changeID).Property(nameof(changeID.OwnerDbId)).IsModified = true;
    db.SaveChangesEx();
}

// SharedDB의 Token테이블에서 특정 Token의 만료기간 변경하기
using(SharedDbContext shared = new SharedDbContext())
{
    TokenDb changeTD = new TokenDb()
    {
        TokenDbId = 수정을 원하는 토큰DbId,
        Expired = DateTime.UtcNow.AddSeconds(600)
    };
    shared.Entry(changeTD).State = EntityState.Unchanged;
    shared.Entry(changeTD).Property(nameof(changeTD.Expired)).IsModified = true;
    shared.SaveChangesEx();
}

// SharedDB의 ServerInfo테이블에서 특정 서버정보의 포트번호 변경하기
using (SharedDbContext shared = new SharedDbContext())
{
    ServerDb changeSD = new ServerDb()
    {
        ServerDbId = 수정을 원하는 서버정보DbId,
        Port = 7777
    };
    shared.Entry(changeSD).State = EntityState.Unchanged;
    shared.Entry(changeSD).Property(nameof(changeSD.Port)).IsModified = true;
    shared.SaveChangesEx();
}

 

여기까지와보니 테이블을 만드는 생성하는 방법도 적어두는게 좋겠네요.

 

1. DataModels.cs에서 데이터를 정의한다.

[Table("Item")]
public class ItemDb
{
    public int ItemDbId { get; set; } // db상에서 고유id
     public int TemplateId { get; set; }
     public int Count { get; set; }
     public int Slot { get;set; }
     public bool Equipped { get; set; }
 
     [ForeignKey("Owner")]
     public int? OwnerDbId { get; set; }
     public PlayerDb Owner { get; set; }
}

 

2. AppDbContext.cs에서 DbSet을 선언

public DbSet<ItemDb> Items { get; set; }

 

3. 기존 Db에서 테이블 모두 삭제 후 패키지 관리자 콘솔에서 명령어 두 개 입력

add-migration tttttttt
update-database

 

이후에는 위에서 나온 것처럼 추가나 검색, 수정 등의 작업을 하시면 되겠어요.


4. Job 관련

rookissGDF에서 Job을 관리하는 녀석은 GameLogic, GameRoom, DbTransaction 에요. 이녀석들에게 Job을 밀어넣을 수 있어요.

 

Push(특정함수, 인자1...) : 특정 작업을 Job으로 밀어넣기. 람다식 사용가능. 특정함수에 인자가 있다면 그 인자들을 쭉 넣어줄 것 (현재는 최대 3개까지)

PushAfter(int 지연시간, 특정함수, 인자1...) : 특정 작업을 지연시간 후에 실행토록 Job으로 밀어넣기. 위와 같이 특정 함수에 인자가 있다면 그 인자들을 쭉 넣어줄 것 (현재는 최대 3개까지)

 

역시 예제를 하나 보여드려야..

GameRoom gameRoom = new GameRoom();

// 1) 즉시 잡큐에 담기( .Push(등록함수, 등록함수에 전달할 인자1, 등록함수에 전달할 인자2) )
gameRoom.Push(gameRoom.Init, mapId, 10); 

// 2) 10초 대기 후 잡큐에 담을 것을 예약
IJob job = gameRoom.PushAfter(10, gameRoom.Test, mapId, 10); 

// 3) 10초가 지나기 전 예약작업을 취소
// Cancel변수가 true일 경우만 해당 작업실행토록함으로써 예약취소효과!
job.Cancel = false;

5. 오브젝트 매니저

오브젝트 매니저는 서버에 접속한 플레이어들을 모두 들고 있어요. 게다가 싱글턴으로 되어있어서 어느 코드에서든 접근이 가능합니다.

 

ObjectManager.Instance.Add(플레이어) : 플레이어를 접속자 목록에 추가

ObjectManager.Instance.Remove(오브젝트 아이디) : 특정 플레이어를 접속자 목록에서 제거

ObjectManager.Instance.Find(조건) : 서버의 모든 플레이어 중 특정 조건의 플레이어를 검색하여 반환

ObjectManager.GetObjectTypeById(오브젝트 아이디) : 아이디에서 오브젝트 타입을 추출


6. 게임오브젝트

게임오브젝트는 플레이어, 몬스터, 화살(=projectile)의 조상님이에요. 당연히 플레이어, 몬스터, 화살도 이 게임오브젝트의 프로퍼티나 함수를 사용할 수 있어요.

 

ObjectType : 오브젝트타입

(GameObjectType.None, GameObjectType.Player, GameObjectType.Monster, GameObjectType.Projectile)

Id : 오브젝트 아이디 [UNUSED(1)][TYPE(7)][ID(24)]

Room : 현재 게임오브젝트가 들어있는 방

 

Info : ObjectInfo

Info.objectId : 아이디(int)
Info.name : 이름(string)
Info.posInfo : 위치정보(PositionInfo)
Info.statInfo : 스탯정보(StatInfo)

 

PosInfo : PositionInfo

PosInfo.State : 상태(CreatureState)
(CreatureState.Idle, CreatureState.Moving, CreatureState.Skill, CreatureState.Dead)
PosInfo.moveDir : 이동방향(MoveDir)
(MoveDir.Up, MoveDir.Down, MoveDir.Left, MoveDir.Right)
PosInfo.posX : x좌표(int)
PosInfo.posX : y좌표(int)

 

Stat : StatInfo

Stat.Level : 레벨
Stat.Hp : 현재Hp
Stat.MaxHp : 최대Hp
Stat.Attack : 기본 공격력
Stat.Speed : 이동속도
Stat.TotalExp : 누적경험치

 

TotalAttack : 종합 공격력 (스탯 공격력 + 아이템 방어력)

TotalDefence : 종합 방어력 (아이템 방어력)

Speed : 이동속도(float)

Hp : 현재 Hp(int)

Dir : 현재 방향(MoveDir)

State : 현재 상태(CreatueState)

CellPos : 현재 x,y좌표(Vector2Int)

 

GetFrontCellPos() : 1칸 앞 좌표가져오기

GetFrontCellPos(MoveDir dir) : 특정 dir방향으로 1칸 앞 좌표가져오기

GameObject.GetDirFromVec(Vector2Int dir) : 특정 Vector2Int형태를 MoveDir형태로 변환

GetOwner() : 화살, 마법의 경우는 시전자, 일반적인 플레이어나 몬스터는 자기자신을 가져옴

OnDamaged(GameObject attacker, int damage) : 데미지주기 가상함수

OnDead(GameObject attacker) : 죽이기 가상함수

 

이외에 가상함수 Update()가 있으며 상속받은 객체가 재정의해서 사용 가능해요.


7. 플레이어

 

플레이어는 게임오브젝트를 상속받아 사용하기 때문에 당연히 게임오브젝트의 함수와 변수를 사용가능해요. 아래는 그 외에도 사용할 수 있는 것들을 정리 해 두었어요

 

PlayerDbId : 플레이어 Db 고유 아이디 (int)

Session : 네트워크상 세션정보 (ClientSession)

 

Vision : 시야 정보 (VisionCube)

Vision.Owner : 비전큐브의 주인남 플레이어를 물기
Vision.GatherObjects() : 시야 범위 내의 플레이어, 몬스터, 화살 객체를 해쉬셋으로 반환 ( 값 : GameObject )
이외에 Update(), PerviousObjects가 있으나 이는 바전큐브 내부에서만 사용하고 있고 외부에서 호출시 로직 꼬일 우려있음

 

Inven : 인벤토리 정보 (Inventory)

Inven.Items : 인벤토리 아이템 목록 -> 딕셔너리로 관리

Inven.Add(Item item) : 특정 아이템을 인벤토리에 넣기
Inven.Get(int itemDbId) : 특정 itemDbId의 아이템을 긁어오기 -> Item타입으로 반환
Inven.Find(조건) : 특정 조건의 아이템 긁어오기 -> Item타입으로 반환
Inven.GetEmptySlot() : 빈 슬롯 가져오기

 

WeaponDamage : 장비된 무기 종합 공격력 (int)

ArmorDefence : 장비된 방어구 종합 방어력 (int)

TotalAttack : 종합 공격력(Stat.Attack + WeaponDamage) (int)

TotalDefence : 종합 방어력(ArmorDefence)

 

OnLeaveGame() : 게임에서 나가기

RefreshAdditionalStat() : 스탯재계산

 

이 외에도 HandleEquipItem(C_EquipItem equipPacket)이라는 장비장착 관련 패킷을 받아 처리하는 함수도 있으나 특정 코드에서만 사용하게끔  만든 것이어서 다른 코드에서 함부로 호출하지 않도록 해요


8. 몬스터

몬스터는 게임오브젝트를 상속받고 있어서 게임오브젝트의 모든 프로퍼티와 함수를 사용 가능해요. 

 

TemplateId : 해당 몬스터의 데이터시트 인덱스

 

이 외에 UpdateIdle(), UpdateMoving(), UpdateSkill(), UpdateDead(), 가상함수 GetRandomReward()가 있으나 내부에서만 사용해요.


9. 발사체(=projectile)

발사체는 게임오브젝트의 상속을 받고 있구요. 이는 다시 화살이 상속받고 있어요. 때문에 게임오브젝트의 모든 걸 가져다 쓸 수 있어요.

 

Data : 데이터시트에서 해당 스킬정보

Data.id : 데이터시트상 스킬 id
Data.name : 데이터시트상 스킬 이름
Data.cooldown : 데이터시트상 스킬 쿨타임
Data.damage : 데이터시트상 스킬 데미지
Data.skillType : 데이터시트상 스킬 타입(SkillType.SkillNone, SkillType.SkillAuto, SkillType.SkillProjectile)
Data.projectile.name : 발사체의 이름(string)
Data.projectile.speed : 발사체의 이동속도(float)
Data.projectile.range : 발사체의 공격범위(int)
Data.projectile.prefab : 발사체의 프리팹의 path

10. 화살

 

화살은 발사체를 상속받고 있어요. 당연히 게임오브젝트와 발사체의 모든 프로퍼티와 함수를 가져다 쓸 수 있어요.

 

GetOwner() : 해당 화살을 발사한 주인님 게임오브젝트


11. 게임로직

게임로직에서는 서버내에 존재하는 모든 게임룸을 관리합니다.

 

Add(int mapId) : 게임룸 추가

Remove(int roomId) : 게임룸 제거 -> bool값 반환

Find(int roomId) : 게임룸 검색 -> 게임룸 반환

 

이 외에 JobSerialize를 상속 받고 있어서 Push(), PushAfter() 사용 가능해요.


12. 게임룸

게임룸은 말그대로 '게임방'이에요. 여러명의 플레이어가 게임을 즐 길 수 있는 공간이에요.

 

GameRoom.VisionCells : 비전큐브에서의 시야범위 값

RoomId : 게임룸의 고유Id

Zones : 게임룸 내를 나눈 Zone들 (Zone[,]타입으로 반환)

ZoneCells : 맵의 가로와 세로를 몇개의 Zone으로 쪼갤 것인지

 

Map : Map

MinX : 맵의 최소 X값 (map텍스트 내의 값 중 하나) => int타입으로 반환
MaxX : 맵의 최대 X값 (map텍스트 내의 값 중 하나) => int타입으로 반환
MinY : 맵의 최소 Y값 (map텍스트 내의 값 중 하나) => int타입으로 반환
MaxY : 맵의 최대 Y값 (map텍스트 내의 값 중 하나) => int타입으로 반환
SizeX : 맵의 가로 사이즈 => int타입으로 반환
SizeY : 맵의 세로 사이즈 => int타입으로 반환

CanGo(Vector2Int cellPos, bool checkObjects = true) : 특정 칸(cellPos)가 이동 가능한지 체크, 인자로 게임오브젝트도 충돌체로 인식 할 것인지를 넣어 줄 수 있어요. => bool타입으로 반환
Find(Vector2Int cellPos) : 특정 칸(cellPos)을 밟고 있는 게임오브젝트를 반환 => GameObject타입으로 반환
ApplyLeave(GameObject gameObject) : 특정 게임오브젝트를 Zone에서 나가게 하고 충돌정보도 삭제 => bool타입으로 반환
ApplyMove(GameObject gameObject, Vector2Int dest, bool checkObjects = true, bool collision = true) : 특정 게임오브젝트를 destPos로 이동 => bool타입으로 반환
LoadMap(int mapId, string pathPrefix = "../../../../../Common/MapData") : map텍스트파일을 토대로 맵 충돌정보 구성
FindPath(Vector2Int startCellPos, Vector2Int destCellPos, bool checkObjects = true, int maxDist = 10) : startPos에서 destPos까지 A*를 이용하여 최단 거리 반환 => List<Vector2Int>타입으로 반환

 

GetZone(Vector2Int cellPos) : 특정 칸(cellPos)이 속한 Zone을 긁어오기 => Zone타입 반환

GetZone(int indexY, int indexX) : Zones배열 내에서 특정 존을 긁어오기 => Zone타입 반환

Init(int mapId, int zoneCells) : 게임룸 초기화 함수

EnterGame(GameObject gameObject, bool randomPos) : 게임룸에 입장하기

LeaveGame(int objectId) : 게임룸 나가기

FindClosestPlayer(Vector2Int pos, int range) : 특정 칸(cellPos)를 기준으로 range범위 내에서 가장 가까운 플레이어 검색 => Player타입으로 반환

Broadcast(Vector2Int pos, IMessage packet) : 비전큐브 시야 범위 내의 플레이어들에게 패킷쏘아주기

GetAdjacentZones(Vector2Int cellPos, int range = GameRoom.VisionCells) : 특정 칸 (cellPos) 기준으로 range범위 내의 인접 Zone들을 긁어오기 => List<Zone>타입으로반환

 

이외에도 JobSerialize를 상속받았기에 Job함수들 사용가능하고 Pos, Vector2Int, PQNode구조체들이 정의되어 았어요. 


 

여기까지에요 ㅎㅎ 도움이 되셨음 좋겠습니다. GoodMorningGoodAfternoonGoodNight :D