您的位置:首页 > 移动开发 > Unity3D

Hololens 使用Unet共享详细教程(四)

2018-01-01 17:17 375 查看
Hello World!我是山谷大叔~接下来我将出一系列Hololens开发教程(Hololens API解析空间共享、第三视角Spatial
View
MR交互设计视音频通讯服务器开发,多人游戏实战……),感兴趣的朋友可以关注我哦。下面开始放干货!(后续视频教程 群211031265)

本节讲解锚点数据的传输.

要想多台HoloLens共享,我们之前已经完成了用Unet实现消息的同步,现在还需要同步空间锚点,这样就能实现多台设备看到的物体实是在同一位置了。

Windows.Networking.Sockets 服务器和客户端

//UWP 下的命名空间
#if !UNITY_EDITOR && UNITY_WSA
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Networking;
using Windows.Foundation;
using System.Threading.Tasks;
using System;
[Tooltip("网络连接端口")]
public int SendConnectionPort = 11000;
//IP地址
private string serverIP;
/// <summary>
/// 当数据到达时调用
/// </summary>
public delegate void OnDataReady(byte[] data);
public event OnDataReady dataReadyEvent;

/// <summary>
///是否有一个未完成的连接请求
/// </summary>
private bool waitingForConnection = false;

/// <summary>
/// 保存最新的数据缓冲区数据
/// </summary>
private byte[] mostRecentDataBuffer;

/// <summary>
///要传给其他连接者的锚点数据
/// </summary>
public void SetData(byte[] data)
{
mostRecentDataBuffer = data;
}

/// <summary>
///要传送锚点数据的设备IP
/// </summary>
public void SetServerIP(string ServerIP)
{
serverIP = ServerIP.Trim();
}

/// <summary>
///重新连接服务器获取数据
/// </summary>
public void RequestAndGetData()
{
ConnectListener();
}

//下面的代码只有只UWP下运行,编辑器下无法运行
#if !UNITY_EDITOR && UNITY_WSA

// 客户端Socket连接对象
private StreamSocket networkConnection;
//服务器Socket监听器
private StreamSocketListener networkListener;
//连接失败时重新连接的等待时间
private float timeToDeferFailedConnections = 10.0f;

//配置服务器
public void ConfigureAsServer()
{
//开始一个线程启动服务器监听
Task t = new Task(() =>
{
networkListener = new StreamSocketListener();
networkListener.ConnectionReceived += NetworkListener_ConnectionReceived;
networkListener.BindServiceNameAsync(SendConnectionPort.ToString()).GetResults();
}
);
t.Start();
}

// 有客户端连接时的回调
private void NetworkListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
//发送数据
if (mostRecentDataBuffer != null)
{
IOutputStream stream = args.Socket.OutputStream;
using (DataWriter writer = new DataWriter(stream))
{
writer.WriteInt32(mostRecentDataBuffer.Length);
writer.WriteBytes(mostRecentDataBuffer);
writer.StoreAsync().AsTask().Wait();
writer.FlushAsync().AsTask().Wait();
}
}
else
{
Debug.LogError("已经有客户端连接,但是没有要发送的数据!");
}
}

//连接服务器,获取数据
private void ConnectListener()
{
if (waitingForConnection)
{
return;
}
Debug.Log("Connecting to " + serverIP);
waitingForConnection = true;
HostName networkHost = new HostName(serverIP);
networkConnection = new StreamSocket();

IAsyncAction outstandingAction = networkConnection.ConnectAsync(networkHost, SendConnectionPort.ToString());
AsyncActionCompletedHandler aach = new AsyncActionCompletedHandler(RcvNetworkConnectedHandler);
outstandingAction.Completed = aach;
}

//当连接到服务器时,开始读取数据,调用此方法。
private async void RcvNetworkConnectedHandler(IAsyncAction asyncInfo, AsyncStatus status)
{
// 连接成功时
if (status == AsyncStatus.Completed)
{
DataReader networkDataReader;
//接收数据
using (networkDataReader = new DataReader(networkConnection.InputStream))
{
//读取前四个字节用于获取数据长度
DataReaderLoadOperation drlo = networkDataReader.LoadAsync(4);
while (drlo.Status == AsyncStatus.Started)
{
// just waiting.
}

int dataSize = networkDataReader.ReadInt32();
if (dataSize < 0)
{
Debug.Log("数据解析错误");
}

//新建一个dataSize大小的缓冲区。
mostRecentDataBuffer = new byte[dataSize];
//读取数据
await networkDataReader.LoadAsync((uint)dataSize);
networkDataReader.ReadBytes(mostRecentDataBuffer);
//读取完成后,调用注册的方法
dataReadyEvent?.Invoke(mostRecentDataBuffer);
}
}
else
{
Debug.Log("建立连接失败: " + asyncInfo.ErrorCode);
//重新连接
Invoke("RequestA
4000
ndGetAnchor", timeToDeferFailedConnections);
}
//断开连接
networkConnection.Dispose();
waitingForConnection = false;
}

#else
//配置服务器接口(实际调用在上面的同名方法)
public void ConfigureAsServer()
{
Debug.Log("ConfigureAsServer编辑器模式不执行");
}
//连接服务器,获取数据实际调用在上面的同名方法)
private void ConnectListener()
{
Debug.Log("ConnectListener编辑器模式不执行");
}
#endif


如果有什么疑问或者发现笔者的错误请留言!

下一节讲解 相关的内容~~~

获取源码请在群资料中下载

Hololens MR 技术交流群 211031265
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息