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上显示出来的更多相关文章

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

    实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...

  2. C# Socket Server 收不到数据

    #/usr/bin/env python # -*- coding: utf- -*- # C# Socket Server 收不到数据 # 说明: # 最近在调Python通过Socket Clie ...

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

    原文地址:http://www.asp119.com/news/2009522181815_1.htm 从socket中接收数据的方法取决于你使用socket类型,Socket和XMLSocket都可 ...

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

    Atitit 研发体系建立 数据存储与数据知识点体系知识图谱attilax 总结 分类具体知识点原理规范具体实现(oracle,mysql,mssql是否可以自己实现说明 数据库理论数据库的类型 数据 ...

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

    1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协 ...

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

    1. UDP协议发送数据 和 接收数据 UDP协议发送数据: • 创建发送端的Socket对象 • 创建数据,并把数据打包 • 调用Socket对象的发送方法,发送数据包 • 释放资源  UDP协议接 ...

  7. 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换

    [源码下载] 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换 作者:webabcd 介绍速战速决 之 PHP ...

  8. ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理

    话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...

  9. Web jquery表格组件 JQGrid 的使用 - 7.查询数据、编辑数据、删除数据

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

随机推荐

  1. POJ1704 Georgia and Bob(Nim博弈变形)

    Georgia and Bob Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14312   Accepted: 4840 ...

  2. 【Python3网络爬虫开发实战】 分析Ajax爬取今日头条街拍美图

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:haoxuan10 本节中,我们以今日头条为例来尝试通过分析Ajax请求 ...

  3. 如何禁止chrome浏览器http自动转成https

    Chrome 浏览器 地址栏中输入 chrome://net-internals/#hsts 在 Delete domain security policies 中输入项目的域名,并 Delete 删 ...

  4. Ambari 自定义服务集成原理介绍

    之前,在 github 上开源了 ambari-Kylin 项目,可离线部署,支持 hdp 2.6+ 及 hdp 3.0+ .github 地址为:https://github.com/8418090 ...

  5. 【JPA】注解@PostConstruct、@PreDestroy

    从Java EE5规范开始,Servlet增加了两个影响Servlet生命周期的注解@PostConstruct和@PreConstruct.这两个注解被用来修饰一个非静态的void()方法,而且这个 ...

  6. java基础篇一

    引言 本人系南京一小小学校的大三小小菜鸟,三年来学了很多杂七杂八的,也荒废了大量的时间,马上就要秋招了,之前也看了不少面试题,备选了一些简单的项目,看了不知多少本的几百页厚的各种知识的pdf电子书,发 ...

  7. eclipse 导入别人拷贝过来的工作空间项目

    切换自己的工作空间 File --> Import --> Existing Project into Workspace --> 选择项目根目录 --> 确定 如果你的ecl ...

  8. [ASP.NET Core 3框架揭秘] 依赖注入[4]:一个Mini版的依赖注入框架

    在前面的章节中,我们从纯理论的角度对依赖注入进行了深入论述,我们接下来会对.NET Core依赖注入框架进行单独介绍.为了让读者朋友能够更好地理解.NET Core依赖注入框架的设计与实现,我们按照类 ...

  9. MySql数据库之常用数据类型及常用约束简述

    本文呢,主要给大家简述一下数据库中常用的几种数据类型以及约束. 1.数据类型 数据类型,是指数据表中可以存储的数据的种类. 数据库中常用的数据类型有: 1.整型:int.bit 2.小数:decima ...

  10. js简单动画:匀速动画、缓动动画、多物体动画以及透明度动画

    主要实现以下几种简单的动画效果(其实原理基本相同): 1.匀速动画:物体的速度固定 2.缓动动画:物体速度逐渐变慢 3.多物体动画 4.透明度动画 效果实现: 1.匀速动画(以物体左右匀速运动为例) ...