Unity3D 使用Socket处理数据并将数据 在UGUI、NGUI上显示出来
Unity3d 不支持C#的线程直接调用Unity3D 主线程才能实现的功能。例如:给UGUI text 赋值、改变Color值等。怎样解决这个问题呢?使用一个Loom脚本。
按照惯例贴上代码。
首先Loom脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using System.Linq;
public class Loom : MonoBehaviour
{
public static int maxThreads = 8;
static int numThreads;
private static Loom _current;
private int _count;
public static Loom Current
{
get
{
Initialize();
return _current;
}
}
void Awake()
{
_current = this;
initialized = true;
}
static bool initialized;
static void Initialize()
{
if (!initialized)
{
if (!Application.isPlaying)
return;
initialized = true;
var g = new GameObject("Loom");
_current = g.AddComponent<Loom>();
}
}
private List<System.Action> _actions = new List<System.Action>();
public struct DelayedQueueItem
{
public float time;
public System.Action action;
}
private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
public static void QueueOnMainThread(System.Action action)
{
QueueOnMainThread(action, 0f);
}
public static void QueueOnMainThread(System.Action action, float time)
{
if (time != 0)
{
lock (Current._delayed)
{
Current._delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action });
}
}
else
{
lock (Current._actions)
{
Current._actions.Add(action);
}
}
}
public static Thread RunAsync(System.Action a)
{
Initialize();
while (numThreads >= maxThreads)
{
Thread.Sleep(1);
}
Interlocked.Increment(ref numThreads);
ThreadPool.QueueUserWorkItem(RunAction, a);
return null;
}
private static void RunAction(object action)
{
try
{
((System.Action)action)();
}
catch
{
}
finally
{
Interlocked.Decrement(ref numThreads);
}
}
void OnDisable()
{
if (_current == this)
{
_current = null;
}
}
// Use this for initialization
void Start()
{
}
List<System.Action> _currentActions = new List<System.Action>();
// Update is called once per frame
void Update()
{
lock (_actions)
{
_currentActions.Clear();
_currentActions.AddRange(_actions);
_actions.Clear();
}
foreach (var a in _currentActions)
{
a();
}
lock (_delayed)
{
_currentDelayed.Clear();
_currentDelayed.AddRange(_delayed.Where(d => d.time <= Time.time));
foreach (var item in _currentDelayed)
_delayed.Remove(item);
}
foreach (var delayed in _currentDelayed)
{
delayed.action();
}
}
}
/*
* 调用案例
*/
//public class LoomUse
//{
// void ScaleMesh(Mesh mesh, float scale)
// {
//
// var vertices = mesh.vertices;
// //Run the action on a new thread
// Loom.RunAsync(() =>
// {
// //Loop through the vertices
// for (var i = 0; i < vertices.Length; i++)
// {
// //Scale the vertex
// vertices[i] = vertices[i] * scale;
// }
// //Run some code on the main thread
// //to update the mesh
// Loom.QueueOnMainThread(() =>
// {
// //Set the vertices
// mesh.vertices = vertices;
// //Recalculate the bounds
// mesh.RecalculateBounds();
// });
// });
// }
//}
其次: Socket脚本
using System;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace ReceiveMessage
{
class ReceiveMessage : MonoBehaviour
{
public delegate void ReceiveMes(string str);
public static event ReceiveMes receiveMes;
//在内存中开辟一块1024缓存区域
private static byte[] result = new byte[1024];
//自定义一个端口
private static int myProt = 8009;
//定义服务器 Socket 对象
private static Socket serverSocket;
private static int SencenNum = 0;
public Button mListenButton;
public Text mMainMessagetext;
private Thread MainThread;
public GameObject[] obj;
public string getInfo;
public object Wait { get; private set; }
void Start()
{
mListenButton.onClick.AddListener(ListenFunction);
}
//private void Update()
//{
// mMainMessagetext.text = getInfo;
//}
void ListenFunction()
{
DontDestroyOnLoad(this.gameObject);
IPAddress ip = IPAddress.Parse("192.168.2.176");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt));
serverSocket.Listen(10);
Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
MainThread = new Thread(ListenClientConnect);
MainThread.Start();
}
private void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept();
clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
Thread receiveThread = new Thread(ReceiveMessage1);
receiveThread.Start(clientSocket);
}
}
private void ReceiveMessage1(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;
Boolean b = true;
while (b)
{
try
{
int receiveNumber = myClientSocket.Receive(result);
string str = Encoding.UTF8.GetString(result, 0, receiveNumber);
if (str.Equals(""))
{
b = false;
}
else
{
Loom.RunAsync(() =>
{
//处理普通数据 例如:1+1,
Loom.QueueOnMainThread(() =>
{
receiveMes(str);// 调到 unity3d 主线程上
});
});
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
}
}
}
}
最后,UGUI 页面
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
namespace ReceiveMessage
{
public class Test : MonoBehaviour
{
public Text mText;
private void OnEnable()
{
ReceiveMessage.receiveMes += ReceiveMes;
}
private void Start()
{
if (mText == null)
{
mText = GetComponent<Text>();
}
}
private void OnDisable()
{
ReceiveMessage.receiveMes -= ReceiveMes;
}
private void OnDestroy()
{
ReceiveMessage.receiveMes -= ReceiveMes;
}
public void ReceiveMes(string str)
{
if (mText)
{
mText.text = str;
}
}
}
}
总结,Loom是一个单例脚本,必须挂在场景中一个空物体上,不然,Loom不起作用
Unity3D 使用Socket处理数据并将数据 在UGUI、NGUI上显示出来的更多相关文章
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- C# Socket Server 收不到数据
#/usr/bin/env python # -*- coding: utf- -*- # C# Socket Server 收不到数据 # 说明: # 最近在调Python通过Socket Clie ...
- ActionScript接收socket服务器发送来的数据
原文地址:http://www.asp119.com/news/2009522181815_1.htm 从socket中接收数据的方法取决于你使用socket类型,Socket和XMLSocket都可 ...
- Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结
Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结 分类具体知识点原理规范具体实现(oracle,mysql,mssql是否可以自己实现说明 数据库理论数据库的类型 数据 ...
- Java基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据
1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协 ...
- Java基础知识强化之网络编程笔记03:UDP之UDP协议发送数据 和 接收数据
1. UDP协议发送数据 和 接收数据 UDP协议发送数据: • 创建发送端的Socket对象 • 创建数据,并把数据打包 • 调用Socket对象的发送方法,发送数据包 • 释放资源 UDP协议接 ...
- 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换
[源码下载] 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换 作者:webabcd 介绍速战速决 之 PHP ...
- ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理
话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...
- Web jquery表格组件 JQGrid 的使用 - 7.查询数据、编辑数据、删除数据
系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...
随机推荐
- cf round 598div3 D.Binary String Minimizing
题目:https://codeforces.com/contest/1256/problem/D 题意:给你长度为n的01串,能将任意两相邻字符交换k次,求最小字典序的交换结果. 思路:贪心...甚至 ...
- 5分钟教你看大神操作keepalived服务
第11章 高可用服务(keepalived)的配置 11.1 高可用服务的概念 11.1.1 高可用服务总体概念 为了解决单点故障 减轻服务器的压力 11.1.2 高可用keepalived的概念 为 ...
- Bootstrap响应式栅格系统设计
为了方便起见,我们通过1200px宽的屏幕来讲解bootstrap中container.row.col的css属性值为何这样设置的原理 在1200px屏幕中为何container的宽度设置为1170p ...
- Django(一):url路由配置和模板渲染
urls.py路由用法 url基本概念 url格式 urls.py的作用 url解析过程 include的作用 kwarg的作用 name的作用 URL概念 URL(Uniform Resoure L ...
- vue click.stop阻止点击事件继续传播
<div id="app"> <div @click="dodo"> <button @:click="doThis&q ...
- 基于WCF 的远程数据库服务访问技术
原文出处:http://www.lw80.cn/shuji/jsjlw/13588Htm.Htm摘要:本文介绍了使用WCF 建立和运行面向服务(SOA)的数据库服务的系统结构和技术要素,分析了WCF ...
- 防止DataGridview闪烁
在Load事件中加入 typeof(DataGridView).InvokeMember("DoubleBuffered", BindingFlags.NonPublic | Bi ...
- pip和conda添加国内清华镜像源(亲测有效)
文章目录 pip和conda 添加国内清华镜像 1. pip源更改: 2. conda源更改: pip和conda 添加国内清华镜像 python模块安装,使用国内源可以提高下载速度. 1. pip源 ...
- zookeeper扫盲
一.zookeeper概述 a.zookeeper是一个开源的分布式的项目,为分布式业务提供协调服务的apache顶级项目 那什么是分布式的呢,通俗的说就是多个机器可以同时去处理一件事情 b.zook ...
- [ASP.NET Core 3框架揭秘] 文件系统[4]:程序集内嵌文件系统
一个物理文件可以直接作为资源内嵌到编译生成的程序集中.借助于EmbeddedFileProvider,我们可以采用统一的编程方式来读取内嵌的资源文件,该类型定义在 "Microsoft.Ex ...