2016-06-15 13:54:52 qq_22780533 阅读数 753

由于很多的因素,项目改用U3D开发,而项目组目前为止没资深的Unity开发程序员,只能摸着石头过河了.我们网络通信数据使用protobuf的格式,(关于这protobuf的格式分析在上一篇笔记中已经分析得很详细了).简单说明一下目前项目的开发环境与插件的使用情况:

开发脚本: C# (.Net 2.0) 由于我与另一位同事均无C#功底,所以业余时间学习C#必不可少,本人而言已经有了基本的计划.(为什么不是JS 或者BOO,详细翻了一下Assets Unity 基本上大多插件都是用C#写的,Boo更加是第一次听)

开发工具:抛弃官方的Mono 使用VS2012,主要使用了UnityVS插件,注意这个插件现在已经免费了.传送门

GUI:有UGUI与NGUI和GUI三个选择,目前选的是NGUI,主要原因是NGUI的教材网上一抓一大把,由于换引擎的突发性,已经没太多时间给我去看那个比较好用了.(很多事情总是充满无奈)

网络模块:Unity5 提供了一套Net组件,在我花了两天时间去看了它的几个组件之后,发现根本不足以满足我们项目的要求.所以决定使用.Net自带的Socket自己实现.(约莫花了三天的时间)

protobuf的使用

目前C#的库 在google code上有两个:

  1. protobuf-net
  2. protobuf-csharp-port

发现protobuf-net对跨平台的支持似乎略优于protobuf-csharp-port,在社区的评价也好一点,所以选用了protobuf-net.使用protobuf-net基本的步骤是:

  • 编写proto文件

举个梨子,保存为demo.proto,message语法请自行学习

/*
 * package demo;  
 *
 * message People {  
 *    required string name = 1;  
 *    required int32 id = 2;  
 *    required string email = 3;  
 * }
 */
  • 使用protogen.exe生成C#源码文件

基本语法为

// -i: 指定proto文件 可以指定多个
// -o: 制定输出文件路径与文件名
// -ns: 指定源码命名空间,如果不设置则默认为proto的文件名为命名空间
// 若proto文件中有package XXX 参数,则强制命名空间名字为 XXX
protobuf-net\ProtoGen\protogen.exe -i:demo.proto -o:PBMessage\PBMessage.cs -ns:PBMessage
  • 源文件生成DLL动态链接库

基本命令为:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /
errorreport:prompt /warn:4 /define:TRACE /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /
reference:protobuf-net.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /debug:pdbonly /
filealign:512 /optimize+ /out:obj\Release\PBMessage.dll /target:library /utf8output PBMessage.cs Properties\AssemblyInfo.cs

如果不想用命令行解决,也可以直接使用VS创建C#库项目,然后把源文件加到项目里,F5生成.在这一步中 得到PBMessage.dll(dll文件名可随意更改)AssemblyInfo.cs为版本信息文件,可在本文末的下载文件中找到,也可以自行创建一个

  • 预编译序列化库 需要上一步得到的PBMessage.dll

命令如下:

protobuf-net\Precompile\precompile.exe PBMessage.dll -o:PBMessageSerializer.dll -t:PBMessageSerializer

经过前面的步骤之后,我们得到了三个DLL:

  1. protobuf-net.dll 从protobuf-net工具包直接取出,根据不同平台而不同
  2. PBMessage.dll 生成的动态链接库
  3. PBMessageSerializer.dll 预编译序列化库

把这三个库放到 Unity项目的 Assets\Plugins\protobuf文件夹下,如没这个文件夹则自行创建.到此就完成了全部配置工作,接下来是代码使用.方法如下:

/*
 * package demo;  
 *
 * message People {  
 *    required string name = 1;  
 *    required int32 id = 2;  
 *    required string email = 3;  
 * }
 */
