Created
January 6, 2019 21:33
-
-
Save warrickct/fb03d7e1e55bc05fbff8bf3dd5818bc9 to your computer and use it in GitHub Desktop.
Code Used for UDP Broadcasted Multiplayer used in River Gear VR
This file contains hidden or 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 System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Runtime.Serialization.Formatters.Binary; | |
using System.Text; | |
using UnityEngine; | |
public class Networking : MonoBehaviour { | |
UdpClient udp; | |
public int port = 9001; | |
IPEndPoint broadcastIp; | |
BinaryFormatter bf = new BinaryFormatter(); | |
public bool ignoreSelf = true; | |
string deviceId; | |
//warrick test | |
Dictionary<string, WireData> playerPositions = new Dictionary<string, WireData>(); | |
//making a smaller dictionary for convenience. Not implemented yet | |
Dictionary<string, PlayerPosition> positionList = new Dictionary<string, PlayerPosition>(); | |
public GameObject playerPrefab; | |
//warrick test end | |
//warrick not implemented yet | |
public class PlayerPosition | |
{ | |
public string playerId; | |
public Vector3 playerPosition; | |
public Quaternion playerRotation; | |
public PlayerPosition (string id, Vector3 position, Quaternion rotation) | |
{ | |
this.playerId = id; | |
this.playerPosition = position; | |
this.playerRotation = rotation; | |
} | |
} | |
[Serializable] | |
public class WireData | |
{ | |
public float x, y, z, u, v, w; | |
public string id; | |
public WireData(float x, float y, float z, float u, float v, float w, string id) | |
{ | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
this.u = u; | |
this.v = v; | |
this.w = w; | |
this.id = id; | |
} | |
} | |
// Use this for initialization | |
void Start () { | |
udp = new UdpClient(port); | |
broadcastIp = new IPEndPoint(IPAddress.Broadcast, port); | |
deviceId = SystemInfo.deviceUniqueIdentifier; | |
InvokeRepeating("BroadcastPosition", 0f, 0.1f); | |
//warrick test | |
//wont let me call instantiate from a thread that isn't main (start/awake) so trying this to fix it | |
//compile works but gets synchronisation error | |
InvokeRepeating("GetPositions", 0f, 0.1f); | |
//warrick test end | |
Debug.Log("Listening on " + port); | |
udp.EnableBroadcast = true; | |
udp.BeginReceive(new AsyncCallback(OnUdpData), udp); | |
} | |
void BroadcastPosition() | |
{ | |
MemoryStream ms = new MemoryStream(); | |
var p = transform.position; | |
var r = transform.rotation.eulerAngles; | |
var wd = new WireData(p.x, p.y, p.z, r.x, r.y, r.z, deviceId); | |
bf.Serialize(ms, wd); | |
var bytes = ms.ToArray(); | |
udp.Send(bytes, bytes.Length, broadcastIp); | |
Debug.Log("broadcast " + bytes.Length + " bytes"); | |
} | |
void GetPositions() | |
{ | |
foreach (var player in playerPositions) | |
{ | |
//loop through the dictionary and update the wiredata at device w.id with the position/rotation | |
GameObject newPlayer = (GameObject)Instantiate(playerPrefab, ); | |
//GameObject newPlayer = (GameObject)Instantiate(playerPrefab, new Vector3(0, 0, 0), Quaternion.identity); | |
//can't loop through a dictionary that'll change whilst looping. Make list of keys from dict | |
//and iterate over that list then use the list to make instantiations. | |
} | |
} | |
void OnUdpData(IAsyncResult result) | |
{ | |
// this is what had been passed into BeginReceive as the second parameter: | |
UdpClient socket = result.AsyncState as UdpClient; | |
// points towards whoever had sent the message: | |
IPEndPoint source = new IPEndPoint(0, 0); | |
// get the actual message and fill out the source: | |
byte[] buffer = socket.EndReceive(result, ref source); | |
var ms = new MemoryStream(buffer); | |
WireData wd = (WireData)bf.Deserialize(ms); | |
if (wd.id != deviceId || !ignoreSelf) | |
{ | |
var p = new Vector3(wd.x, wd.y, wd.z); | |
var r = new Vector3(wd.u, wd.v, wd.z); | |
Debug.Log(wd.id + " is at " + p + " with rotation " + r); | |
//warrick test | |
//if wiredata device id isn't already in dictionary then add it to the dict | |
if (!playerPositions.ContainsKey (wd.id)) { | |
playerPositions.Add (wd.id, wd); | |
} else { | |
playerPositions [wd.id] = (); | |
} | |
//warrick test end | |
} | |
// schedule the next receive operation once reading is done: | |
socket.BeginReceive(new AsyncCallback(OnUdpData), socket); | |
} | |
// Update is called once per frame | |
void Update () { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment