您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
198 行
8.0 KiB
198 行
8.0 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Unity.Collections;
|
|
using UnityEngine;
|
|
using Unity.Entities;
|
|
using Unity.Sample.Core;
|
|
|
|
// Simple, team based deathmatch mode
|
|
|
|
public class GameModeDeathmatch : IGameMode
|
|
{
|
|
[ConfigVar(Name = "game.dm.minplayers", DefaultValue = "1", Description = "Minimum players before match starts")]
|
|
public static ConfigVar minPlayers;
|
|
[ConfigVar(Name = "game.dm.prematchtime", DefaultValue = "0", Description = "Time before match starts")]
|
|
public static ConfigVar preMatchTime;
|
|
[ConfigVar(Name = "game.dm.postmatchtime", DefaultValue = "10", Description = "Time after match ends before new will begin")]
|
|
public static ConfigVar postMatchTime;
|
|
[ConfigVar(Name = "game.dm.roundlength", DefaultValue = "1800", Description = "Deathmatch round length (seconds)")]
|
|
public static ConfigVar roundLength;
|
|
|
|
public void Initialize(World world, GameModeSystemServer gameModeSystemServer)
|
|
{
|
|
m_world = world;
|
|
m_GameModeSystemServer = gameModeSystemServer;
|
|
|
|
// Create teams
|
|
m_GameModeSystemServer.CreateTeam("Team 1");
|
|
m_GameModeSystemServer.CreateTeam("Team 2");
|
|
|
|
Console.Write("Deathmatch game mode initialized");
|
|
}
|
|
|
|
public void Restart()
|
|
{
|
|
foreach (var t in m_GameModeSystemServer.teams)
|
|
t.score = 0;
|
|
m_Phase = Phase.Countdown;
|
|
m_GameModeSystemServer.StartGameTimer(preMatchTime, "PreMatch");
|
|
}
|
|
|
|
public void Shutdown()
|
|
{
|
|
}
|
|
|
|
char[] _msgBuf = new char[256];
|
|
public void Update()
|
|
{
|
|
|
|
var players = m_GameModeSystemServer.playersComponentGroup.ToComponentDataArray<Player.State>(Allocator.TempJob);
|
|
|
|
switch (m_Phase)
|
|
{
|
|
case Phase.Countdown:
|
|
if (m_GameModeSystemServer.GetGameTimer() == 0)
|
|
{
|
|
if (players.Length < minPlayers.IntValue)
|
|
{
|
|
m_GameModeSystemServer.chatSystem.SendChatAnnouncement("Waiting for more players.");
|
|
m_GameModeSystemServer.StartGameTimer(preMatchTime, "PreMatch");
|
|
}
|
|
else
|
|
{
|
|
m_GameModeSystemServer.StartGameTimer(roundLength, "");
|
|
m_Phase = Phase.Active;
|
|
m_GameModeSystemServer.chatSystem.SendChatAnnouncement("Match started!");
|
|
}
|
|
}
|
|
break;
|
|
case Phase.Active:
|
|
if (m_GameModeSystemServer.GetGameTimer() == 0)
|
|
{
|
|
// Find winner team
|
|
var winTeam = -1;
|
|
var teams = m_GameModeSystemServer.teams;
|
|
// TODO (petera) Get rid of teams list and hardcode for teamsize 2 as all ui etc assumes it anyways.
|
|
if (teams.Count == 2)
|
|
{
|
|
winTeam = teams[0].score > teams[1].score ? 0 : teams[0].score < teams[1].score ? 1 : -1;
|
|
}
|
|
|
|
// TODO : For now we just kill all players when we restart
|
|
// but we should change it to something less dramatic like taking
|
|
// control away from the player or something
|
|
for (int i = 0, c = players.Length; i < c; i++)
|
|
{
|
|
var playerState = players[i];
|
|
if (playerState.controlledEntity != Entity.Null)
|
|
{
|
|
var healthState = m_world.EntityManager
|
|
.GetComponentData<HealthStateData>(playerState.controlledEntity);
|
|
healthState.health = 0.0f;
|
|
healthState.deathTick = -1;
|
|
m_world.EntityManager
|
|
.SetComponentData(playerState.controlledEntity, healthState);
|
|
}
|
|
playerState.displayGameResult = true;
|
|
if (winTeam == -1)
|
|
playerState.gameResult = new NativeString64("TIE");
|
|
else
|
|
playerState.gameResult = new NativeString64((playerState.teamIndex == winTeam) ? "VICTORY" : "DEFEAT");
|
|
playerState.displayCountDown = false;
|
|
playerState.displayScoreBoard = false;
|
|
playerState.displayGoal = false;
|
|
}
|
|
|
|
m_Phase = Phase.Ended;
|
|
m_GameModeSystemServer.SetRespawnEnabled(false);
|
|
m_GameModeSystemServer.StartGameTimer(postMatchTime, "PostMatch");
|
|
var l = 0;
|
|
if (winTeam > -1)
|
|
l = StringFormatter.Write(ref _msgBuf, 0, "Match over. {0} wins!", m_GameModeSystemServer.teams[winTeam].name);
|
|
else
|
|
l = StringFormatter.Write(ref _msgBuf, 0, "Match over. Its a tie!");
|
|
m_GameModeSystemServer.chatSystem.SendChatAnnouncement(new CharBufView(_msgBuf, l));
|
|
}
|
|
break;
|
|
case Phase.Ended:
|
|
if (m_GameModeSystemServer.GetGameTimer() == 0)
|
|
{
|
|
for (int i = 0, c = players.Length; i < c; i++)
|
|
{
|
|
var playerState = players[i];
|
|
playerState.displayGameResult = false;
|
|
}
|
|
m_GameModeSystemServer.Restart();
|
|
}
|
|
break;
|
|
}
|
|
|
|
for (int i = 0; i < players.Length; i++)
|
|
{
|
|
var player = players[i];
|
|
if (player.controlledEntity == Entity.Null)
|
|
continue;
|
|
var charPredictedState = m_world.EntityManager.GetComponentData<Character.PredictedData>(player.controlledEntity);
|
|
var position = charPredictedState.position;
|
|
player.enableCharacterSwitch = false;
|
|
foreach (var b in m_GameModeSystemServer.teamBases)
|
|
{
|
|
if (b.teamIndex == player.teamIndex)
|
|
{
|
|
var inside = (b.boxCollider.transform.InverseTransformPoint(position) - b.boxCollider.center);
|
|
if (Mathf.Abs(inside.x) < b.boxCollider.size.x * 0.5f && Mathf.Abs(inside.y) < b.boxCollider.size.y * 0.5f && Mathf.Abs(inside.z) < b.boxCollider.size.z * 0.5f)
|
|
{
|
|
player.enableCharacterSwitch = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
players.Dispose();
|
|
|
|
var gameModeState = m_world.EntityManager.GetComponentData<GameModeData>(m_GameModeSystemServer.gameModeEntity);
|
|
|
|
// Push scores to gameMode that is synchronized to client
|
|
gameModeState.teamScore0 = m_GameModeSystemServer.teams[0].score;
|
|
gameModeState.teamScore1 = m_GameModeSystemServer.teams[1].score;
|
|
m_world.EntityManager.SetComponentData(m_GameModeSystemServer.gameModeEntity, gameModeState);
|
|
}
|
|
|
|
public void OnPlayerJoin(ref Player.State playerState)
|
|
{
|
|
playerState.score = 0;
|
|
m_GameModeSystemServer.AssignTeam(ref playerState);
|
|
}
|
|
|
|
public void OnPlayerKilled(ref Player.State victim, ref Player.State killer)
|
|
{
|
|
if (killer.teamIndex != victim.teamIndex)
|
|
{
|
|
killer.score++;
|
|
m_GameModeSystemServer.teams[killer.teamIndex].score++;
|
|
}
|
|
else if (victim.playerId == killer.playerId)
|
|
{
|
|
victim.score--;
|
|
m_GameModeSystemServer.teams[victim.teamIndex].score--;
|
|
}
|
|
}
|
|
|
|
public void OnPlayerRespawn(ref Player.State playerState, ref Vector3 position, ref Quaternion rotation)
|
|
{
|
|
m_GameModeSystemServer.GetRandomSpawnTransform(playerState.teamIndex, ref position, ref rotation);
|
|
}
|
|
|
|
enum Phase
|
|
{
|
|
Undefined,
|
|
Countdown,
|
|
Active,
|
|
Ended,
|
|
}
|
|
Phase m_Phase;
|
|
|
|
World m_world;
|
|
GameModeSystemServer m_GameModeSystemServer;
|
|
}
|