public void WriteProtoBuf()
{
    demo.People proto = new demo.People();
    proto.email = "rectvv@gmail.com";
    proto.id = 10086;
    proto.name = "Rect";

    // 序列化
    using (MemoryStream ms = new MemoryStream())
    {
        new PBMessageSerializer().Serialize(ms, proto);
        Byte[] pBuffer = ms.ToArray();
    }
}
public void ReadProtoBuf(Byte[] pBuffer,int nSize)
{
    if (null == pBuffer || 0 >= nSize)
    {
        return;
    }
    // 反序列化
    using (MemoryStream ms = new MemoryStream(pBuffer, 0, nSize))
    {
        demo.People proto =  new PBMessageSerializer().Deserialize(ms, null, typeof(demo.People)) as demo.People;
    }
}

代码非常简单.

整个过程被我整合成一个Bat命令:传送门,只需要把proto文件放到根目录,然后运行Build.bat批处理即可.最后的生成DLL在Bin目录中.

2018-08-23 10:12:12 wang_huizhang 阅读数 208

服务端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace Server
{
    class Program
    {
        static Socket ReceiveSocket;
        static void Main(string[] args)
        {
            int port = 8885;
            IPAddress ip = IPAddress.Any;  // 侦听所有网络客户接口的客活动
            ReceiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用指定的地址簇协议、套接字类型和通信协议   <br>            ReceiveSocket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReuseAddress,true);  //有关套接字设置
            IPEndPoint endPoint = new IPEndPoint(ip, port);
            ReceiveSocket.Bind(new IPEndPoint(ip, port)); //绑定IP地址和端口号
            ReceiveSocket.Listen(10);  //设定最多有10个排队连接请求
            Console.WriteLine("建立连接");
            Socket socket = ReceiveSocket.Accept();

            byte[] receive = new byte[1024];
            socket.Receive(receive);
            Console.WriteLine("接收到消息:" + Encoding.ASCII.GetString(receive));
            byte[] send = Encoding.ASCII.GetBytes("Success receive the message,send the back the message");
            socket.Send(send);
            Console.WriteLine("发送消息为:" + Encoding.ASCII.GetString(send));

            Console.ReadKey();
        }
    }
}

客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;

namespace Client
{
    class Program
    {
        static Socket ClientSocket;
        static void Main(string[] args)
        {
            String IP = "127.0.0.1";
            int port = 8885;

            IPAddress ip = IPAddress.Parse(IP);  //将IP地址字符串转换成IPAddress实例
            ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用指定的地址簇协议、套接字类型和通信协议
            IPEndPoint endPoint = new IPEndPoint(ip, port); // 用指定的ip和端口号初始化IPEndPoint实例
            ClientSocket.Connect(endPoint);  //与远程主机建立连接


            Console.WriteLine("开始发送消息");
            byte[] message = Encoding.ASCII.GetBytes("Connect the Server");  //通信时实际发送的是字节数组,所以要将发送消息转换字节
            ClientSocket.Send(message);
            Console.WriteLine("发送消息为:" + Encoding.ASCII.GetString(message));
            byte[] receive = new byte[1024];
            int length = ClientSocket.Receive(receive);  // length 接收字节数组长度
            Console.WriteLine("接收消息为:" + Encoding.ASCII.GetString(receive));
            ClientSocket.Close();  //关闭连接
            Console.ReadKey();
        }
    }
}

 

2017-04-09 21:10:02 Mogoson 阅读数 3702

MGS-SerialPort

概述

Unity3D与串口通信,同步读取,持续写入,串口参数通过本地文件配置。

版本

  • Unity3D 5.4.1f1。
  • .NET 2.0。

问题

  1. Unity3D目前不能正常在Update,FixedUpdate等事件函数中直接读取串口数据,运行程序卡顿。
  2. Unity3D目前没有实现“SerialPort.ReceivedBytesThreshold”属性设置,抛出没有实现异常。
  3. Unity3D目前不能正常触发“SerialPort.DataReceived”事件,无异常抛出,无响应。
  4. Unity3D目前不能正常读取“SerialPort.BytesToRead”属性,运行程序卡死。
  5. Unity3D目前不能有效执行“SerialPort.DiscardInBuffer”方法,无异常抛出,输入缓冲区没
    能清空。
  6. Unity3D目前不能有效执行“SerialPort.DiscardOutBuffer”方法,无异常抛出,输出缓冲区没
    能清空。
  7. 上位机与下位机收发周期不一致(除特殊情况外可协调一致),每次从缓冲区读取到的数据基本
    不是一个完整的数据帧(单次接收/发送的数据),接收周期小于发送周期时,每次读取到的字
    节数小于1个数据帧长度;接收周期大于发送周期时,每次读取到的字节数大于1个数据帧长度。
  8. 即使上位机与下位机收发周期一致,因收发时刻差异,每次从缓冲区读取到的数据并非都是一个
    完整的数据帧,数据或长或短。

方案

参数配置

  • 串口参数按行写入到本地文本文件,便于调试,维护时修改适配。

持续读写

  • 使用线程按照读取周期持续从串口读取数据。
  • 使用线程按照写入周期持续向串口写入数据。

数据同步

协议

  • 商定收发周期尽量一致,不一致也无妨。
  • 商定收发协议,数据帧长度固定,数据帧的第一个字节作为收发头部标记(ReadHead/WiteHead),
    数据帧的最后一个字节作为收发尾部标记(ReadTail/WiteTail),剩余字节数作为收发数据计
    数(ReadCount/WriteCount)。

读取

  1. 读取整个缓冲区Buffer,并获取读取到的字节数Count;事实上,如果程序运行内存吃紧且收发
    周期基本一致,那么单次可以只从缓冲区读取1个数据帧长度(ReadCount+2)的字节以节约内
    存开销,读者可根据自己的需求自行修改。
  2. 如果Count不超过2个数据帧则数据没有延迟,直接将读取到的字节数据(Buffer的前Count个字节)
    添加到一个ReadBuffer列表;否则数据有延迟冗余,将读取到的字节数据(Buffer的前Count个字节)
    的后2个数据帧长度的字节数据添加到ReadBuffer列表;因为正常情况下,2个数据帧长度的连
    续字节数据必然包含一个完整的数据帧。继续。
  3. 检查ReadBuffer的长度,如果小于1个数据帧长度则返回步骤1;如果大于或等于1个数据帧长度
    (有可能包含一个完整的数据帧),继续。
  4. 检查ReadBuffer,如果第一个字节不等于ReadHead标记,则删除这个无效字节,返回步骤3;如
    果第一个字节等于ReadHead标记,则检查第1个数据帧长度位置的字节,如果等于ReadTail标记
    则找到一个完整的数据帧,将ReadBuffer前1个数据帧长度的字节存入ReadBytes,至此,缓冲
    区中由串口发来的最近一个完整数据帧已读取到;否则数据无效;现在ReadBuffer的前1个数据
    帧长度的字节已经检查过,将其从ReadBuffer中删除,返回步骤3。

写入

  1. 检查WriteBytes,长度不等于WriteCount则返回(避免WriteBytes被误操作重新初始化为其他长
    度的数组时,向串口写入错误的字节数据);如果长度等于WriteCount,继续。
  2. 在WriteBytes前面添加WiteHead标记,后面添加WriteTail标记,将其写入串口;返回步骤1。

实现

  1. SerialPortConfig.cs 结构体存储串口参数配置。
  2. SerialPortConfigurer.cs 串口参数配置写入本地文件,从文件读取配置。
  3. SerialPortController.cs 串口同步读取,持续写入。

源码

2019-01-04 15:30:43 Sxx930923 阅读数 562

