Skip to content

Instantly share code, notes, and snippets.

@arun02139
Created April 5, 2017 16:30
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save arun02139/49132cc38941a70b5936a37df48c62b8 to your computer and use it in GitHub Desktop.
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