보스 Scene
rpg의 하이라이트라고 할 수 있는 보스 원정대를 만들어보자.
일단 먼저 보스가 존재하는 Scene을 따로 분리해서 만들어 줄 것이다. 아무리 오픈월드라고 해도 보스가 있는 곳은 연산 때문에 분리하는게 좋다고 판단했다.
대신 보스는 제자리 고정형으로 구성되기 때문에 데디 서버를 이용할 필요는 없을 것이다.
맵은 던전 느낌이 나도록 구성한 에셋을 이용했다.
밑에 지형에 보스랑 전투를 할 것이고 위 지형에는 보상을 얻는 장소로 사용할 것이다.
시네머신 Timeline을 이용해 컷신도 만들어 볼 것이다.
보스 몬스터의 경우는 드래곤으로 결정했다.(역시 rpg는 드래곤이지)
컷신
보스 컷신은 이런식으로 구성되어 있다.
시네머신을 처음 사용해서 약간의 어색함이 존재하지만 크게 어렵지는 않아서 충분히 연습하면 잘 쓸 수 있을 것이다.
두가지 버전을 고민 중인데 후자를 선택했다.
버전1
버전2
컷신도 만들었겠다. 이제 이 씬에 입장하는 걸 만들어보자.
원정대 신청
일단 원정대를 신청할 수 있는 npc를 만들어준다.
상점과 동일하게 spacebar를 누르면 원정대를 신청할 수 있다.
public override void OpenNpc()
{
C_Expedition expedition = new C_Expedition();
expedition.RoomId = 2;
Managers.Network.Send(expedition);
}
여기서 roomId는 내가 입장하고자 하는 맵의 숫자이다.
서버 쪽에는 이렇게 동작한다.
public void HandleExpedition(Player player, C_Expedition expeditionPacket)
{
if(GameLogic.Instance.Find(expeditionPacket.RoomId).isRaid)
{
S_Message message = new S_Message();
message.Message = $"누군가 레드 드래곤 토벌 중 입니다.";
player.Session.Send(message);
return;
}
if(moveMapPlayer.Count == 0)
{
S_Message message = new S_Message();
message.Message = $"누군가 레드 드래곤 원정대를 생성했습니다.\n 5분뒤 원정대가 출발합니다.";
foreach (Player players in _players.Values)
{
players.Session.Send(message);
}
PushAfter(3000, AllPlayerEnterNextMap, expeditionPacket.RoomId, "Boss");
}
else
{
if (moveMapPlayer.Find(p => p.Info.Name == player.Info.Name) != null)
{
S_Message messages = new S_Message();
messages.Message = "이미 원정대에 가입했습니다.";
player.Session.Send(messages);
return;
}
S_Message message = new S_Message();
message.Message = "누군가 레드 드래곤 원정대에 참여했습니다.";
foreach (Player players in _players.Values)
{
players.Session.Send(message);
}
}
moveMapPlayer.Add(player);
}
이미 한 파티가 원정을 시작했다면 거부하고 아니라면 신청하게 된다. 또한 자신이 원정대장 인 경우와 아닌 경우를 분류해서 클라이언트로 메시지를 보낸다.
현재는 5분이라고 표기는 했지만 3초만에 입장하게 된다.(pushAfter를 3초로 함. 테스트 용도)
public void AllPlayerEnterNextMap(int roomId, string mapName)
{
foreach (var player in moveMapPlayer)
{
C hangeTheRoom(roomId, player, mapName);
}
if(roomId == 2)
{
GameLogic.Instance.Find(roomId).isRaid = true;
}
moveMapPlayer.Clear();
}
public void ChangeTheRoom(int roomId, Player player, string mapName)
{
GameRoom room = GameLogic.Instance.Find(roomId);
if (room == null) return;
if (player == null) return;
int objectId = player.Id;
if (_players.Remove(objectId, out player) == false)
return;
List<Monster> monsters = _monsters.Values.ToList();
foreach (var monster in monsters)
{
if (monster.Target != null && monster.Target == player)
monster.Target = null;
}
player.curZone.Remove(player);
player.Room = null;
S_Despawn despawnPacket = new S_Despawn();
despawnPacket.ObjectIds.Add(objectId);
Broadcast(player.Pos, despawnPacket);
player.Room = room;
room.cutSceneCount = 0;
if (player != null)
room.moveMapPlayer.Add(player);
// 맵 이동 패킷 보내기
S_ChangeMap changeMap = new S_ChangeMap();
changeMap.MapName = mapName;
player.Session.Send(changeMap);
}
이렇게 플레이어의 room을 보스 room으로 이동시켜주고 맵도 이동시켜주면 된다.
결과
'Unity > 온라인 RPG' 카테고리의 다른 글
[Unity 3D] 각종 사운드 추가 (0) | 2024.07.29 |
---|---|
[Unity 3D] 보스 드래곤의 패턴 만들기 (0) | 2024.07.29 |
[Unity 3D] 클라이언트, 서버 최적화 (0) | 2024.07.04 |
[Unity 3D] 상점 Npc - 아이템 구매, 판매하기 (0) | 2024.07.04 |
[Unity 3D] 아이템 인벤창에서 옮기기 (0) | 2024.06.21 |