今天开始为大家介绍一下unity和UE4的通信机制,如何实现两个PC端或者PC端与移动端的通信,包括Unity与Unity的通信,UE4与UE4的通信,UE4与Unity的通信,首先今天给大家介绍一下Unity与Unity之间的通信。
这里我主要使用的是Networking下的NetworkServe和NetworkClient建立服务器端和客户端。

服务器端

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using System;

public class MyNetworkManager : MonoBehaviour
{
	/// 要发送的信息
	public InputField send;
	
	/// 显示信息
	public Text info;
	
	/// 网络客户端
	private NetworkClient myClient;
	
	/// 用户信息分类
	private const short userMsg = 64;

	void Start ()
	{
		info.text = "Start...";
		myClient = new NetworkClient ();
	}
		  

	/// <summary>
	/// 建立服务器
	/// </summary>
	public void SetupServer ()
	{
		if (!NetworkServer.active) {
			ShowMsg ("setup server");
			ServerRegisterHandler ();
			NetworkServer.Listen (10000);  //端口号,随便你自己定义

			if (NetworkServer.active) {
				ShowMsg ("Server setup ok.");
			}
		}
	}

	
		
	/// <summary>
	/// 停止服务器端
	/// </summary>
	public void ShutdownServer ()
	{
		if (NetworkServer.active) {
			ServerUnregisterHandler ();
			NetworkServer.DisconnectAll ();
			NetworkServer.Shutdown ();

			if (!NetworkServer.active) {
				ShowMsg ("shut down server");
			}
		}
	}

	


	/// <summary>
	/// 服务器端有客户端连入事件
	/// </summary>
	/// <param name="netMsg">Net message.</param>
	private void OnServerConnected (NetworkMessage netMsg)
	{
		ShowMsg ("One client connected to server");
	}

	/// <summary>
	/// 服务器端有客户端断开事件
	/// </summary>
	/// <param name="netMsg">Net message.</param>
	private void OnServerDisconnected (NetworkMessage netMsg)
	{
		ShowMsg ("One client connected from server");
	}

	/// <summary>
	/// 服务器端错误事件
	/// </summary>
	/// <param name="netMsg">Net message.</param>
	private void OnServerError (NetworkMessage netMsg)
	{
		ServerUnregisterHandler ();
		ShowMsg ("Server error");
	}

	/// <summary>
	/// 显示信息
	/// </summary>
	/// <param name="Msg">Message.</param>
	private void ShowMsg (string Msg)
	{
		info.text = Msg + "\n\r" + info.text;
		//Debug.Log (Msg);
	}

	

	/// <summary>
	/// 服务器端向所有客户端发送信息
	/// </summary>
	public void ServerSend ()
	{
		if (NetworkServer.active) {
			UserMsg um = new UserMsg ();
			um.message = send.text;
			if (NetworkServer.SendToAll (userMsg, um)) {
				ShowMsg ("Server send:" + send.text);
			}
		}
	}

	/// <summary>
	/// 服务器端收到信息事件
	/// </summary>
	/// <param name="netMsg">Net message.</param>
	private void ServerGet (NetworkMessage netMsg)
	{
		UserMsg Msg = netMsg.ReadMessage<UserMsg> ();
		ShowMsg ("Server get:"+Msg.message);
	}

	/// <summary>
	/// 服务器端注册事件
	/// </summary>
	private void ServerRegisterHandler(){
		NetworkServer.RegisterHandler (MsgType.Connect, OnServerConnected);
		NetworkServer.RegisterHandler (MsgType.Disconnect, OnServerDisconnected);
		NetworkServer.RegisterHandler (MsgType.Error, OnServerError);
		NetworkServer.RegisterHandler (userMsg, ServerGet);
	}

	

	/// <summary>
	/// 服务器端注销事件
	/// </summary>
	private void ServerUnregisterHandler(){
		NetworkServer.UnregisterHandler (MsgType.Connect);
		NetworkServer.UnregisterHandler (MsgType.Disconnect);
		NetworkServer.UnregisterHandler (MsgType.Error);
		NetworkServer.UnregisterHandler (userMsg);
	}
}

