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不起作用

原文地址:https://www.cnblogs.com/WinnerYu/p/12074477.html

时间: 2024-10-12 01:08:24

Unity3D 使用Socket处理数据并将数据 在UGUI、NGUI上显示出来的相关文章

谈谈大数据时代web数据可视化探析

  数据可视化技术可借助人脑的视觉思维能力,帮助人们理解大量的数据信息,发现数据中隐含的规律,从而提高数据的使用效率.面对大数据深奥的面貌,如何才能让大型数据集变得亲切和易于理解,可视化无疑是最有效的途径.对大数据背景下的数据可视化应用展开研究,将有助于我们发展和创新数据可视化技术. 大数据时代的机遇与挑战 物联网.云计算.移动互联网.手机.平板电脑.PC以及遍布地球各个角落的各种各样的传感器,无一不是数据来源或者承载的方式.随着社交网络的普及,使得人们的行为和情绪的细节化测量成为可能.挖掘用户

C# Socket Server 收不到数据

#/usr/bin/env python # -*- coding: utf-8 -*- # C# Socket Server 收不到数据 # 说明: # 最近在调Python通过Socket Client连接C#的Socket Server,但是Server端能检测到连接, # 却收不到数据,这个问题困扰了几个小时,最后是因为Python这边发送完数据,直接关闭了 # 连接,最好是sleep一点点时间再关闭Socket,这样就能正常受到数据了. # # 2016-11-09 深圳 南山平山村

Window下UDP(socket)接和收数据案例

 配置QT的环境变量,这台电脑à属性à高级系统设置à高级à环境变量à系统变量àpathàC:\Qt\Qt5.3.0\5.3\mingw482_32\bin;C:\Qt\Qt5.3.0\Tools\QtCreator\bin 创建一个QT项目:winAndLinuxMyUdpProject项目 修改QT的项目文件,修改winAndLinuxMyUdpProject.pro文件: 注意,这的的:LIBS+= -lWs2_32  ##标示使用window下的Ws2_32.lib,-l表示要链接后面

iOS开发之Socket通信实战--Request请求数据包编码模块

实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncSocket来进行长连接连接和传输数据,该第三方地 址:https://github.com/robbiehanson/CocoaAsyncSocket,读者可以自行google或者baidu搜索 这个库的用法,网上有很多资料,而且用法不难. 在一些对Socket通信使用需求不是很高的应用中,比如需要

ActionScript接收socket服务器发送来的数据

原文地址:http://www.asp119.com/news/2009522181815_1.htm 从socket中接收数据的方法取决于你使用socket类型,Socket和XMLSocket都可以接收数据,但是两者实现方法有些不同,让我们先看看Socket类是如何做的. 正如前面所讲到的,Flash提供的socket通信方式是异步通信,也就是说仅仅创建socket连接并试图读取数据这是不可能的,read方法读取数据时并不会等待数据传输过来而立即返回,如果数据还没准备好而去读取数据会导致异常

Java基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据

1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协议发送数据: • 创建发送端的Socket对象• 这一步如果成功,就说明连接已经建立成功了.• 获取输出流,写数据• 释放资源 2. 代码实现: (1)发送端: 1 package cn.itcast_06; 2 3 import java.io.IOException; 4 import java

linux学习笔记——数据查找、数据截取

##########数据查找########## find             ##find 命令在系统中查找文件    -name        ##按照文件名查找    -user        ##按照文件属主查找    -group        ##按文件属组查找     -perm        ##按文件权限查找    -type        ##按文件类型查找            ##文件类型:b块设备c字符设备d目录f普通文件l链接s(socket)    -size

Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结

分类具体知识点原理规范具体实现(oracle,mysql,mssql是否可以自己实现说明 数据库理论数据库的类型 数据库理论,网状,层次, 数据库理论树形数据库注册表,hashtable 数据库理论,kv数据库.hashtable 数据库理论Oodb 数据库理论nosql db 数据库理论隔离级别 数据库理论 数据库理论Er模型 数据库理论Acid数据库完整性 数据库理论关系模型 数据库理论   sql 数据库理论 数据库理论存储过程 数据库理论 触发器 数据库理论 视图 约束 数据库理论 数据

Java基础知识强化之网络编程笔记03:UDP之UDP协议发送数据 和 接收数据

1. UDP协议发送数据 和 接收数据 UDP协议发送数据: • 创建发送端的Socket对象 • 创建数据,并把数据打包 • 调用Socket对象的发送方法,发送数据包 • 释放资源  UDP协议接收数据:       • 创建接收端的Socket对象      • 创建数据包,接收数据(接收容器)      • 调用Socket对象的接收方法,接收数据包      • 解析数据包,并显示在控制台      • 释放资源 2. 代码实现 (1)首先我们先写发送端的程序,如下: 1 packag