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. Codeforces-527c

    Leonid wants to become a glass carver (the person who creates beautiful artworks by cutting the glas ...

  2. linux 根据端口关闭程序的管道命令

    netstat -anp|grep :3306|head -n1|cut -d"/" -f1|sed 's/ /\r\n/g'|tail -n1|xargs -I{} kill - ...

  3. 【Redis】349- Redis 入门指南

    点击上方"前端自习课"关注,学习起来~ 1. 概述 1.1. Redis 简介 Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映 ...

  4. verilog设计加法器

    概述 本文利用了硬件行为描述.数据流描述.结构描述三种方法分别写了几个加法器 一位半加法器 即两个一位的二进制数相加,得到其正常相加的结果的最后一位. 仿真波形图 硬件行为描述 设计文件 123456 ...

  5. 《一头扎进》系列之Python+Selenium框架设计篇3- 价值好几K的框架,狼来了,狼来了....,狼没来,框架真的来了

    1. 简介 前边宏哥一边一边的喊框架,就如同一边一边的喊狼来了!狼来了!.....这回是狼没有来,框架真的来了.从本文开始宏哥将会一步一步介绍,如何从无到有地创建自己的第一个自动化测试框架.这一篇,我 ...

  6. Oracle用户、角色、权限

    一.Oracle权限 系统权限:系统规定用户使用数据库的权限.(系统权限是对用户而言) 对象权限:某种权限用户对其它用户的表或视图的存取权限.(是针对表或视图而言的) 1.Oracle系统权限 ​ o ...

  7. 京东云携手HashiCorp,宣布推出Terraform Provider

    2019年4月23日消息,京东云携手云基础设施自动化软件的领导者HashiCorp,宣布推出Terraform Provider for JD Cloud,这意味着用户能够在京东云上轻松使用简单模板语 ...

  8. B站上传字幕问题解决

    博客:blog.shinelee.me | 博客园 | CSDN B站上传字幕时,如果srt文件中出现如下空行,则会报错,仅上传了空行前的部分 于是写了个python脚本,如下: import pys ...

  9. Android 插件化开发(四):插件化实现方案

    在经过上面铺垫后,我们可以尝试整体实现一下插件化了.这里我们先介绍一下最简单的实现插件化的方案. 一.最简单的插件化实现方案 最简单的插件化实现方案,对四大组件都是适用的,技术面涉及如下: 1). 合 ...

  10. Android.mk语法说明

    版权申明: 本文原创首发于以下网站,您可以自由转载,但必须加入完整的版权声明 博客园:https://www.cnblogs.com/MogooStudio/ csdn博客:https://blog. ...