客户端


using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using System;

public class MyNetworkManager : MonoBehaviour
{
	// 服务器ip地址
	public InputField ip;   
	
	// 服务器端口
	public InputField port;

	//要发送的信息
	public InputField send;

	//显示信息
	public Text info;

	//网络客户端
	private NetworkClient myClient;

	//用户信息分类
	private const short userMsg = 64;

	void Start ()
	{
		info.text = "Start...";
		myClient = new NetworkClient ();
	}
		  

	//建立客户端
	public void SetupClient ()
	{
		if (!myClient.isConnected) {
			ShowMsg ("setup client");
			ClientRegisterHandler ();
			myClient.Connect (ip.text, int.Parse (port.text));
		}
	}


	//停止客户端
	public void ShutdownClient ()
	{
		if (myClient.isConnected) {
			ClientUnregisterHandler ();
			myClient.Disconnect ();

			//NetworkClient.Shutdown()使用后,无法再次连接。
			//This should be done when a client is no longer going to be used.
			//myClient.Shutdown ();
		}
	}
		

	// 客户端连接到服务器事件
	private void OnClientConnected (NetworkMessage netMsg)
	{
		ShowMsg ("Client connected to server");
	}


	//客户端从服务器断开事件
	private void OnClientDisconnected (NetworkMessage netMsg)
	{
		ShowMsg ("Client disconnected from server");
	}


	//客户端错误事件
	private void OnClientError (NetworkMessage netMsg)
	{
		ClientUnregisterHandler ();
		ShowMsg ("Client error");
	}


	//显示信息
	private void ShowMsg (string Msg)
	{
		info.text = Msg + "\n\r" + info.text;
		//Debug.Log (Msg);
	}


	// 客户端向服务器端发送信息
	public void ClientSend ()
	{
		if (myClient.isConnected) {
			UserMsg um = new UserMsg ();
			um.message = send.text;
			if (myClient.Send (userMsg, um)) {
				ShowMsg ("Client send:" + send.text);
			}
		}
	}

	
	//客户端接收到服务器端信息事件
	private void ClientGet (NetworkMessage netMsg)
	{
		UserMsg Msg = netMsg.ReadMessage<UserMsg> ();
		ShowMsg ("Client get:"+Msg.message);
	}

	
	//客户端注册事件
	private void ClientRegisterHandler(){
		myClient.RegisterHandler (MsgType.Connect, OnClientConnected); 
		myClient.RegisterHandler (MsgType.Disconnect, OnClientDisconnected);
		myClient.RegisterHandler (MsgType.Error, OnClientError);
		myClient.RegisterHandler (userMsg, ClientGet);
	}


	//客户端注销事件
	private void ClientUnregisterHandler(){
		myClient.UnregisterHandler (MsgType.Connect);
		myClient.UnregisterHandler (MsgType.Disconnect);
		myClient.UnregisterHandler (MsgType.Error);
		myClient.UnregisterHandler (userMsg);
	}
}

这个示例只是简单的给大家实现了服务器和客户端的一个互传消息,在此基础上大家可以尽情的扩展。

Demo地址:https://download.csdn.net/download/sxx930923/10903377

2013-03-15 16:26:58 asd237241291 阅读数 19103

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 Unity3D引擎技术交流QQ群:【119706192本文链接地址: Unity3D 网络通信_HTTP协议:获取网络图片内容

自己写的测试demo,一个功能一个功能测试着做的,没有什么结构,凑合看吧。

http协议,在手机平台,URL必须必带http://头。

此脚本主要实现了 

  • 分别用pose和get方式获取天气预报信息(XML格式)。
  • 解析XML
  • 获取网络图片
  • 获取网络图片(base64格式)
  • base64与byte[]互转
  • byte[]与Texture2D(图片)互转

