2017-10-05 3 views
0

J'essaie de créer une petite application de test, en utilisant l'unité. Je construis une instance de l'application et la configure pour fonctionner en tant qu'Hôte et en exécutant une autre instance dans l'éditeur de l'unité en tant que client. Dans cette itération actuelle, j'ai un seul bouton qui DEVRAIT, lorsqu'il est pressé est de prendre une capture d'écran, puis envoyer cette capture d'écran à tous les clients. Mais rien ne semble fonctionner. Le problème initial que je frappe est une erreur ReadPixels:ReadPixels a été appelé pour lire des pixels à partir du tampon de trame système, mais pas à l'intérieur du cadre de dessin. UnityEngine.Texture2D: ReadPixels

ReadPixels was called to read pixels from system frame buffer, while not inside drawing frame. UnityEngine.Texture2D:ReadPixels(Rect, Int32, Int32) UNETChat:OnPostRender() (at Assets/Scripts/UNETChat.cs:50) <TakeSnapshot>c__Iterator0:MoveNext() (at Assets/Scripts/UNETChat.cs:42) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr). Au-delà de ça, une fois résolu, je suis sûr qu'il y a beaucoup de travail supplémentaire ici qui est hors sujet. Mais je commence juste ici. Merci pour l'aide!

using System.Collections; 
using System.IO; 
using UnityEngine; 
using UnityEngine.Networking; 
using UnityEngine.Networking.NetworkSystem; 

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 = "Test Received Message"; //Optional 
} 

public class UNETChat : Chat 
{ 
    NetworkClient myClient; 
    public Texture2D previewTexture; 
    string messageToSend = "Screen Short Image"; 

    private void Start() 
    { 
     //if the client is also the server 
     if (NetworkServer.active) 
     { 
      // Register to connect event 
      myClient.RegisterHandler(MsgType.Connect, OnConnected); 
      // Register to texture receive event 
      myClient.RegisterHandler(MyMsgType.texture, OnTextureReceive); 
     } 
     setupClient(); 
    } 

    public IEnumerator TakeSnapshot(int width, int height) 
    { 
     yield return new WaitForSeconds(0.1F); 
     Texture2D texture = new Texture2D(800, 800, TextureFormat.RGB24, true); 
     texture.ReadPixels(new Rect(0, 0, 800, 800), 0, 0); 
     texture.LoadRawTextureData(texture.GetRawTextureData()); 
     texture.Apply(); 

     sendTexture(texture, messageToSend); 

     // gameObject.renderer.material.mainTexture = TakeSnapshot; 

    } 

    public void DoSendTexture() 
    { 
     StartCoroutine(TakeSnapshot(Screen.width, Screen.height)); 
    } 

    // SERVER ////////////////////////// 

    //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); 

     Debug.Log("Texture Sent!!"); 
    } 

    // CLIENT ////////////////////////// 

    // 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("localhost", 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"); 
    } 
} 
+0

S'il vous plaît changer le titre et le corps de votre question pour refléter l'erreur que vous avez obtenu. Cliquez également sur l'erreur et ajoutez où l'erreur se produit dans votre question. – Programmer

+0

juste fait ces changements au titre et le message d'erreur – greyBow

Répondre

1

attendre la fin de la trame courante avant de prendre la capture d'écran ou avant d'appeler la fonction Texture2D.ReadPixels. Cela peut être fait avec la classe WaitForEndOfFrame. Notez comment je l'ai mis en cache pour éviter de créer un nouvel objet chaque fois que la fonction TakeSnapshot est appelée.

WaitForEndOfFrame frameEnd = new WaitForEndOfFrame(); 

public IEnumerator TakeSnapshot(int width, int height) 
{ 
    yield return frameEnd; 

    Texture2D texture = new Texture2D(800, 800, TextureFormat.RGB24, true); 
    texture.ReadPixels(new Rect(0, 0, 800, 800), 0, 0); 
    texture.LoadRawTextureData(texture.GetRawTextureData()); 
    texture.Apply(); 
    sendTexture(texture, messageToSend); 

    // gameObject.renderer.material.mainTexture = TakeSnapshot; 
} 

Je remarqué que vous avez yield return new WaitForSeconds(0.1F) dans votre script qui attend 0.2 secondes avant de prendre la capture d'écran. Si vous devez attendre 0.2 secondes, puis d'abord attendre 0.2 secondes, puis attendre la fin du cadre avant de prendre la capture d'écran:

WaitForSeconds waitTime = new WaitForSeconds(0.1F); 
WaitForEndOfFrame frameEnd = new WaitForEndOfFrame(); 

public IEnumerator TakeSnapshot(int width, int height) 
{ 
    yield return waitTime; 
    yield return frameEnd; 

    Texture2D texture = new Texture2D(800, 800, TextureFormat.RGB24, true); 
    texture.ReadPixels(new Rect(0, 0, 800, 800), 0, 0); 
    texture.LoadRawTextureData(texture.GetRawTextureData()); 
    texture.Apply(); 
    sendTexture(texture, messageToSend); 

    // gameObject.renderer.material.mainTexture = TakeSnapshot; 
}