Mirror List Server example (#611)

feature: Mirror List Server example
This commit is contained in:
vis2k 2019-03-20 09:38:53 +01:00 committed by GitHub
parent c2d16c6a5a
commit 22640b5e62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 4428 additions and 0 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e192f90e0acbb41f88dfe3dba300a5c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,307 @@
// add this component to the NetworkManager
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
namespace Mirror.Examples.Listen
{
public class ServerStatus
{
public string ip;
//public ushort port; // <- not all transports use a port. assume default port. feel free to also send a port if needed.
public string title;
public ushort players;
public ushort capacity;
public int lastLatency = -1;
public Ping ping;
public ServerStatus(string ip, /*ushort port,*/ string title, ushort players, ushort capacity)
{
this.ip = ip;
//this.port = port;
this.title = title;
this.players = players;
this.capacity = capacity;
ping = new Ping(ip);
}
}
[RequireComponent(typeof(NetworkManager))]
public class ListServer : MonoBehaviour
{
[Header("Listen Server Connection")]
public string listServerIp = "127.0.0.1";
public ushort gameServerToListenPort = 8887;
public ushort clientToListenPort = 8888;
public string gameServerTitle = "Deathmatch";
Telepathy.Client gameServerToListenConnection = new Telepathy.Client();
Telepathy.Client clientToListenConnection = new Telepathy.Client();
[Header("UI")]
public GameObject mainPanel;
public Transform content;
public UIServerStatusSlot slotPrefab;
public Button serverAndPlayButton;
public Button serverOnlyButton;
public GameObject connectingPanel;
public Text connectingText;
public Button connectingCancelButton;
int connectingDots = 0;
// all the servers, stored as dict with unique ip key so we can
// update them more easily
// (use "ip:port" if port is needed)
Dictionary<string, ServerStatus> list = new Dictionary<string, ServerStatus>();
void Start()
{
// examples
//list["127.0.0.1"] = new ServerStatus("127.0.0.1", "Deathmatch", 3, 10);
//list["192.168.0.1"] = new ServerStatus("192.168.0.1", "Free for all", 7, 10);
//list["172.217.22.3"] = new ServerStatus("172.217.22.3", "5vs5", 10, 10);
//list["172.217.16.142"] = new ServerStatus("172.217.16.142", "Hide & Seek Mod", 0, 10);
// Update once a second. no need to try to reconnect or read data
// in each Update call
// -> calling it more than 1/second would also cause significantly
// more broadcasts in the list server.
InvokeRepeating(nameof(Tick), 0, 1);
}
bool IsConnecting() => NetworkClient.active && !ClientScene.ready;
bool FullyConnected() => NetworkClient.active && ClientScene.ready;
// should we use the client to listen connection?
bool UseClientToListen()
{
return !NetworkManager.IsHeadless() && !NetworkServer.active && !FullyConnected();
}
// should we use the game server to listen connection?
bool UseGameServerToListen()
{
return NetworkServer.active;
}
void Tick()
{
TickGameServer();
TickClient();
}
// send server status to list server
void SendStatus()
{
BinaryWriter writer = new BinaryWriter(new MemoryStream());
// create message
// NOTE: you can send anything that you want, as long as you also
// receive it in ParseMessage
char[] titleChars = gameServerTitle.ToCharArray();
writer.Write((ushort)titleChars.Length);
writer.Write(titleChars);
writer.Write((ushort)NetworkServer.connections.Count);
writer.Write((ushort)NetworkManager.singleton.maxConnections);
// send it
writer.Flush();
gameServerToListenConnection.Send(((MemoryStream)writer.BaseStream).ToArray());
}
void TickGameServer()
{
// send server data to listen
if (UseGameServerToListen())
{
// connected yet?
if (gameServerToListenConnection.Connected)
{
SendStatus();
}
// otherwise try to connect
// (we may have just started the game)
else if (!gameServerToListenConnection.Connecting)
{
Debug.Log("Establishing game server to listen connection...");
gameServerToListenConnection.Connect(listServerIp, gameServerToListenPort);
}
}
// shouldn't use game server, but still using it?
else if (gameServerToListenConnection.Connected)
{
gameServerToListenConnection.Disconnect();
}
}
void ParseMessage(byte[] bytes)
{
// use binary reader because our NetworkReader uses custom string reading with bools
// => we don't use ReadString here because the listen server doesn't
// know C#'s '7-bit-length + utf8' encoding for strings
BinaryReader reader = new BinaryReader(new MemoryStream(bytes, false), Encoding.UTF8);
ushort ipLength = reader.ReadUInt16();
string ip = new string(reader.ReadChars(ipLength));
//ushort port = reader.ReadUInt16(); <- not all Transports use a port. assume default.
ushort titleLength = reader.ReadUInt16();
string title = new string(reader.ReadChars(titleLength));
ushort players = reader.ReadUInt16();
ushort capacity = reader.ReadUInt16();
//Debug.Log("PARSED: ip=" + ip + /*" port=" + port +*/ " title=" + title + " players=" + players + " capacity= " + capacity);
// build key
string key = ip/* + ":" + port*/;
// find existing or create new one
ServerStatus server;
if (list.TryGetValue(key, out server))
{
// refresh
server.title = title;
server.players = players;
server.capacity = capacity;
}
else
{
// create
server = new ServerStatus(ip, /*port,*/ title, players, capacity);
}
// save
list[key] = server;
}
void TickClient()
{
// receive client data from listen
if (UseClientToListen())
{
// connected yet?
if (clientToListenConnection.Connected)
{
// receive latest game server info
while (clientToListenConnection.GetNextMessage(out Telepathy.Message message))
{
// data message?
if (message.eventType == Telepathy.EventType.Data)
ParseMessage(message.data);
}
// ping again if previous ping finished
foreach (ServerStatus server in list.Values)
{
if (server.ping.isDone)
{
server.lastLatency = server.ping.time;
server.ping = new Ping(server.ip);
}
}
}
// otherwise try to connect
// (we may have just joined the menu/disconnect from game server)
else if (!clientToListenConnection.Connecting)
{
Debug.Log("Establishing client to listen connection...");
clientToListenConnection.Connect(listServerIp, clientToListenPort);
}
}
// shouldn't use client, but still using it? (e.g. after joining)
else if (clientToListenConnection.Connected)
{
clientToListenConnection.Disconnect();
list.Clear();
}
// refresh UI afterwards
OnUI();
}
// instantiate/remove enough prefabs to match amount
public static void BalancePrefabs(GameObject prefab, int amount, Transform parent)
{
// instantiate until amount
for (int i = parent.childCount; i < amount; ++i)
{
GameObject go = GameObject.Instantiate(prefab);
go.transform.SetParent(parent, false);
}
// delete everything that's too much
// (backwards loop because Destroy changes childCount)
for (int i = parent.childCount-1; i >= amount; --i)
GameObject.Destroy(parent.GetChild(i).gameObject);
}
void OnUI()
{
// only show while client not connected and server not started
if (!NetworkManager.singleton.isNetworkActive || IsConnecting())
{
mainPanel.SetActive(true);
// instantiate/destroy enough slots
BalancePrefabs(slotPrefab.gameObject, list.Count, content);
// refresh all members
for (int i = 0; i < list.Values.Count; ++i)
{
UIServerStatusSlot slot = content.GetChild(i).GetComponent<UIServerStatusSlot>();
ServerStatus server = list.Values.ToList()[i];
slot.titleText.text = server.title;
slot.playersText.text = server.players + "/" + server.capacity;
slot.latencyText.text = server.lastLatency != -1 ? server.lastLatency.ToString() : "...";
slot.addressText.text = server.ip;
slot.joinButton.interactable = !IsConnecting();
slot.joinButton.gameObject.SetActive(server.players < server.capacity);
slot.joinButton.onClick.RemoveAllListeners();
slot.joinButton.onClick.AddListener(() => {
NetworkManager.singleton.networkAddress = server.ip;
NetworkManager.singleton.StartClient();
});
}
// server buttons
serverAndPlayButton.interactable = !IsConnecting();
serverAndPlayButton.onClick.RemoveAllListeners();
serverAndPlayButton.onClick.AddListener(() => {
NetworkManager.singleton.StartHost();
});
serverOnlyButton.interactable = !IsConnecting();
serverOnlyButton.onClick.RemoveAllListeners();
serverOnlyButton.onClick.AddListener(() => {
NetworkManager.singleton.StartServer();
});
}
else mainPanel.SetActive(false);
// show connecting panel while connecting
if (IsConnecting())
{
connectingPanel.SetActive(true);
// . => .. => ... => ....
connectingDots = ((connectingDots + 1) % 4);
connectingText.text = "Connecting" + new string('.', connectingDots);
// cancel button
connectingCancelButton.onClick.RemoveAllListeners();
connectingCancelButton.onClick.AddListener(NetworkManager.singleton.StopClient);
}
else connectingPanel.SetActive(false);
}
// disconnect everything when pressing Stop in the Editor
void OnApplicationQuit()
{
if (gameServerToListenConnection.Connected)
gameServerToListenConnection.Disconnect();
if (clientToListenConnection.Connected)
clientToListenConnection.Disconnect();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69f796b44735c414783d66f47b150c5f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9826d673f42ad4c59b8fc27ae86729e1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b7816657e55c04901be36ace7275ad85
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ccdea83d270df4b078963a0243e41ac0
timeCreated: 1426587410
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8d7b75cc57dee4425af050c10508257a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,651 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1009505356919436
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224428085307354514}
- component: {fileID: 222534217462828066}
- component: {fileID: 114077992825021022}
m_Layer: 5
m_Name: TextPlayers
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224428085307354514
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1009505356919436}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224813910264502154}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 60, y: 16}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222534217462828066
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1009505356919436}
m_CullTransparentMesh: 0
--- !u!114 &114077992825021022
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1009505356919436}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 5
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '[Players]'
--- !u!1 &1165846264137056
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224595697833923954}
- component: {fileID: 222565095748274674}
- component: {fileID: 114410999938197916}
m_Layer: 5
m_Name: TextLatency
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224595697833923954
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1165846264137056}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224813910264502154}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 60, y: 16}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222565095748274674
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1165846264137056}
m_CullTransparentMesh: 0
--- !u!114 &114410999938197916
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1165846264137056}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 5
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '[Latency]'
--- !u!1 &1259177336467004
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224813910264502154}
- component: {fileID: 222443701544564472}
- component: {fileID: 114424214131292870}
- component: {fileID: 114617214395066132}
- component: {fileID: 114618400118094574}
- component: {fileID: 114611570997501482}
m_Layer: 5
m_Name: ServerStatusSlot
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224813910264502154
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224596263305646570}
- {fileID: 224428085307354514}
- {fileID: 224595697833923954}
- {fileID: 2588874080615256095}
- {fileID: 224530003443674914}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222443701544564472
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_CullTransparentMesh: 0
--- !u!114 &114424214131292870
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.2509804, g: 0.2509804, b: 0.2509804, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!114 &114617214395066132
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1741964061, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalFit: 0
m_VerticalFit: 2
--- !u!114 &114618400118094574
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -405508275, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Padding:
m_Left: 4
m_Right: 2
m_Top: 1
m_Bottom: 1
m_ChildAlignment: 0
m_Spacing: 0
m_ChildForceExpandWidth: 0
m_ChildForceExpandHeight: 0
m_ChildControlWidth: 0
m_ChildControlHeight: 0
--- !u!114 &114611570997501482
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1259177336467004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7f24d39c9182b4098bcfd0c2546d0bf2, type: 3}
m_Name:
m_EditorClassIdentifier:
titleText: {fileID: 114105517410707240}
playersText: {fileID: 114077992825021022}
latencyText: {fileID: 114410999938197916}
addressText: {fileID: 1711666012325280996}
joinButton: {fileID: 114358377111651776}
--- !u!1 &1368168976437814
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224596263305646570}
- component: {fileID: 222703717971346548}
- component: {fileID: 114105517410707240}
m_Layer: 5
m_Name: TextTitle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224596263305646570
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1368168976437814}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224813910264502154}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 218, y: 16}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222703717971346548
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1368168976437814}
m_CullTransparentMesh: 0
--- !u!114 &114105517410707240
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1368168976437814}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 3
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '[Title]'
--- !u!1 &1462871638010074
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224530003443674914}
- component: {fileID: 222322555260831376}
- component: {fileID: 114653458098104780}
- component: {fileID: 114358377111651776}
m_Layer: 5
m_Name: ButtonJoin
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224530003443674914
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1462871638010074}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224615151935076648}
m_Father: {fileID: 224813910264502154}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 40, y: 18}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222322555260831376
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1462871638010074}
m_CullTransparentMesh: 0
--- !u!114 &114653458098104780
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1462871638010074}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
--- !u!114 &114358377111651776
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1462871638010074}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 1
m_Colors:
m_NormalColor: {r: 0.32156864, g: 0.32156864, b: 0.32156864, a: 1}
m_HighlightedColor: {r: 0.3529412, g: 0.3529412, b: 0.3529412, a: 1}
m_PressedColor: {r: 0.3882353, g: 0.3882353, b: 0.3882353, a: 1}
m_DisabledColor: {r: 0.3882353, g: 0.3882353, b: 0.3882353, a: 0.37254903}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 114653458098104780}
m_OnClick:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null
--- !u!1 &1575165076438694
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 224615151935076648}
- component: {fileID: 222903696298421472}
- component: {fileID: 114447744505293664}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &224615151935076648
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575165076438694}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224530003443674914}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &222903696298421472
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575165076438694}
m_CullTransparentMesh: 0
--- !u!114 &114447744505293664
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575165076438694}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Join
--- !u!1 &2231260898927249423
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2588874080615256095}
- component: {fileID: 2389080155505640677}
- component: {fileID: 1711666012325280996}
m_Layer: 5
m_Name: TextAddress
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2588874080615256095
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2231260898927249423}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224813910264502154}
m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 130, y: 16}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2389080155505640677
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2231260898927249423}
m_CullTransparentMesh: 0
--- !u!114 &1711666012325280996
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2231260898927249423}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 12
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MaxSize: 40
m_Alignment: 5
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: '[Address]'

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 611330311f6094567ad2f8012b470129
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
// Attach to the prefab for easier component access by the UI Scripts.
// Otherwise we would need slot.GetChild(0).GetComponentInChildren<Text> etc.
using UnityEngine;
using UnityEngine.UI;
public class UIServerStatusSlot : MonoBehaviour
{
public Text titleText;
public Text playersText;
public Text latencyText;
public Text addressText;
public Button joinButton;
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f24d39c9182b4098bcfd0c2546d0bf2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5,3 +5,4 @@ EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes: []
m_configObjects: {}