更多常用WEBService:http://www.webxml.com.cn/zh_cn/web_services.aspx

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.IO;

public class HTTPDemo : MonoBehaviour
{
    public string HostName = "http://www.webxml.com.cn";
    //城市天气预报服务 
    public string URLPath = "/WebServices/WeatherWebService.asmx/getWeatherbyCityName";
    //获得验证码服务(直接获得图片)
    private string PictureName = "/WebServices/ValidateCodeWebService.asmx/cnValidateImage?byString='Picture'";
    //获得验证码服务(获得图片字节流)
    private string PictureByteName = "/WebServices/ValidateCodeWebService.asmx/cnValidateByte?byString='picByte'";
        
    private Texture2D mPicture;
    private Texture2D mPictureByte;
    private Texture2D mConvertPNG;

    public string[] Parameters = new string[] { "theCityName" };

    private string XMLContent = "null";

    public string testC = "null";

    void OnGUI()
    {
        //显示测试信息 
        GUI.Label(new Rect(100, 10, 1000, 38), testC);


        //表单传值
        if (GUI.Button(new Rect(10, 50, 100, 60), "post"))
        {
            postWeatherbyCityName("北京");
        }
        GUI.Button(new Rect(120, 80, 100 + getJindu() * 100, 20), (getJindu() * 100) + "%");


        //get传值(android平台不支持中文参数)
        if (GUI.Button(new Rect(10, 130, 100, 60), "get"))
        {
            getWeatherbyCityName("58367");//上海
        }
        GUI.Button(new Rect(120, 150, 100 + getJindu() * 100, 20), (getJindu() * 100) + "%");


 
        //显示读取到的天气预报原始信息(xml格式)
        GUI.Label(new Rect(10, 220, 380, 500), mContent);



        //解析xml 
        if (GUI.Button(new Rect(500, 200, 120, 60), "AnalysisXML"))
        {
            XMLContent = AnalysisXML();
        }
        GUI.Label(new Rect(410, 220, 380, 500), XMLContent);



        //下载网络图片 
        if (GUI.Button(new Rect(10, 750, 80, 60), "downPic"))
        {
            downloadPicture(PictureName);
        }
        GUI.Label(new Rect(100, 760, 200, 200), mPicture);


        //下载网络图片 (base64格式)
        if (GUI.Button(new Rect(350, 750, 80, 60), "downPicByte"))
        {
            downloadPictureByte(PictureByteName);
        }
        GUI.Label(new Rect(450, 760, 200, 200), mPictureByte);
    }

    public void postWeatherbyCityName(string str)
    {
        //将参数集合封装到Dictionary集合方便传值
        Dictionary<string, string> dic = new Dictionary<string, string>();

        //参数
        dic.Add(Parameters[0], str);

        StartCoroutine(POST(HostName + URLPath , dic));
    }

    public void getWeatherbyCityName(string str)
    {
        //将参数集合封装到Dictionary集合方便传值
        Dictionary<string, string> dic = new Dictionary<string, string>();

        //参数
        dic.Add(Parameters[0], str);

        StartCoroutine(GET(HostName + URLPath , dic));
    }

    //下载图片 
    public void downloadPicture(string picName)
    {
        testC ="picurl = " + picName;

        StartCoroutine(GETTexture(HostName + picName));
    }

    //下载图片(字节流)
    public void downloadPictureByte(string picName)
    {
        StartCoroutine(GETTextureByte(HostName + picName));
    }

    /*----------------------------------------------------Helper----------------------------------------------------------------------------*/

    private float mJindu = 0;
    private string mContent;

    public float getJindu()
    {
        return mJindu;
    }

