Unity - 将纹理数据写入字节数组会产生空数组

时间:2017-09-21 13:27:25

标签: c# arrays string unity3d

我在从纹理数据创建字节数组时遇到了问题。我有两个函数,一个将纹理写入文件(正在工作),另一个将纹理数据写入一个数组,然后将其处理成一个字符串。我试图测试它是否适用于调试' Debug.Log("局部变量textureString是:" + textureString);'但它是空的。我有什么不对?为了清楚地了解我在整体上想要完成的事情,我创建了一个图表来说明:

enter image description here

所以我有4个客户端运行一个允许用户创建自定义纹理的应用程序,然后是第五个运行不同应用程序的客户端,该应用程序获取该纹理信息并使用它来实例化基于texture2d,字符串动物类型的自定义字符,和字符串客户端ID。

    public byte[] textureBytes;
    public string textureString;
    public string textureType;

    public void WriteTextureToBytes()
    {
        SaveColoringBookTexturePNG();

        StartCoroutine(DoWriteTextureToBytes());
        Debug.Log("WriteTextureToBytes Button Pressed.");
    }

    IEnumerator DoWriteTextureToBytes()
    {
        yield return new WaitForEndOfFrame();
        RenderTexture tmp = RenderTexture.active;
        RenderTexture.active = BackLayerController.RenderTexture;

        TmpTexture2D.ReadPixels(new Rect(0, 0, RenderTextureSize.x, RenderTextureSize.y), 0, 0, false);

        textureBytes = TmpTexture2D.GetRawTextureData();
        textureString = Encoding.UTF8.GetString(textureBytes);
        textureType = PageConfig.UniqueId;

        player = GameObject.FindGameObjectWithTag("Player");
        player.GetComponent<PlayerController>().AnimalTex = textureString;
        player.GetComponent<PlayerController>().AnimalType = textureType;

        Debug.Log("Local variable textureType is : " + textureType);
        Debug.Log("Local variable textureString is : " + textureString);
        Debug.Log("PlayerController AnimalType is : " + player.GetComponent<PlayerController>().AnimalType);
        Debug.Log("PlayerController AnimalTex is : " + player.GetComponent<PlayerController>().AnimalTex);
    }

    public void SaveColoringBookTexturePNG()
    {
        StartCoroutine(DoSaveColoringBookTexturePNG());
    }

    IEnumerator DoSaveColoringBookTexturePNG()
    {
        yield return new WaitForEndOfFrame();
        RenderTexture tmp = RenderTexture.active;
        RenderTexture.active = BackLayerController.RenderTexture;

        TmpTexture2D.ReadPixels(new Rect(0, 0, RenderTextureSize.x, RenderTextureSize.y), 0, 0, false);

        File.WriteAllBytes(SaveFilePath, TmpTexture2D.EncodeToPNG());

        Debug.Log("File Saved to: " + SaveFilePath);
    }

1 个答案:

答案 0 :(得分:1)

  

我以为我需要先将数组转换为字符串   通过网络发送。也许我没有?

没有。您可以使用NetworkServer.SendBytesToPlayer向具有MessageBase的玩家发送字节数组,但我建议您使用NetworkServer.SendToAll,因为您希望通过网络发送多个数据。 永远不要将纹理转换为字符串。这是一个缓慢而糟糕的编程。

只需创建一个类,该类将包含您要通过网络发送的所有变量。确保此类派生自MessageBase。当您从派生时,Unity会自动为您在该类中序列化这些变量,这样您就不必自己完成。

服务器

这是包含Texture数组(textureBytes)和简单字符串消息的服务器示例:

public class MyMsgType
{
    public static short texture = MsgType.Highest + 1;
};

//Create a class that holds a variables to send
public class TextureMessage : MessageBase
{
    public byte[] textureBytes;
    public string message;//Optional
}

//Call to send the Texture and a simple string message
public void sendTexture(Texture2D texture, string message)
{
    TextureMessage msg = new TextureMessage();
    //Convert Texture2D to byte array
    msg.textureBytes = texture.GetRawTextureData();
    msg.message = message;

    NetworkServer.SendToAll(MyMsgType.texture, msg);
}

USAGE

然后在连接到网络时简单发送:

Texture2D textureToSend = ....;
string messageToSend = "Screen Short Image";

sendTexture(textureToSend , messageToSend);

<强>客户端

客户也很容易。注册MyMsgType活动,以便在收到Texture2D时收到通知。收到后,使用LoadRawTextureData将字节数组转换回Texture2D

public class MyMsgType
{
    public static short texture = MsgType.Highest + 1;
};

//Create a class that holds a variables to send
public class TextureMessage : MessageBase
{
    public byte[] textureBytes;
    public string message;//Optional
}

NetworkClient myClient;

// Create a client and connect to the server port
public void setupClient()
{
    //Create new client
    myClient = new NetworkClient();
    //Register to connect event
    myClient.RegisterHandler(MsgType.Connect, OnConnected);
    //Register to texture receive event
    myClient.RegisterHandler(MyMsgType.texture, OnTextureReceive);

    //Connect to server
    myClient.Connect("127.0.0.1", 4444);
}

//Called when texture is received
public void OnTextureReceive(NetworkMessage netMsg)
{
    TextureMessage msg = netMsg.ReadMessage<TextureMessage>();

    //Your Received message
    string message = msg.message;
    Debug.Log("Texture Messsage " + message);

    //Your Received Texture2D
    Texture2D receivedtexture = new Texture2D(4, 4);
    receivedtexture.LoadRawTextureData(msg.textureBytes);
    receivedtexture.Apply();
}

public void OnConnected(NetworkMessage netMsg)
{
    Debug.Log("Connected to server");
}

USAGE

注册接收事件然后连接到服务器。只需调用setupClient()函数即可。

setupClient();