0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

class ExWebSocketBehavior の中からGameObjectをいじりたい

Posted at

結論

ExWebSocketBehaviorから直接GameObjectをいじらずに、いったんテキストでメインclassに転送してからvoid Update()で動かせばよろしい。

背景

unityでネットワークを使うのにwebsocket-sharpとかいうのがあるらしい。
単にwebsocketを使うだけならググればたくさん出てくるのでそちらに任せるとして。(例↓)

みょんなことから友人にWebsocket-sharp.dll(ビルド済み)をもらったので、これで遊ぼう。
スマホのジャイロをパソコンに送って、パソコン上の何かGameObjectを動かせたら楽しそうだと思ったのだ。

過ち

perplexityにサンプルを書かせてテキトウに編集して、次のように構想した。

websocketManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using WebSocketSharp;
using WebSocketSharp.Server;
using System;

public class websocketManager : MonoBehaviour
{
    //websocket受信時に動かしたい何かしらのGameObject
    public GameObject[] myGameObject;

    WebSocketServer ws;
    // Start is called before the first frame update
    void Start()
    {
        //ポート番号を指定
        ws = new WebSocketServer(12345);
        //クライアントからの通信時の挙動を定義したクラス、「ExWebSocketBehavior」を登録
        ws.AddWebSocketService<ExWebSocketBehavior>("/");
        //サーバ起動
        ws.Start();
    }
    private void OnApplicationQuit()
    {
        Debug.Log("サーバ停止");
        ws.Stop();
    }


    // Update is called once per frame
    void Update()
    {//何も書いていない
    }


    public class ExWebSocketBehavior : WebSocketBehavior
    {
        //誰かがメッセージを送信してきたときに呼ばれるメソッド
        protected override void OnMessage(MessageEventArgs e)
        {
            string str = e.Data;
            Debug.Log("受信データ: " + str); // ここで文字列や数値を受信   
            
            //ここでmyGameObjectの処理をしたい。

            //↓これが動かない(今はテキトウに(1,2,3)とかしてるけど文字列をparseするとかを予定)
            myGameObject[0].transform.localPosition = new Vector3(1, 2, 3);
            
        }
    }
}

エラーが出た。

エラー
'websocketManager.myGameObject' で、オブジェクト参照が必要です

よく考えてみればそれもそうか。myGameObjectは上位(websocketManager)のclass内変数なわけで、下位(ExWebSocketBehavior)のclassから参照も編集もできるわけないよな。
よっし、じゃあパプる(perplexityに相談する)ぞ。

メインのclassの先頭で

    //websocketなclassからも参照できるようにするコード
    public static websocketManager Instance;
    void Awake()
    {
        Instance = this;
    }

をしてから、ExWebSocketBehaviorの中で

websocketManager.Instance.myGameObjects[0]

といった感じでアクセスできるようになるらしい。確かにエラーも何も出ていないが…
でもplayしてみても何も動かない。うーん?

原因

UnityではGameObjectの操作はメインスレッドでしか実行できないらしい。ExWebSocketBehaviorのようなメインでないところからは直接GameObjectをいじれない模様。

解決

websocketManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using WebSocketSharp;
using WebSocketSharp.Server;
using System;

public class websocketManager : MonoBehaviour
{
+   public static websocketManager Instance;
+   void Awake()
+   {
+       Instance = this;
+   }
    //websocket受信時に動かしたい何かしらのGameObject
    public GameObject[] myGameObject;
+   //websocketで受信したテキストをそのまま格納するリスト
+   List<string> strlist = new List<string>(); 

    WebSocketServer ws;
    // Start is called before the first frame update
    void Start()
    {
        //ポート番号を指定
        ws = new WebSocketServer(12345);
        //クライアントからの通信時の挙動を定義したクラス、「ExWebSocketBehavior」を登録
        ws.AddWebSocketService<ExWebSocketBehavior>("/");
        //サーバ起動
        ws.Start();
    }
    private void OnApplicationQuit()
    {
        Debug.Log("サーバ停止");
        ws.Stop();
    }


    // Update is called once per frame
    void Update()
    {
+       if (strlist.Count > 0)
+       {
+           string str = strlist[0];
+           strlist.RemoveAt(0);
+           //ここで受信した文字列を処理する
+           //処理結果をイイカンジに反映させる
+           myGameObject[0].transform.localPosition = new Vector3(1, 2, 3);
+       }
    }


    public class ExWebSocketBehavior : WebSocketBehavior
    {
        //誰かがメッセージを送信してきたときに呼ばれるメソッド
        protected override void OnMessage(MessageEventArgs e)
        {
            string str = e.Data;
            Debug.Log("受信データ: " + str); // ここで文字列や数値を受信   
            
-           //ここでmyGameObjectの処理をしたい。

-           //↓これが動かない(今はテキトウに(1,2,3)とかしてるけど文字列をparseするとかを予定)
-           myGameObject[0].transform.localPosition = new Vector3(1, 2, 3);

+           //ここでは何も処理せず、ただメインに受信した文字列を投げる
+           websocketManager.Instance.strlist.Add(str);
            
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?