    //POST请求(Form表单传值、效率低、安全 ,)
    IEnumerator POST(string url, Dictionary<string, string> post)
    {
        //表单 
        WWWForm form = new WWWForm();
        //从集合中取出所有参数,设置表单参数(AddField()).
        foreach (KeyValuePair<string, string> post_arg in post)
        {
            form.AddField(post_arg.Key, post_arg.Value);
        }
        //表单传值,就是post 
        WWW www = new WWW(url, form);

        yield return www;
        mJindu = www.progress;

        if (www.error != null)
        {
            //POST请求失败
            mContent =  "error :" + www.error;
        }
        else
        {
            //POST请求成功
            mContent = www.text;
        }
    }

    //GET请求(url?传值、效率高、不安全 )
    IEnumerator GET(string url, Dictionary<string, string> get)
    {
        string Parameters;
        bool first;
        if (get.Count > 0)
        {
            first = true;
            Parameters = "?";
            //从集合中取出所有参数,设置表单参数(AddField()).
            foreach (KeyValuePair<string, string> post_arg in get)
            {
                if (first)
                    first = false;
                else
                    Parameters += "&";

                Parameters += post_arg.Key + "=" + post_arg.Value;
            }
        }
        else
        {
            Parameters = "";
        }

        testC ="getURL :" + Parameters;

        //直接URL传值就是get
        WWW www = new WWW(url + Parameters);
        yield return www;
        mJindu = www.progress;

        if (www.error != null)
        {
            //GET请求失败
            mContent = "error :" + www.error;
        }
        else
        {
            //GET请求成功
            mContent = www.text;
        }
    }

    IEnumerator GETTexture(string picURL)
    {
        WWW wwwTexture = new WWW(picURL);

        yield return wwwTexture;

        if (wwwTexture.error != null)
        {
            //GET请求失败
            Debug.Log("error :" + wwwTexture.error);
        }
        else
        {
            //GET请求成功
            mPicture = wwwTexture.texture;
        }
    }

    string PicByte;
    IEnumerator GETTextureByte(string picURL)
    {
        WWW www = new WWW(picURL);

        yield return www;

        if (www.error != null)
        {
            //GET请求失败
            Debug.Log("error :" + www.error);
        }
        else
        {
            //GET请求成功
            Debug.Log("PicBytes text = " + www.text);

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(new StringReader(www.text));

            //通过索引查找子节点 
            PicByte = xmlDoc.GetElementsByTagName("base64Binary").Item(0).InnerText;
            testC = PicByte;

            mPictureByte = BttetoPic(PicByte);
        }
    }

    //解析XML 
    string AnalysisXML()
    {
        string str = "";

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(new StringReader(mContent));

        //得到文档根节点的所有子节点集合 
        //XmlNodeList nodes = xmlDoc.DocumentElement.ChildNodes;
        //通过节点名得到节点集合
        XmlNodeList nodes = xmlDoc.GetElementsByTagName("string");

        //通过索引查找子节点 
        str += "item[1] = " + xmlDoc.GetElementsByTagName("string").Item(1).InnerText + "\n\n";

        //遍历所有子节点
        foreach (XmlElement element in nodes)
        {
            if (element.Name == "string")
            {
                str += element.InnerText + "\n";
            }
        }
        
        return str;
    }

    //图片与byte[]互转
    public void convertPNG(Texture2D pic)
    {
        byte[] data = pic.EncodeToPNG();
        Debug.Log("data = " + data.Length + "|" + data[0]);
        mConvertPNG = new Texture2D(200, 200);
        mConvertPNG.LoadImage(data);
    }

    //byte[]与base64互转 
    Texture2D BttetoPic(string base64)
    { 
        Texture2D pic = new Texture2D(200,200);
        //将base64转码为byte[] 
        byte[] data = System.Convert.FromBase64String(base64);
        //加载byte[]图片
        pic.LoadImage(data);

        string base64str = System.Convert.ToBase64String(data);
        Debug.Log("base64str = " + base64str);

        return pic;
    }
}

Unity-Android通信

阅读数 1253

没有更多推荐了,返回首页