Created
April 5, 2017 16:30
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.UI; | |
using UnityEngine.Assertions; | |
using UnityEngine.Networking; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Prototype.NetworkLobby; | |
public class Player : NetworkBehaviour//, IPlayer | |
{ | |
public int DBId; | |
public List<uint> unitIds = new List<uint>(); | |
public UIntUnityEvent UnitDied = new UIntUnityEvent(); | |
public bool AllUnitsDead() | |
{ | |
for (int i = 0; i < unitIds.Count; i++) | |
{ | |
uint id = unitIds[i]; | |
if(Battle.i.units[id].hp > 0) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
// NOTE: any SyncVar with 'sync' as a prefix (such as below) is used *only* to set initial value within | |
// the base class (e.g. .color) and **should not be accessed elsewhere** despite being public! | |
[SyncVar(hook="ColorHook")] | |
public Color color; | |
[SyncVar] | |
public bool isHost; | |
// list of jobs! TODO: sync a struct that has job and | |
public SyncListParty syncParty = new SyncListParty(); | |
string _debugString; | |
bool _init; | |
NetIdUI _netUI; | |
public override void OnStartClient() | |
{ | |
// HACK: manually call my hook function for all the necessary SyncVars on OnStartClient() to ensure that the hook | |
// is called during player initialization, even if the SyncVar value does get properly updated | |
// LINK: https://forum.unity3d.com/threads/syncvar-hook-not-called-on-client-immediately-after-scene-change.424844/ | |
ColorHook(color); | |
} | |
public override void OnStartServer() | |
{ | |
base.OnStartServer (); | |
} | |
IEnumerator Start() | |
{ | |
// _debugString = string.Format ("Player.Start: {0}", this.name); | |
// ClientDebugUI.i.Log (_debugString, GameColor.Black); | |
yield return new WaitForEndOfFrame (); // HACK (necessary to test for isLocalPlayer) | |
while (Battle.i == null) | |
{ | |
_debugString = string.Format ("Player.Start: Battle.i is null", ""); | |
ClientDebugUI.i.Log (_debugString, GameColor.Magenta); | |
yield return new WaitForEndOfFrame (); | |
} | |
while(netId.Value == 0) | |
{ | |
_debugString = string.Format ("Player.Start: netId is zero", ""); | |
ClientDebugUI.i.Log (_debugString, GameColor.Magenta); | |
yield return new WaitForEndOfFrame(); | |
} | |
// handy variable | |
isHost = (isServer && isLocalPlayer) || (!isServer && !isLocalPlayer); | |
int gameColor = System.Convert.ToInt32(netId.Value) % Constants.COLORS.Length; | |
this.color = Constants.COLORS [gameColor]; | |
if (isLocalPlayer) { | |
Assert.IsTrue (Battle.i.localPlayerId == 0); | |
Battle.i.localPlayerId = netId.Value; | |
} | |
AddNetUI(); | |
Battle.i.players.Add (netId.Value, this); | |
transform.SetParent (Battle.i.transform); | |
_init = true; | |
} | |
public override void OnStartAuthority () | |
{ | |
base.OnStartAuthority(); | |
StartCoroutine(OnAuthorized()); | |
} | |
IEnumerator OnAuthorized() | |
{ | |
while(!_init) | |
yield return new WaitForEndOfFrame(); | |
// if there already are children (units), do nothing (perhaps this is an AI troop) | |
if (transform.childCount == 0) | |
{ | |
// player units should have been copied here if we went through a lobby | |
if (syncParty.Count > 0) { | |
LoadLobbyParty (); | |
} else { | |
LoadPlayerParty (); | |
} | |
} | |
} | |
void AddNetUI() | |
{ | |
_netUI = UIManager.i.Add<NetIdUI>("NetIdUI"); | |
_netUI.Init (this, false); | |
_netUI.SetTextColor (color); | |
_netUI.SetPrescript ("Player "); | |
_netUI.transform.SetAsLastSibling (); | |
_netUI.GetComponent<Text> ().alignment = TextAnchor.MiddleLeft; | |
Vector2 center = isHost ? Constants.LOWER_PLAYER_UI_ANCHOR : Constants.UPPER_PLAYER_UI_ANCHOR; | |
_netUI.GetComponent<RectTransform>().anchorMin = center; | |
_netUI.GetComponent<RectTransform>().anchorMax = center; | |
} | |
[Command] | |
void CmdSpawnUnit(int spawnOrder, int job, int level) | |
{ | |
if(SpawnManager.i == null) | |
{ | |
_debugString = string.Format ("Player.CmdSpawnUnit: SpawnManager not found, aborting (level may be missing)", ""); | |
ClientDebugUI.i.Log (_debugString); | |
return; | |
} | |
var spawnPoints = SpawnManager.i.UnitSpawnPoints(isLocalPlayer); | |
if (spawnOrder > spawnPoints.Length - 1) | |
{ | |
_debugString = string.Format("Player.CmdSpawnUnit: no spawn points available, aborting", GameColor.Red); | |
ServerDebugUI.i.Log (_debugString); | |
return; | |
} | |
Transform spawnPoint = spawnPoints[spawnOrder]; | |
// ServerDebugUI.i.Log (string.Format ("Player.CmdSpawnUnit: {0} spawning new unit at {1}", netId, spawnPoint.position)); | |
// grab the prefab reference | |
var unitPrefab = NetworkLobbyManager.singleton.spawnPrefabs [job-1]; | |
// instantiate (on the server) | |
var unitGO = Instantiate(unitPrefab, spawnPoint.position, Quaternion.identity) as GameObject; | |
// position at spawn point | |
unitGO.transform.position = spawnPoint.position; | |
// set new networked unit's player id (via a SyncVar and a HookFunction that sets UnitBase.playerId; | |
// Hook function will be manually called in Unit.OnStartClient() | |
if (netId.Value == 0) { | |
_debugString = string.Format ("Player.CmdSpawnUnit: netId not set!", ""); | |
Debug.Log (_debugString); | |
ServerDebugUI.i.Log (_debugString, GameColor.Red); | |
} | |
// spawn on clients across the network | |
NetworkServer.SpawnWithClientAuthority(unitGO, base.connectionToClient); | |
unitGO.GetComponent<Unit> ().CmdSetPlayerId (netId.Value); | |
// maintain hierarchy across network (unit will look up the hierarchy for a playerId) | |
//LinkToParent (unitGO, gameObject); | |
// TODO TOMORROW/NEXTIMEASAP: hook up in unit instead.. | |
} | |
// use hook function to directly set .color asap | |
void ColorHook(Color value) | |
{ | |
color = value; | |
// ClientDebugUI.i.Log (string.Format ("Player." + "ColorHook".Colorize(GameColor.Yellow) + | |
// ": lobbyColor={0},\n color={1}", lobbyColor, color)); | |
} | |
void OnDestroy() | |
{ | |
if(Battle.i != null && Battle.i.players.ContainsKey(netId.Value)) | |
{ | |
Battle.i.players.Remove(netId.Value); | |
} | |
// clean-up ui | |
if(_netUI != null && UIManager.i != null) { | |
UIManager.i.Remove(_netUI.gameObject); | |
} | |
} | |
void LoadLobbyParty() | |
{ | |
for (int i = 0; i < syncParty.Count; i++) | |
CmdSpawnUnit (i, syncParty [i].job, syncParty [i].level); | |
} | |
void LoadPlayerParty() | |
{ | |
int playerDBId = SQLDynamicUtil.GetPlayerInfo ().ID; | |
// _debugString = string.Format ("Player.LoadPlayerParty: playerDBId={0}", playerDBId); | |
// ClientDebugUI.i.Log (_debugString, GameColor.Black); | |
var party = SQLDynamicUtil.GetPlayerParty (playerDBId, 1, true); | |
for (int i = 0; i < party.Count; i++) | |
CmdSpawnUnit (i, party [i].Job, party [i].Level); | |
} | |
private static void LinkToParent(GameObject child, GameObject parent) | |
{ | |
child.transform.parent = parent.transform; | |
NetworkServer.SendToAll(CustomMessage.SetParent, new SetParentMessage(child, parent)); | |
} | |
// HACK (http://answers.unity3d.com/questions/1170290/unet-indexoutofrangeexception-networkreaderreadbyt.html) | |
public override void OnDeserialize(NetworkReader reader, bool initialState) | |
{ | |
base.OnDeserialize(reader, initialState); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment