Make so that player see eachothers capsules staticly
This commit is contained in:
parent
0df99b4bc8
commit
eb23f474c5
@ -34,7 +34,7 @@ namespace Cyber.Entities {
|
||||
/// set if they exist already (eg. the server has sent them over). These
|
||||
/// ids should be from <see cref="SyncDB.GetEntityIDs"/>. To create new
|
||||
/// ids, leave as the default (null).</param>
|
||||
public GameObject Spawn(EntityType type, Vector3 position, uint[] ids = null) {
|
||||
public GameObject Spawn(EntityType type, Vector3 position, int[] ids = null) {
|
||||
GameObject Spawned = null;
|
||||
switch (type) {
|
||||
case EntityType.PC:
|
||||
@ -55,7 +55,6 @@ namespace Cyber.Entities {
|
||||
}
|
||||
|
||||
private void Start() {
|
||||
Spawn(EntityType.PC, new Vector3());
|
||||
}
|
||||
|
||||
private void Update() {
|
||||
|
@ -14,6 +14,6 @@ namespace Cyber.Entities {
|
||||
/// The ID this syncable component can be found with from its parent
|
||||
/// <see cref="SyncDB"/>.
|
||||
/// </summary>
|
||||
public uint ID;
|
||||
public int ID;
|
||||
}
|
||||
}
|
@ -15,8 +15,8 @@ namespace Cyber.Entities {
|
||||
typeof(Character)
|
||||
};
|
||||
|
||||
private uint IDCounter = 0;
|
||||
private Dictionary<uint, SyncBase> Database = new Dictionary<uint, SyncBase>();
|
||||
private int IDCounter = 0;
|
||||
private Dictionary<int, SyncBase> Database = new Dictionary<int, SyncBase>();
|
||||
|
||||
/// <summary>
|
||||
/// Add an entity to the database with the given IDs.
|
||||
@ -24,7 +24,7 @@ namespace Cyber.Entities {
|
||||
/// <param name="gameObject">Game object.</param>
|
||||
/// <param name="ids">The IDs. Should be from <see cref="GetEntityIDs"/> or
|
||||
/// <see cref="GetNewEntityIDs"/>, since the order is important.</param>
|
||||
public void AddEntity(GameObject gameObject, uint[] ids) {
|
||||
public void AddEntity(GameObject gameObject, int[] ids) {
|
||||
int Index = 0;
|
||||
for (int i = 0; i < SyncableClasses.Length; i++) {
|
||||
SyncBase Syncable = (SyncBase)gameObject.GetComponent(SyncableClasses[i]);
|
||||
@ -44,8 +44,8 @@ namespace Cyber.Entities {
|
||||
/// <param name="newIDs">Whether or not new IDs are created.
|
||||
/// <see cref="GetNewEntityIDs"/> is a shorthand for this function with
|
||||
/// this parameter set to true.</param>
|
||||
public uint[] GetEntityIDs(GameObject gameObject, bool newIDs = false) {
|
||||
List<uint> IDs = new List<uint>();
|
||||
public int[] GetEntityIDs(GameObject gameObject, bool newIDs = false) {
|
||||
List<int> IDs = new List<int>();
|
||||
for (int i = 0; i < SyncableClasses.Length; i++) {
|
||||
SyncBase Syncable = (SyncBase)gameObject.GetComponent(SyncableClasses[i]);
|
||||
if (Syncable != null) {
|
||||
@ -55,7 +55,7 @@ namespace Cyber.Entities {
|
||||
IDs.Add(Syncable.ID);
|
||||
}
|
||||
}
|
||||
uint[] IDArray = new uint[IDs.Count];
|
||||
int[] IDArray = new int[IDs.Count];
|
||||
for (int i = 0; i < IDs.Count; i++) {
|
||||
IDArray[i] = IDs[i];
|
||||
}
|
||||
@ -68,7 +68,7 @@ namespace Cyber.Entities {
|
||||
/// </summary>
|
||||
/// <returns>The new IDs.</returns>
|
||||
/// <param name="gameObject">Game object.</param>
|
||||
public uint[] GetNewEntityIDs(GameObject gameObject) {
|
||||
public int[] GetNewEntityIDs(GameObject gameObject) {
|
||||
return GetEntityIDs(gameObject, true);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ namespace Cyber.Entities {
|
||||
/// Get a synced component by its ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID.</param>
|
||||
public SyncBase Get(uint id) {
|
||||
public SyncBase Get(int id) {
|
||||
return Database[id];
|
||||
}
|
||||
|
||||
@ -84,17 +84,17 @@ namespace Cyber.Entities {
|
||||
/// Creates a new ID which isn't in use yet.
|
||||
/// </summary>
|
||||
/// <returns>A new, free ID.</returns>
|
||||
public uint CreateID() {
|
||||
uint ID;
|
||||
public int CreateID() {
|
||||
int ID;
|
||||
try {
|
||||
ID = IDCounter++;
|
||||
} catch (OverflowException) {
|
||||
ID = 0;
|
||||
IDCounter = 1;
|
||||
}
|
||||
while (Database.ContainsKey(ID) && ID < uint.MaxValue) {
|
||||
while (Database.ContainsKey(ID) && ID < int.MaxValue) {
|
||||
ID++;
|
||||
if (ID < uint.MaxValue - 1)
|
||||
if (ID < int.MaxValue - 1)
|
||||
IDCounter = ID + 1;
|
||||
}
|
||||
if (Database.ContainsKey(ID)) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Cyber.Console;
|
||||
using Cyber.Entities;
|
||||
using Cyber.Networking.Messages;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
@ -24,11 +25,13 @@ namespace Cyber.Networking.Clientside {
|
||||
|
||||
private static Client Singleton;
|
||||
|
||||
private Spawner Spawner;
|
||||
|
||||
/// <summary>
|
||||
/// The player of this client
|
||||
/// </summary>
|
||||
private CConnectedPlayer Player;
|
||||
private List<CConnectedPlayer> Players = new List<CConnectedPlayer>();
|
||||
private Dictionary<int, CConnectedPlayer> Players = new Dictionary<int, CConnectedPlayer>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the client and sets it as the signleton.
|
||||
@ -86,6 +89,11 @@ namespace Cyber.Networking.Clientside {
|
||||
return Singleton.NetClient.isConnected;
|
||||
}
|
||||
|
||||
|
||||
private void Start() {
|
||||
Spawner = GetComponent<Spawner>();
|
||||
}
|
||||
|
||||
private bool LaunchClient(string ip, int port) {
|
||||
if (Running) {
|
||||
return false;
|
||||
@ -104,6 +112,7 @@ namespace Cyber.Networking.Clientside {
|
||||
NetClient.RegisterHandler(PktType.TextMessage, HandlePacket);
|
||||
NetClient.RegisterHandler(PktType.Identity, HandlePacket);
|
||||
NetClient.RegisterHandler(PktType.MassIdentity, HandlePacket);
|
||||
NetClient.RegisterHandler(PktType.SpawnEntity, HandlePacket);
|
||||
|
||||
NetClient.RegisterHandler(MsgType.Connect, OnConnected);
|
||||
NetClient.RegisterHandler(MsgType.Disconnect, OnDisconnected);
|
||||
@ -134,15 +143,27 @@ namespace Cyber.Networking.Clientside {
|
||||
Debug.Log(Conn.ConnectionID + " connected!");
|
||||
Term.Println(Conn.ConnectionID + " connected!");
|
||||
}
|
||||
Players.Add(Conn);
|
||||
Players.Add(Conn.ConnectionID, Conn);
|
||||
break;
|
||||
case (PktType.MassIdentity):
|
||||
MassIdentityPkt Identities = new MassIdentityPkt();
|
||||
Identities.Deserialize(msg.reader);
|
||||
foreach (int currId in Identities.IdList) {
|
||||
Players.Add(new CConnectedPlayer(currId));
|
||||
Players.Add(currId, new CConnectedPlayer(currId));
|
||||
}
|
||||
break;
|
||||
case (PktType.SpawnEntity):
|
||||
SpawnEntityPkt SpawnPkt = new SpawnEntityPkt();
|
||||
SpawnPkt.Deserialize(msg.reader);
|
||||
|
||||
EntityType EntityType = SpawnPkt.EntityType;
|
||||
// Check if you are the owner and if they are spawning an NPC
|
||||
if (SpawnPkt.OwnerID == Player.ConnectionID && EntityType == EntityType.NPC) {
|
||||
// Change it into a PC instead.
|
||||
EntityType = EntityType.PC;
|
||||
}
|
||||
Spawner.Spawn(EntityType, SpawnPkt.Position, SpawnPkt.SyncBaseIDList);
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("Received an unknown packet, id: " + msg.msgType);
|
||||
Term.Println("Received an unknown packet, id: " + msg.msgType);
|
||||
|
@ -8,16 +8,30 @@ namespace Cyber.Networking.Messages {
|
||||
/// </summary>
|
||||
public class MassIdentityPkt : MessageBase {
|
||||
|
||||
/// <summary>
|
||||
/// List of Connection ID's to send
|
||||
/// </summary>
|
||||
public int[] IdList;
|
||||
|
||||
/// <summary>
|
||||
/// Create a Mass Identity packet used to send a list of currently online connections.
|
||||
/// </summary>
|
||||
/// <param name="idList"></param>
|
||||
public MassIdentityPkt(int[] idList) {
|
||||
IdList = idList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameter-less constructor using when deserializing the message.
|
||||
/// </summary>
|
||||
public MassIdentityPkt() {
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize a message received via networking.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
public override void Deserialize(NetworkReader reader) {
|
||||
byte[][] ByteArray = new byte[4][];
|
||||
ByteArray[0] = reader.ReadBytesAndSize();
|
||||
@ -27,6 +41,10 @@ namespace Cyber.Networking.Messages {
|
||||
IdList = NetworkHelper.DeserializeIntArray(ByteArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to serialize the message before it is sent.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
public override void Serialize(NetworkWriter writer) {
|
||||
byte[][] ByteArray = NetworkHelper.SerializeIntArray(IdList);
|
||||
writer.WriteBytesFull(ByteArray[0]);
|
||||
|
86
Assets/Scripts/Networking/Messages/SpawnEntityPkt.cs
Normal file
86
Assets/Scripts/Networking/Messages/SpawnEntityPkt.cs
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
using Cyber.Entities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Cyber.Networking.Messages {
|
||||
|
||||
/// <summary>
|
||||
/// Packet which tells the client to spawn an entity corresponding to the data inside.
|
||||
/// </summary>
|
||||
public class SpawnEntityPkt : MessageBase {
|
||||
|
||||
/// <summary>
|
||||
/// The type of entity to spawn.
|
||||
/// </summary>
|
||||
public EntityType EntityType;
|
||||
/// <summary>
|
||||
/// The position of the entity, where it should be spawned
|
||||
/// </summary>
|
||||
public Vector3 Position;
|
||||
/// <summary>
|
||||
/// The List of Sync ID's for the entity.
|
||||
/// </summary>
|
||||
public int[] SyncBaseIDList;
|
||||
|
||||
/// <summary>
|
||||
/// Connection ID of the owner of this entity
|
||||
/// </summary>
|
||||
public int OwnerID;
|
||||
|
||||
/// <summary>
|
||||
/// Create a packet of information about spawning an entity to send the clients.
|
||||
/// </summary>
|
||||
/// <param name="entityType">Type of entity to spawn.</param>
|
||||
/// <param name="position">Position where the entity will be spawned.</param>
|
||||
/// <param name="syncIDList">List of Sync ID's for the entity.</param>
|
||||
/// <param name="ownerID">The Connection ID who owns this entity (or -1).</param>
|
||||
public SpawnEntityPkt(EntityType entityType, Vector3 position, int[] syncIDList, int ownerID) {
|
||||
EntityType = entityType;
|
||||
Position = position;
|
||||
SyncBaseIDList = syncIDList;
|
||||
OwnerID = ownerID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameter-less constructor using when deserializing the message.
|
||||
/// </summary>
|
||||
public SpawnEntityPkt() {
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize a message received via networking.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
public override void Deserialize(NetworkReader reader) {
|
||||
EntityType = (EntityType) reader.ReadInt16();
|
||||
Position = reader.ReadVector3();
|
||||
OwnerID = reader.ReadInt32();
|
||||
|
||||
byte[][] ByteArray = new byte[4][];
|
||||
ByteArray[0] = reader.ReadBytesAndSize();
|
||||
ByteArray[1] = reader.ReadBytesAndSize();
|
||||
ByteArray[2] = reader.ReadBytesAndSize();
|
||||
ByteArray[3] = reader.ReadBytesAndSize();
|
||||
SyncBaseIDList = NetworkHelper.DeserializeIntArray(ByteArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to serialize the message before it is sent.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
public override void Serialize(NetworkWriter writer) {
|
||||
writer.Write((short) EntityType);
|
||||
writer.Write(Position);
|
||||
writer.Write(OwnerID);
|
||||
|
||||
byte[][] ByteArray = NetworkHelper.SerializeIntArray(SyncBaseIDList);
|
||||
writer.WriteBytesFull(ByteArray[0]);
|
||||
writer.WriteBytesFull(ByteArray[1]);
|
||||
writer.WriteBytesFull(ByteArray[2]);
|
||||
writer.WriteBytesFull(ByteArray[3]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
12
Assets/Scripts/Networking/Messages/SpawnEntityPkt.cs.meta
Normal file
12
Assets/Scripts/Networking/Messages/SpawnEntityPkt.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bcdedfecd6ba4a04397852ba038f0939
|
||||
timeCreated: 1494296640
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -20,5 +20,10 @@ namespace Cyber.Networking {
|
||||
/// Packet containing the identification details about everyone on the server before the client connected.
|
||||
/// </summary>
|
||||
public const short MassIdentity = 202;
|
||||
|
||||
/// <summary>
|
||||
/// Packet containing necessary information about spawning an entity.
|
||||
/// </summary>
|
||||
public const short SpawnEntity = 203;
|
||||
}
|
||||
}
|
@ -11,9 +11,10 @@ namespace Cyber.Networking.Serverside {
|
||||
/// Server-class used to host a server and communicate to clients.
|
||||
/// </summary>
|
||||
/// \todo Change connection channels to Unreliable to optimize ping.
|
||||
/// \todo Remove PC/NPC and make a Human-type entity instead.
|
||||
public class Server : MonoBehaviour {
|
||||
|
||||
private List<SConnectedPlayer> Players = new List<SConnectedPlayer>();
|
||||
private Dictionary<int, SConnectedPlayer> Players = new Dictionary<int, SConnectedPlayer>();
|
||||
private static Server Singleton;
|
||||
|
||||
private Spawner Spawner;
|
||||
@ -131,27 +132,50 @@ namespace Cyber.Networking.Serverside {
|
||||
// Internal built-in event handler
|
||||
|
||||
private void OnConnected(NetworkMessage msg) {
|
||||
// Get client's ID
|
||||
int Id = msg.conn.connectionId;
|
||||
|
||||
Debug.Log(Id + " connected!");
|
||||
Term.Println(Id + " connected!");
|
||||
|
||||
// Send all other clients a notification and collect their id's
|
||||
int[] IdList = new int[Players.Count];
|
||||
for (int i = 0; i < Players.Count; i++) {
|
||||
SConnectedPlayer P = Players[i];
|
||||
IdList[i] = P.ConnectionID;
|
||||
int TempCounter = 0;
|
||||
foreach (SConnectedPlayer P in Players.Values) {
|
||||
IdList[TempCounter++] = P.ConnectionID;
|
||||
NetworkServer.SendToClient(P.ConnectionID, PktType.Identity, new IdentityPkt(Id, false));
|
||||
}
|
||||
foreach (int id in IdList) {
|
||||
Debug.Log("id: " + id);
|
||||
}
|
||||
|
||||
// Then send the client a list of all other clients
|
||||
NetworkServer.SendToClient(Id, PktType.MassIdentity, new MassIdentityPkt(IdList));
|
||||
|
||||
// Add the player to the list
|
||||
SConnectedPlayer Player = new SConnectedPlayer(msg.conn.connectionId);
|
||||
Players.Add(Player);
|
||||
Players.Add(Id, Player);
|
||||
|
||||
// Send the previously collected list to the player
|
||||
NetworkServer.SendToClient(msg.conn.connectionId,
|
||||
PktType.Identity, new IdentityPkt(msg.conn.connectionId, true));
|
||||
|
||||
// Spawn the player and collet it's IDs
|
||||
Vector3 Position = new Vector3(0, 0, 0);
|
||||
GameObject Obj = Spawner.Spawn(EntityType.NPC, Position);
|
||||
int[] EntityIdList = Spawner.SyncDB.GetEntityIDs(Obj);
|
||||
Player.Character = Obj.GetComponent<Character>();
|
||||
|
||||
NetworkServer.SendToAll(PktType.SpawnEntity, new SpawnEntityPkt(EntityType.NPC, Position, EntityIdList, Id));
|
||||
|
||||
// Send every entity to the player who just connected.
|
||||
foreach (var Entry in Players) {
|
||||
if (Entry.Key == Id) {
|
||||
continue;
|
||||
}
|
||||
Character Char = Players[Entry.Key].Character;
|
||||
GameObject CurrObj = Char.gameObject;
|
||||
int[] CurrEntityIdList = Spawner.SyncDB.GetNewEntityIDs(CurrObj);
|
||||
NetworkServer.SendToClient(Id, PktType.SpawnEntity,
|
||||
new SpawnEntityPkt(EntityType.NPC, CurrObj.transform.position, CurrEntityIdList, Entry.Key));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisconnected(NetworkMessage msg) {
|
||||
|
@ -47,5 +47,5 @@ Version 0.1.0 - Gigantic
|
||||
- [x] ...With movement capabilities.
|
||||
- [ ] Client-server connectivity, players can see each other moving around.
|
||||
- [x] 1. Client-server connectivity: the clients can connect to the server and send some messages back and forth.
|
||||
- [ ] 2. Players can see eachothers capsule-characters and send commands to move them around.
|
||||
- [x] 2. Players can see eachothers capsule-characters and send commands to move them around.
|
||||
- [ ] 3. Basic syncing (Send sync packages at certain intervals) in order to sync positions correctly between server and client.
|
||||
|
Loading…
Reference in New Issue
Block a user