IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Unity et Websocket en C# [Débutant]


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 37
    Points : 62
    Points
    62
    Par défaut Unity et Websocket en C#
    Bonjour a tous.
    Voici le contexte:
    J'ai créer une scene sous unity composé d'une capsule nommée MaCapsule, d'un Plan et d'un Cube.
    J'ai créé un script C# que j'ai associé à mon cube, et lorsque je clic sur le cube, la capsule se déplace.
    Ce script fonctionne très bien.
    J'ai ensuite voulu faire bouger ma capsule en fonction de données reçu via une websocket.
    J'ai créé un script WebSocket client, qui fontionne bien, il reçoit bien les données en provenance du serveur de websocket et les affiches sans erreur.
    J'ai modifié mon script afin que la capsule bouge quand je recoit des données en provenance du serveur et c'est là que ça ne fonctionne plus.
    Lors de la réception d'une donnée, l'appel à la méthode qui permet le déplacement de la capsule est bien fait, mais j'ai une levée d'exception lié à la websocket lorsque j'arrive à la ligne Debug.Log("son nom : " + maCapsule.name); de la méthode VersLeHaut().
    Si quelqu'un peut m'expliquer ce que ne va pas, merci d'avance.
    Voici le code de mon script:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    // WebSocketClient.cs
    using UnityEngine;
    using WebSocketSharp;
    using WebSocketSharp.Net.WebSockets;
     
    public class WebSocketClient: MonoBehaviour {
      private WebSocket ws;
      public GameObject maCapsule;
      public float hauteurDeplacement = 1.0 f;
     
      // Vitesse de déplacement de la capsule
      public float vitesseDeplacement = 5.0 f;
     
      public void VersLeHaut() {
        Debug.Log("dans vers le haut");
        // Vérifie si la capsule est définie
     
        Debug.Log("son nom : " + maCapsule.name);
        if (maCapsule != null) {
          Debug.Log("La capsule est connue");
          // Calcule la position cible de la capsule (vers le haut)
          Debug.Log("info maCapsule" + maCapsule.transform.position);
          Vector3 positionCible = new Vector3(
            maCapsule.transform.position.x,
            maCapsule.transform.position.y * 30,
            maCapsule.transform.position.z);
          Debug.Log("apres calcul position cible");
          // Déplace la capsule vers la position cible
          maCapsule.transform.position = Vector3.Lerp(maCapsule.transform.position, positionCible, Time.deltaTime * vitesseDeplacement);
          Debug.Log("apres deplacement vers position cible");
          Renderer capsuleRenderer = maCapsule.GetComponent < Renderer > ();
          Debug.Log("apres recuperation du render de la capsule");
          if (capsuleRenderer != null) {
            Debug.Log("changement de la couleur de la capsule");
            capsuleRenderer.material.color = Color.blue;
          } else {
            Debug.LogError("Le composant Renderer est manquant sur la capsule !");
          }
        } else {
          Debug.Log("La capsule n'est pas connu");
        }
     
      }
      public void Traitement(object sender, MessageEventArgs e) {
        // Vérifier si le message est un objet JSON
        if (e.IsText) {
          // Analyser le message JSON
          var json = e.Data;
          var obj = JsonUtility.FromJson < JsonObject > (json);
          Debug.Log("Message reçu : " + json);
          // Vérifier si les propriétés x, y et z sont égales à 15, 0 et 0 respectivement
          if (obj.x == 15 && obj.y == 0 && obj.z == 0) {
            Debug.Log("Message reçu et good coordonnées: " + json);
          }
          Debug.Log("avant le Invoke: ");
          //Invoke("VersLeHaut",0.0f);
          VersLeHaut();
          Debug.Log("après le Invoke: ");
     
        }
      }
     
      void Start() {
     
        maCapsule = GameObject.Find("MaCapsule");
     
        // Créer une instance WebSocket
     
        ws = new WebSocket("ws://127.0.0.1:8888");
     
        // Définir les gestionnaires d'événements
        ws.OnOpen += (sender, e) => {
          Debug.Log("WebSocket ouvert");
        };
     
        ws.OnMessage += (sender, e) => Traitement(sender, e);
     
        ws.OnError += (sender, e) => {
          Debug.LogError("Erreur WebSocket : " + e.Message);
        };
     
        ws.OnClose += (sender, e) => {
          Debug.Log("WebSocket fermé");
        };
     
        // Connecter le client WebSocket
        ws.Connect();
      }
     
      void OnDestroy() {
        // Fermer la connexion WebSocket lorsque le script est détruit
        if (ws != null) {
          ws.Close();
        }
      }
      private void OnMouseDown() {
        Debug.Log("clic sur le cube");
        VersLeHaut();
     
      }
     
      // Classe pour représenter l'objet JSON
      [System.Serializable]
      public class JsonObject {
        public int x;
        public int y;
        public int z;
      }
    }
    Et voici l'erreur générée:
    Erreur WebSocket : An exception has occurred during an OnMessage event.
    UnityEngine.Debug:LogError (object)
    WebSocketClient/<>c:<Start>b__6_2 (object,WebSocketSharp.ErrorEventArgs) (at Assets/Scenes/WebSocketClient.cs:95)
    WebSocketSharp.Ext:Emit<WebSocketSharp.ErrorEventArgs> (System.EventHandler`1<WebSocketSharp.ErrorEventArgs>,object,WebSocketSharp.ErrorEventArgs) (at Assets/Scenes/Plugins/websocket-sharp/Ext.cs:412)
    WebSocketSharp.WebSocket:error (string,System.Exception) (at Assets/Scenes/Plugins/websocket-sharp/WebSocket.cs:1546)
    WebSocketSharp.WebSocket:messagec (WebSocketSharp.MessageEventArgs) (at Assets/Scenes/Plugins/websocket-sharp/WebSocket.cs:1606)
    WebSocketSharp.WebSocket:message () (at Assets/Scenes/Plugins/websocket-sharp/WebSocket.cs:1593)
    WebSocketSharp.WebSocket/<>c__DisplayClass166_0:<startReceiving>b__1 (WebSocketSharp.WebSocketFrame) (at Assets/Scenes/Plugins/websocket-sharp/WebSocket.cs:2358)
    WebSocketSharp.WebSocketFrame/<>c__DisplayClass83_0:<ReadFrameAsync>b__3 (WebSocketSharp.WebSocketFrame) (at Assets/Scenes/Plugins/websocket-sharp/WebSocketFrame.cs:787)
    WebSocketSharp.WebSocketFrame/<>c__DisplayClass75_0:<readPayloadDataAsync>b__0 (byte[]) (at Assets/Scenes/Plugins/websocket-sharp/WebSocketFrame.cs:570)
    WebSocketSharp.Ext/<>c__DisplayClass51_0:<ReadBytesAsync>b__0 (System.IAsyncResult) (at Assets/Scenes/Plugins/websocket-sharp/Ext.cs:762)
    System.Threading._ThreadPoolWaitCallbackerformWaitCallback ()

  2. #2
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    645
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 645
    Points : 2 165
    Points
    2 165
    Par défaut
    Bonjour,

    Question bête mais maCapsule est bien récupérée ? Parce que si ça bug sur un simple Debug.Log, soit l'erreur est asynchrone, soit c'est ta variable qui est nulle. En plus ton Debug.Log intervient juste avant la vérification de nullité.

    Vérifie juste ça, pas que l'erreur soit encapsulée dans un try / catch du Websocket et que ça te mène en bateau.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 37
    Points : 62
    Points
    62
    Par défaut
    Bon, alors j'ai mis des try/catch, ce qui m'a permis d'avoir une erreur plus précise:
    Error parsing JSON data: get_transform can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
    Du coup j'ai trouvé une solution en ajoutant ce script à ma scene:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
     
    public class MainThreadDispatcher : MonoBehaviour
    {
        private static MainThreadDispatcher instance;
     
        private Queue<Action> actions = new Queue<Action>();
     
        private void Awake()
        {
            if (instance != null)
            {
                Destroy(gameObject);
                return;
            }
     
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
     
        private void Update()
        {
            while (actions.Count > 0)
            {
                actions.Dequeue().Invoke();
            }
        }
     
        public static void Enqueue(Action action)
        {
            instance.actions.Enqueue(action);
        }
    }
    et en modifiant ma méthode VersLeHaut() en l'encadrant avec ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void VersLeHaut()
    { 
         Debug.Log("dans vers le haut" );
        // Vérifie si la capsule est définie
          MainThreadDispatcher.Enqueue(() =>
        {  ...});
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 30/06/2008, 09h21
  2. Communication PLC sous Unity V3.0
    Par bboule10 dans le forum Automation
    Réponses: 2
    Dernier message: 14/05/2008, 23h46
  3. Reherche talents sur Unity 3D [partenaire]
    Par Chand dans le forum Autres
    Réponses: 1
    Dernier message: 25/02/2008, 12h18
  4. Accèder à un objet d'un FormX dans le code d'un unitY
    Par Akeon dans le forum C++Builder
    Réponses: 2
    Dernier message: 06/04/2007, 09h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo