浏览代码

more progress on core scene switching framework

/main
David Woodruff 4 年前
当前提交
bc9bfd75
共有 41 个文件被更改,包括 758 次插入134 次删除
  1. 19
      Assets/Scenes/MainMenu.unity
  2. 50
      Assets/Scripts/Client/UI/MainMenuUI.cs
  3. 60
      Assets/Scripts/Shared/Net/GameNetHub.cs
  4. 2
      Assets/Scripts/Server/Game/SCharSelectBRState.cs.meta
  5. 8
      Assets/Scripts/Client/Game.meta
  6. 8
      Assets/Scripts/Client/Net.meta
  7. 8
      Assets/Scripts/Server.meta
  8. 8
      Assets/Scripts/Shared/Game.meta
  9. 29
      Assets/Scripts/Client/Game/CCharSelectBRState.cs
  10. 11
      Assets/Scripts/Client/Game/CCharSelectBRState.cs.meta
  11. 25
      Assets/Scripts/Client/Game/CGameBRState.cs
  12. 11
      Assets/Scripts/Client/Game/CGameBRState.cs.meta
  13. 35
      Assets/Scripts/Client/Game/CMainMenuBRState.cs
  14. 11
      Assets/Scripts/Client/Game/CMainMenuBRState.cs.meta
  15. 78
      Assets/Scripts/Client/Net/GNH_Client.cs
  16. 8
      Assets/Scripts/Server/Game.meta
  17. 28
      Assets/Scripts/Server/Game/SCharSelectBRState.cs
  18. 25
      Assets/Scripts/Server/Game/SGameBRState.cs
  19. 11
      Assets/Scripts/Server/Game/SGameBRState.cs.meta
  20. 8
      Assets/Scripts/Server/Net.meta
  21. 80
      Assets/Scripts/Server/Net/GNH_Server.cs
  22. 143
      Assets/Scripts/Shared/Game/BossRoomStateManager.cs
  23. 11
      Assets/Scripts/Shared/Game/BossRoomStateManager.cs.meta
  24. 32
      Assets/Scripts/Shared/Game/CharSelectBRState.cs
  25. 11
      Assets/Scripts/Shared/Game/CharSelectBRState.cs.meta
  26. 40
      Assets/Scripts/Shared/Game/GameBRState.cs
  27. 11
      Assets/Scripts/Shared/Game/GameBRState.cs.meta
  28. 33
      Assets/Scripts/Shared/Game/IBossRoomState.cs
  29. 11
      Assets/Scripts/Shared/Game/IBossRoomState.cs.meta
  30. 25
      Assets/Scripts/Shared/Net/GNH_Client.cs
  31. 26
      Assets/Scripts/Shared/Net/GNH_Server.cs
  32. 26
      Assets/Scripts/Shared/Net/StartupManager.cs
  33. 0
      /Assets/Scripts/Client/Net/GNH_Client.cs.meta
  34. 0
      /Assets/Scripts/Server/Net/GNH_Server.cs.meta
  35. 0
      /Assets/Scripts/Server/Game/SCharSelectBRState.cs.meta

19
Assets/Scenes/MainMenu.unity


- component: {fileID: 569965807}
- component: {fileID: 569965806}
- component: {fileID: 569965808}
- component: {fileID: 569965809}
m_Name: GameNetHub
m_Name: GameHub
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0

PrefabHashGenerator: GameNetHub
AlwaysReplicateAsRoot: 0
DontDestroyWithOwner: 0
--- !u!114 &569965809
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 569965805}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 39332c63269f3f34db37df122adcc57b, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &726602803
GameObject:
m_ObjectHideFlags: 0

m_Script: {fileID: 11500000, guid: f6144e8dd0fc8ec4cb23a1a49059aa08, type: 3}
m_Name:
m_EditorClassIdentifier:
NetHostGO: {fileID: 1359040525}
GameHubGO: {fileID: 569965805}
--- !u!1 &1359040525
GameObject:
m_ObjectHideFlags: 0

TimeResyncInterval: 30
EnableNetworkedVar: 0
EnsureNetworkedVarLengthSafety: 0
EnableSceneManagement: 1
EnableSceneManagement: 0
ForceSamePrefabs: 1
UsePrefabSync: 0
RecycleNetworkIds: 1

50
Assets/Scripts/Client/UI/MainMenuUI.cs


using System.Collections.Generic;
using UnityEngine;
public class MainMenuUI : MonoBehaviour
namespace BossRoomViz
public GameObject NetHostGO;
private MLAPI.NetworkingManager m_netManager;
// Start is called before the first frame update
void Start()
public class MainMenuUI : MonoBehaviour
m_netManager = NetHostGO.GetComponent<MLAPI.NetworkingManager>();
}
public GameObject GameHubGO;
private BossRoom.GameNetHub m_netHub;
// Update is called once per frame
void Update()
{
}
// Start is called before the first frame update
void Start()
{
m_netHub = GameHubGO.GetComponent<BossRoom.GameNetHub>();
}
public void OnHostClicked()
{
Debug.Log("Host Clicked");
// Update is called once per frame
void Update()
{
}
//TODO: bring up transition screen.
public void OnHostClicked()
{
Debug.Log("Host Clicked");
m_netManager.StartHost();
UnityEngine.SceneManagement.SceneManager.LoadScene("SampleScene", UnityEngine.SceneManagement.LoadSceneMode.Single);
}
//TODO: bring up transition screen.
public void OnConnectClicked()
{
Debug.Log("Connect Clicked");
m_netHub.NetManager.StartHost();
}
public void OnConnectClicked()
{
Debug.Log("Connect Clicked");
m_netHub.StartClient("127.0.0.1", 7777);
}

60
Assets/Scripts/Shared/Net/GameNetHub.cs


{
public enum ConnectStatus
{
CONNECT, //client successfully connected. This may also be a successful reconnect.
SUCCESS, //client successfully connected. This may also be a successful reconnect.
ESERVERFULL, //can't join, server is already at capacity.
EMATCHSTARTED, //can't join, match is already in progress.
EUNKNOWN //can't join, reason unknown.

{
public GameObject NetworkingManagerGO;
private GNH_Client m_clientLogic;
private GNH_Server m_serverLogic;
private BossRoomClient.GNH_Client m_clientLogic;
private BossRoomServer.GNH_Server m_serverLogic;
public MLAPI.NetworkingManager NetManager { get; private set; }

public override void NetworkStart()
{
if( NetManager.IsServer )
if (NetManager.IsClient)
m_serverLogic = new GNH_Server(this);
m_clientLogic = new BossRoomClient.GNH_Client(this);
else if( NetManager.IsClient )
{
m_clientLogic = new GNH_Client(this);
}
else
if ( NetManager.IsServer )
Debug.LogError("NetworkStart invoked, but NetworkingManager is neither server nor client");
m_serverLogic = new BossRoomServer.GNH_Server(this);
//special host code. This is what kicks off the flow that happens on a regular client
//when it has finished connecting successfully. A dedicated server would remove this.
RecvConnectFinished(ConnectStatus.SUCCESS, BossRoomState.CHARSELECT);
//Server->Client RPCs
public void S2C_ConnectResult( ulong netId, ConnectStatus status )
{
InvokeClientRpcOnClient("RecvConnectResult", netId, status);
}
[MLAPI.Messaging.ClientRPC]
private void RecvConnectFinished( ConnectStatus status )
/// <summary>
/// Wraps the invocation of NetworkingManager.StartClient, including our GUID as the payload.
/// </summary>
/// <param name="ipaddress">the IP address of the host to connect to.</param>
/// <param name="port">The port of the host to connect to. </param>
public void StartClient(string ipaddress, int port)
m_clientLogic.RecvConnectFinished( status);
BossRoomClient.GNH_Client.StartClient(this, ipaddress, port);
//Server->Client RPCs
//Client->Server
public void C2S_RequestConnect( string guid )
public void S2C_ConnectResult( ulong netId, ConnectStatus status, BossRoomState targetState )
InvokeServerRpc("RecvRequestConnect", guid, NetManager.LocalClientId, MLAPI.Security.SecuritySendFlags.None);
InvokeClientRpcOnClient("RecvConnectResult",
netId,
"MLAPI_INTERNAL", // channelID. Must be MLAPI_INTERNAL Because it is called as part of the StartClient flow (before possible reject comes back).
MLAPI.Security.SecuritySendFlags.None,
MLAPI.Security.SecuritySendFlags.None,
status, // this is the actual payload
targetState); // ""
[MLAPI.Messaging.ServerRPC(RequireOwnership = false)]
private void RecvRequestConnect( string guid, ulong clientId )
[MLAPI.Messaging.ClientRPC()]
private void RecvConnectFinished( ConnectStatus status, BossRoomState targetState )
m_clientLogic.RecvConnectFinished( status, targetState );
}
}
}
}

2
Assets/Scripts/Server/Game/SCharSelectBRState.cs.meta


fileFormatVersion: 2
guid: 4703759d077152c4db03d0b623e23e9f
guid: 425e77ec23730374bbbe2ee01d6e1e7c
MonoImporter:
externalObjects: {}
serializedVersion: 2

8
Assets/Scripts/Client/Game.meta


fileFormatVersion: 2
guid: 96e5af1f6fcbe144a99396d22b4f7dbf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Client/Net.meta


fileFormatVersion: 2
guid: 834e4dadbaf194f45a280e71aace6a16
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Server.meta


fileFormatVersion: 2
guid: fea36b5492aa19d4f88d4dd297330468
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Shared/Game.meta


fileFormatVersion: 2
guid: 3cd90654bfd4b4d448c23aefbf8174ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

29
Assets/Scripts/Client/Game/CCharSelectBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoomClient
{
class CCharSelectBRState : CharSelectBRState
{
public override void Destroy()
{
base.Destroy();
}
public override void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
base.Initialize(manager, stateParams);
}
public override void Update()
{
base.Update();
}
}
}

11
Assets/Scripts/Client/Game/CCharSelectBRState.cs.meta


fileFormatVersion: 2
guid: 5c5d294b879617e448dbe34b7f09616d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/Scripts/Client/Game/CGameBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoomClient
{
class CGameBRState : GameBRState
{
public override void Destroy()
{
base.Destroy();
}
public override void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
base.Initialize(manager, stateParams);
}
public override void Update()
{
base.Update();
}
}
}

11
Assets/Scripts/Client/Game/CGameBRState.cs.meta


fileFormatVersion: 2
guid: fb79a8334ba58754c98a2ee9fc2a5dee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

35
Assets/Scripts/Client/Game/CMainMenuBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoomClient
{
/// <summary>
/// The BossRoom state logic that runs during MainMenu. Unlike most states, there is only a client variant of this (you are always
/// a client when sitting at the Main Menu screen).
/// </summary>
class CMainMenuBRState : IBossRoomState
{
private BossRoomStateManager m_manager;
public BossRoomState State { get { return BossRoomState.MAINMENU; } }
public void Destroy()
{
}
public void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
m_manager = manager;
}
public void Update()
{
}
}
}

11
Assets/Scripts/Client/Game/CMainMenuBRState.cs.meta


fileFormatVersion: 2
guid: 5a65bc8be73a02c42a41f5efef95fbae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

78
Assets/Scripts/Client/Net/GNH_Client.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BossRoom;
namespace BossRoomClient
{
/// <summary>
/// Client logic for the GameNetHub. Contains implementations for all of GameNetHub's S2C RPCs.
/// </summary>
public class GNH_Client
{
private GameNetHub m_hub;
public GNH_Client(GameNetHub hub)
{
m_hub = hub;
}
public void RecvConnectFinished( ConnectStatus status, BossRoomState targetState )
{
//on success, there is nothing to do (the MLAPI scene management system will take us to the next scene).
//on failure, we must raise an event so that the UI layer can display something.
Debug.Log("RecvConnectFinished Got status: " + status);
m_hub.GetComponent<BossRoomStateManager>().ChangeState(targetState, null);
}
/// <summary>
/// Either loads a Guid string from Unity preferences, or creates one and checkpoints it, then returns it.
/// </summary>
/// <returns>The Guid that uniquely identifies this client install, in string form. </returns>
private static string GetOrCreateGuid()
{
if( PlayerPrefs.HasKey("client_guid"))
{
return PlayerPrefs.GetString("client_guid");
}
System.Guid g = System.Guid.NewGuid();
string guid_string = g.ToString();
PlayerPrefs.SetString("client_guid", guid_string);
return guid_string;
}
/// <summary>
/// Wraps the invocation of NetworkingManager.StartClient, including our GUID as the payload.
/// </summary>
/// <param name="ipaddress">the IP address of the host to connect to.</param>
/// <param name="port">The port of the host to connect to. </param>
public static void StartClient(GameNetHub hub, string ipaddress, int port)
{
string client_guid = GetOrCreateGuid();
string payload = $"client_guid={client_guid}\n"; //minimal format where key=value pairs are separated by newlines.
Debug.Log("client send payload: " + payload); //dmw_debug: remove.
byte[] payload_bytes = System.Text.Encoding.UTF8.GetBytes(payload);
//fixme: this code is not portable, and will break depending on the transport used. Unfortunately different transports call these
//fields different things, so we might need a big switch-case to handle more than one transport. Or we can update this once
//if we have decisively normalized on UTP transport.
var transport = hub.NetworkingManagerGO.GetComponent<MLAPI.Transports.UNET.UnetTransport>();
transport.ConnectAddress = ipaddress;
transport.ConnectPort = port;
hub.NetManager.NetworkConfig.ConnectionData = payload_bytes;
//and...we're off! MLAPI will establish a socket connection to the host.
// If the socket connection fails, we'll hear back by [???] (fixme: where do we get transport-layer failures?)
// If the socket connection succeeds, we'll get our RecvConnectFinished invoked. This is where game-layer failures will be reported.
hub.NetManager.StartClient();
}
}
}

8
Assets/Scripts/Server/Game.meta


fileFormatVersion: 2
guid: 75639e6fb8c2e4b4aac37138c9601db1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

28
Assets/Scripts/Server/Game/SCharSelectBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoomServer
{
class SCharSelectBRState : CharSelectBRState
{
public override void Destroy()
{
base.Destroy();
}
public override void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
base.Initialize(manager, stateParams);
}
public override void Update()
{
base.Update();
}
}
}

25
Assets/Scripts/Server/Game/SGameBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoomServer
{
class SGameBRState : GameBRState
{
public override void Destroy()
{
base.Destroy();
}
public override void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams )
{
base.Initialize(manager, stateParams);
}
public override void Update()
{
base.Update();
}
}
}

11
Assets/Scripts/Server/Game/SGameBRState.cs.meta


fileFormatVersion: 2
guid: 48a8e5e3f2de1a74889818336559cf4a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Server/Net.meta


fileFormatVersion: 2
guid: b49db31b9d52a4e499fc7edbb83dcbc7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

80
Assets/Scripts/Server/Net/GNH_Server.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BossRoom;
namespace BossRoomServer
{
public class GNH_Server
{
private GameNetHub m_hub;
// used in ApprovalCheck. This is intended as a bit of light protection against DOS attacks that rely on sending silly big buffers of garbage.
private const int MAX_CONNECT_PAYLOAD = 1024;
public GNH_Server(GameNetHub hub)
{
m_hub = hub;
m_hub.NetManager.ConnectionApprovalCallback += this.ApprovalCheck;
}
/// <summary>
/// This logic plugs into the "ConnectionApprovalCallback" exposed by MLAPI.NetworkingManager, and is run every time a client connects to us.
/// See GNH_Client.StartClient for the complementary logic that runs when the client starts its connection.
/// </summary>
/// <remarks>
/// Since our game doesn't have to interact with some third party authentication service to validate the identity of the new connection, our ApprovalCheck
/// method is simple, and runs synchronously, invoking "callback" to signal approval at the end of the method. MLAPI currently doesn't support the ability
/// to send back more than a "true/false", which means we have to work a little harder to provide a useful error return to the client. To do that, we invoke a
/// client RPC in the same channel that MLAPI uses for its connection callback. Since that channel ("MLAPI_INTERNAL") is both reliable and sequenced, we can be
/// confident that our login result message will execute before any disconnect message.
/// </remarks>
/// <param name="connectionData">binary data passed into StartClient. In our case this is the client's GUID, which is a unique identifier for their install of the game that persists across app restarts. </param>
/// <param name="clientId">This is the clientId that MLAPI assigned us on login. It does not persist across multiple logins from the same client. </param>
/// <param name="callback">The delegate we must invoke to signal that the connection was approved or not. </param>
private void ApprovalCheck( byte[] connectionData, ulong clientId, MLAPI.NetworkingManager.ConnectionApprovedDelegate callback )
{
if( connectionData.Length > MAX_CONNECT_PAYLOAD )
{
callback(false, 0, false, null, null );
return;
}
string payload = System.Text.Encoding.UTF8.GetString(connectionData);
string[] config_lines = payload.Split('\n');
Dictionary<string, string> payload_config = new Dictionary<string, string>();
foreach( var line in config_lines )
{
//key-value pair.
if( line.Contains("=") )
{
string[] kv = line.Split('=');
payload_config.Add(kv[0], kv[1]);
}
else if( line.Trim() != "" )
{
//single token, with no value present.
payload_config.Add(line, null);
}
}
//TODO: save off the player's Guid.
Debug.Log("host ApprovalCheck: client payload was: " + payload);
Debug.Log("host ApprovalCheck: client guid was: " + payload_config["client_guid"]);
//TODO: handle different cases based on gamestate (e.g. GameState.PLAYING would cause a reject if this isn't a reconnect case).
//TODO: add corresponding NetworkHide, just so that we don't endlessly leak clientIds into our observer's list. The
//GameNetHub should be observable by everybody all the time.
m_hub.GetComponent<MLAPI.NetworkedObject>().NetworkShow(clientId);
m_hub.S2C_ConnectResult(clientId, ConnectStatus.SUCCESS, BossRoomState.CHARSELECT );
callback(false, 0, true, null, null);
}
}
}

143
Assets/Scripts/Shared/Game/BossRoomStateManager.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom
{
public enum BossRoomState
{
NONE,
MAINMENU,
CHARSELECT,
GAME
}
/// <summary>
/// The BossRoomStateManager manages the top-level logic for each gamestate
/// </summary>
public class BossRoomStateManager : MonoBehaviour
{
public GameNetHub NetHub { get; private set; }
/// <summary>
/// Gets the active state that BossRoomStateManager is in.
/// </summary>
public BossRoomState ActiveState
{
get
{
//There is always a client state, and client and server states must always match. See ChangeState.
//Note: if converting to a dedicated server, you would need to change this to an #IF BUILD_SERVER #ELSE block
//that checked either client or server states. See note in ChangeState about converting to a dedicated server.
return m_clientState != null ? m_clientState.State : BossRoomState.NONE;
}
}
private IBossRoomState m_serverState;
private IBossRoomState m_clientState;
/// <summary>
/// Transitions from one active state to another. Will no-op if transitioning to the current active state.
/// </summary>
/// <remarks>
/// On the Host, Server and Client BossRoomState objects run concurrently. On clients, only the "client" version of each
/// state is instantiated, and for a hypothetical dedicated server, only the server object would be instantiated. If you were
/// moving to a dedicated server model and stripping out server code from the client, this is one method you would need to change
/// (for example by making a client and server factory components that plug themselves into the BossRoomStateManager, and are
/// guarded by #IF !BUILD_SERVER or #IF BUILD_SERVER, respectively)
/// </remarks>
/// <param name="target">the target state to transition to</param>
/// <param name="stateParams">Any special parameters to inform the next state about, or null for none.</param>
public void ChangeState(BossRoomState target, Dictionary<string,System.Object> stateParams )
{
if( target == ActiveState ) { return; }
Debug.Log("transitioning from state " + ActiveState + " to " + target);
switch(target)
{
case BossRoomState.NONE:
{
DestroyStates();
m_serverState = null;
m_clientState = null;
break;
}
case BossRoomState.MAINMENU:
{
DestroyStates();
m_clientState = new BossRoomClient.CMainMenuBRState();
m_clientState.Initialize(this, stateParams);
break;
}
case BossRoomState.CHARSELECT:
{
DestroyStates();
if( NetHub.NetManager.IsServer )
{
m_serverState = new BossRoomServer.SCharSelectBRState();
m_serverState.Initialize(this, stateParams);
}
if( NetHub.NetManager.IsClient )
{
m_clientState = new BossRoomClient.CCharSelectBRState();
m_clientState.Initialize(this, stateParams);
}
break;
}
case BossRoomState.GAME:
{
DestroyStates();
if( NetHub.NetManager.IsServer )
{
m_serverState = new BossRoomServer.SGameBRState();
m_serverState.Initialize(this, stateParams);
}
if( NetHub.NetManager.IsClient )
{
m_clientState = new BossRoomClient.CGameBRState();
m_clientState.Initialize(this, stateParams);
}
break;
}
default:
throw new System.Exception("unimplemented gamestate detected: " + target);
}
}
/// <summary>
/// Helper method for ChangeState that destroys the active states if they exist.
/// </summary>
private void DestroyStates()
{
if (m_serverState != null) { m_serverState.Destroy(); }
if (m_clientState != null) { m_clientState.Destroy(); }
m_serverState = null;
m_clientState = null;
}
// Start is called before the first frame update
void Start()
{
NetHub = this.GetComponent<GameNetHub>();
ChangeState(BossRoomState.MAINMENU, null);
}
// Update is called once per frame
void FixedUpdate()
{
if( m_serverState != null ) { m_serverState.Update(); }
if( m_clientState != null ) { m_clientState.Update(); }
}
}
}

11
Assets/Scripts/Shared/Game/BossRoomStateManager.cs.meta


fileFormatVersion: 2
guid: 39332c63269f3f34db37df122adcc57b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

32
Assets/Scripts/Shared/Game/CharSelectBRState.cs


using System;
using System.Collections.Generic;
using BossRoom;
namespace BossRoom
{
class CharSelectBRState : IBossRoomState
{
protected BossRoomStateManager m_manager;
public BossRoomState State { get { return BossRoomState.CHARSELECT; } }
public virtual void Destroy()
{
}
public virtual void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
m_manager = manager;
}
public virtual void Update()
{
//FIXME (temp): as we don't have a CharacterSelect scene yet, we just advance directly to the Game state.
m_manager.ChangeState(BossRoomState.GAME, null);
}
}
}

11
Assets/Scripts/Shared/Game/CharSelectBRState.cs.meta


fileFormatVersion: 2
guid: fe598b22e9599b540a40723c8d48686a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

40
Assets/Scripts/Shared/Game/GameBRState.cs


using System;
using System.Collections.Generic;
using UnityEngine;
using BossRoom;
namespace BossRoom
{
class GameBRState : IBossRoomState
{
protected BossRoomStateManager m_manager;
public BossRoomState State { get { return BossRoomState.GAME; } }
public virtual void Destroy()
{
}
public virtual void Initialize(BossRoomStateManager manager, Dictionary<string, object> stateParams)
{
m_manager = manager;
Debug.Log("Entering GameBRState, advancing to SampleScene");
//this is an example of the slight weirdnesses of having "server" and "client" logic running in parallel on the host.
//This will get invoked twice; once as part of the SGameBRState, once as part of the CGameBRState. It might be tempting
//to move it to the CGameBRState exclusively, but that's not right--it really should happen on a dedicated server too.
//The only alternative I can think of is to add an "if(!IsHost)" check around this logic. There will always be some logic
//which it is not OK to do twice that will need this kind of special handling, although it's not clear to me yet how much.
UnityEngine.SceneManagement.SceneManager.LoadScene("SampleScene");
}
public virtual void Update()
{
}
}
}

11
Assets/Scripts/Shared/Game/GameBRState.cs.meta


fileFormatVersion: 2
guid: 19b55cfbf40aa244f9bd90143d441ee4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

33
Assets/Scripts/Shared/Game/IBossRoomState.cs


using System;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom
{
/// <summary>
/// Interface that models a single state of the BossRoom game. See BossRoomStateManager for more information.
/// </summary>
interface IBossRoomState
{
/// <summary>
/// Called when this BossRoomState is transitioned to.
/// <param name="stateParams"/>optional dictionary of parameters to be used by the new gamestate. </param>
/// </summary>
void Initialize( BossRoomStateManager manager, Dictionary<string,System.Object> stateParams=null );
/// <summary>
/// Called once per Update by the BossRoomStateManager.
/// </summary>
void Update();
/// <summary>
/// Called when this BossRoomState ends.
/// </summary>
void Destroy();
/// <summary>
/// What BossRoomState this object represents.
/// </summary>
BossRoomState State { get; }
}
}

11
Assets/Scripts/Shared/Game/IBossRoomState.cs.meta


fileFormatVersion: 2
guid: d6956349616d0304abbd589d59a797f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

25
Assets/Scripts/Shared/Net/GNH_Client.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom
{
/// <summary>
/// Client logic for the GameNetHub. Contains implementations for all of GameNetHub's S2C RPCs.
/// </summary>
public class GNH_Client
{
private GameNetHub m_hub;
public GNH_Client(GameNetHub hub)
{
m_hub = hub;
}
public void RecvConnectFinished(string targetScene, ConnectStatus status )
{
//TBD: switch to target scene.
}
}
}

26
Assets/Scripts/Shared/Net/GNH_Server.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace BossRoom
{
public class GNH_Server
{
private GameNetHub m_hub;
public GNH_Server(GameNetHub hub)
{
m_hub = hub;
}
public void RecvRequestConnect(string guid, ulong clientId)
{
//TODO: maintain a mapping of clientID to GUID, and handle the reconnect case.
//for the moment, just accept the change and point the client to "SampleScene". We will replace this
//with logic that selects between the Load
m_hub.S2C_ConnectFinished(clientId, "SampleScene", ConnectStatus.CONNECT);
}
}
}

26
Assets/Scripts/Shared/Net/StartupManager.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// This class manages the network startup flow in the MainMenu, when the user has selected
/// either "Connect" or "Host". In the case of "Host", the flow isn't very interesting--you just start
/// up the NetworkingManager in host mode and switch to the target scene.
///
/// In Connect mode, however, things are a bit more interesting. We must not only begin via the initial StartClient, but
/// also receive the first S2C RPC telling us what Scene to go to.
/// </summary>
public class StartupManager : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

/Assets/Scripts/Shared/Net/GNH_Client.cs.meta → /Assets/Scripts/Client/Net/GNH_Client.cs.meta

/Assets/Scripts/Shared/Net/GNH_Server.cs.meta → /Assets/Scripts/Server/Net/GNH_Server.cs.meta

/Assets/Scripts/Shared/Net/StartupManager.cs.meta → /Assets/Scripts/Server/Game/SCharSelectBRState.cs.meta

正在加载...
取消
保存