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. 【Git】Windows 配置 SSH-Key

    查看本地公钥是否存在 执行以下语句来判断是否已经存在本地公钥 cat ~/.ssh/id_rsa.pub 如果出现如下截图,则本地公钥不存在,继续按步骤进行. 如果看到一长串以 ssh-rsa 或 s ...

  2. LeetCode529. 扫雷游戏 Python3 DFS+BFS+注释

    https://leetcode-cn.com/problems/minesweeper/solution/python3-dfsbfszhu-shi-by-xxd630/ 规则: 'M' 代表一个未 ...

  3. 常见问题解决办法=》.net后台

    1:后台返回前端长度过大的问题 除了在web.config中设置最大值外还可以修改返回值  [web.config中配置最大值有时候无效,直接修改返回值效果会好一些] List<User> ...

  4. DevExpress的GridControl的使用以及怎样添加列和绑定数据源

    场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  5. git提交时忽略指定文件

    git提交时忽略指定文件 我们在项目开发过程中经常用到git来管理自己的项目,使用git版本控制进行多人协作开发具有许多优势,这里就不一一阐述了,有兴趣的同学可以自己去查找资料进行系统的学习.而本篇文 ...

  6. oop面向对象【继承、super、this、抽象类】

    今日内容 1.三大特性——继承 2.方法重写 3.super关键字 4.this关键字 5.抽象类 教学目标 1.能够解释类名作为参数和返回值类型 2.能够写出类的继承格式 3.能够说出继承的特点 4 ...

  7. React-Native三种断点调试方式的流程和优缺点比较

    RN的调试和web端的调试虽然相似,但是也有一些不同,下面就来比较一下三种断点调试方法的差异 总结: 感觉还是第一种好一些 1.React-Native-Debugger工具调试法 1.1 首先我们得 ...

  8. PHP使用递归按层级查找数据

    今天主要介绍一下使用递归来按层级查找数据.原理挺简单的,主要是通过父级id一级一级的循环查找子级,使用PHP循环代码也很容易实现,不过如果层级越多,PHP重复代码也越多,这时可以使用递归来实现这功能. ...

  9. webpack 配置babel-loader babel7

    babel 7版本配置 在webpack中 默认只能处理部分 ES6的新语法,一些更高级的ES6或ES7的语法,webpack是处理不了的这个时候就需要借助第三方的loader 来帮助webpack ...

  10. 最后的记忆——Spring ApplicationContext

    本文尝试分析一下Spring 的 ApplicationContext体系的 接口设计,尝试理解为什么这么做,为什么接口这么设计.为什么这么去实现,为什么需要有这个方法,为什么 这样命名?接口.类.方 ...