「Unity&Photon」オンラインで名前を入力して頭上に表示する

なるべく簡単で処理もすくなめにしたいので、(これが長い戦いのきっかけ)

【Unity】uGUIをキャラクターの上に表示する手っ取り早い方法【RenderMode別】

 

やってみた事(興味ない人は最後の解決策へ)

3Dテキストでやってみる

なんかできるだけスクリプトいじりたくなくて、3Dテキストを子オブジェクトにしたら簡単にできんじゃね?

背景となるスプライトを3Dテキストでサンドイッチして正面と裏からなら名前がわかるようにしたんだけど

文字がうまい具合に表示されなくて断念。

 

Canvasでやってみる

CanvasのTextでこオブジェクトに設定してみたら、表示は問題ないんだけど大きさがそのオブジェクトによって変わってしまう。ちなみにWorld座標に変える必要があるよ。

素直にスクリプトでやっとけばよかった感がでてまいりました。

 

名前を入力→シーン切り替え→その名前をCanvasのTextに代入してみる(失敗例ね)

InputFieldを作る。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayButton : MonoBehaviour
{
    
    public static string Name;
    public InputField inputField;
    public GameObject inputFieldOb;

    // Use this for initialization
    void Start ()
    {
        inputField = inputFieldOb.GetComponent <InputField> ();
        /*InitInputField ();*/
    }
    
    // Update is called once per frame
    void Update ()
    {
        Name = inputField.text;
    }

    public void PushPlay ()
    {
        SceneManager.LoadScene (SelectScene);
    }

    public static string getName ()
    {
        return Name;
    }
        
}


で、名前をうけとって、PushPlayをおしたらシーンが切り替わりpublic static string getName ()  { return Name;}でゲーム全体として保存。

 

次のシーンのスクリプト

 

using UnityEngine.UI;

public string ReceiveName;
    public GameObject PlayerCanvas;
    public GameObject PlayerUI;
    public Text PlayerUItext;

void Start ()
    {
        ReceiveName = PlayButton.getName ();
        Nameseisei ();
    }

 

void Nameseisei ()
    {
        PlayerCanvas = instaDoubutu1.transform.GetChild (0).gameObject;
        PlayerUI = PlayerCanvas.transform.GetChild (1).gameObject;
        PlayerUItext = PlayerUI.GetComponent <Text> ();
        PlayerUItext.text = ReceiveName;

    }

 

 

 ReceiveName = PlayButton.getName ();でうけとったやつを代入

 

PlayerCanvas = instaDoubutu1.transform.GetChild (0).gameObject;
PlayerUI = PlayerCanvas.transform.GetChild (1).gameObject;
        PlayerUItext = PlayerUI.GetComponent <Text> ();
        PlayerUItext.text = ReceiveName;

で実際に入れてる感じ。

 

 

で、こっからはオンラインのはなし

いま現在は名前自体が他プレイヤーに名前データがわたされていないので、それを渡して他のプレイヤーに自分の名前が表示されるようにする。

 

オンラインで名前を表示する

今回は自分自身が生成したプレイヤーとなるキャラクターの上につける。

うーん、よくわからんがとりまやってみようか。

//情報を送りたいものはplayerUI.text
    void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
    {
        
        if (stream.isWriting) {
            stream.SendNext (PlayerUI);
        } else {
            PlayerUI = (GameObject)stream.ReceiveNext ();
        }
    }

うーん、まあできないよね

どおうすればいいんだ?

 

解決策

 

 

 

 

 

 

オンラインでこんな感じになりました

連続的な値の同期方法

 

とりあえず、プレイヤーにNameUIとなるテキストメッシュ(空のゲームオブジェクト)をつける。

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//動物にアタッチする
public class PlayerName : Photon.MonoBehaviour
{
    public string name;
    public string myName;

    void Start ()
    {
        if (photonView.isMine) {
            ChangeMyName ();
        }

    }

    void ChangeMyName ()
    {
      name = PlayButton.getName ();
        this.gameObject.name = name;
        transform.Find (NameUI).gameObject.GetComponent<TextMesh> ().text = name;
    }

    //情報を送りたいものはplayerUI.text
    void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
    {

        if (stream.isWriting) {
            myName = this.gameObject.name;
            stream.SendNext (myName);
        } else {
            myName = (string)stream.ReceiveNext ();
            transform.Find (NameUI).gameObject.GetComponent <TextMesh> ().text = myName;
        }
    }
}

 

if (photonView.isMine) {
            ChangeMyName ();
        }

で自分だけChangeMyName ();していて、

 name = PlayButton.getName ();は他のシーンのスクリプトからstringの値を取得してnameに代入しています。

ちなみにそのシーンのスクリプトが

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class PlayButton : MonoBehaviour
{
    
    public static string Name;
    public InputField inputField;
    public GameObject inputFieldOb;

    // Use this for initialization
    void Start ()
    {
        inputField = inputFieldOb.GetComponent <InputField> ();
        /*InitInputField ();*/
    }
    
    // Update is called once per frame
    void Update ()
    {
        Name = inputField.text;
    }

    public void PushPlay ()
    {
        SceneManager.LoadScene (SelectScene);
    }

    public static string getName ()
    {
        return Name;
    }
        
}


で、InputFieldという名前入力できる機能を使っています。

わざわざシーンを移行する必要はないのですが、こんな風に僕はやりました。

 

で、最初のスクリプトに戻って、

 if (stream.isWriting) {
            myName = this.gameObject.name;
            stream.SendNext (myName);
        }

で送信して

else {
            myName = (string)stream.ReceiveNext ();
            transform.Find (NameUI).gameObject.GetComponent <TextMesh> ().text = myName;
        }

で、受け取った場合の処理を書いています。

 

ちょっとわかりにくいかな?

 

inputFieldで名前入力→シーンを切り替えて→そこで先ほどの値を取得PlayButton.getName (); →自分がif (photonView.isMine) なら
ChangeMyName ();を実行して→  オンラインの情報を操作する

 

という流れでした。

 

 

実はこの長い記事がなぜかバグってたのでもう一度書きました。今日は他にもワードで文書書いていたら間違えて完全に削除してしまいました。(自己責任)

1日で二回です。まじでF○○kです。

みなさん、こまめにバックアップ取りましょう。

こんな面倒な事になりたくないなら。

 

そして、この長い戦いにおつかれさま。

 

追記:

 

オンラインで名前をカメラの方向に向かせる

えーと、どう処理すればいいんだ?

まず、(Photon.isMine)で自分自身で他のカメラを取得して、それでカメラの目標位置に自分を設定してあげればいいのかな??

transform.lookatを使うか

 

いや、そもそも同期をとる必要がないのか

つまり自分が生成されたと同時にカメラの目標位置に自分を設定してあげればいいのか!

まず、生成されたタイミングで既にあるNameUIのNameUIスクリプトに合図して、生成された自分に対してテキストを向かせる。

 

はい、なんか色々考えましたが、単純にこうなりました

using UnityEngine;
using System.Collections;

public class TextController : MonoBehaviour
{
    public GameObject targetOb;
    public GameObject target;

    void Start ()
    {
        targetOb = GameObject.FindGameObjectWithTag (MyPlayer);
        target = targetOb.transform.Find (MainCamera).gameObject;
    }

    void Update ()
    {
        transform.LookAt (target.transform);
    }
}

 

これを名前のテキストにアタッチ

そしてPhotonViewを設置したぷれいやーに

void Start ()
    {
        if (photonView.isMine) {
            this.gameObject.tag = MyPlayer;
        }
    }

 

なんかようわからんがこれで解決!ラッキー!

3人以上いても、それぞれの名前がカメラに向くようになりました!

 

自分の名前は表示しない

Photon.Viewをつけたプレイヤーのスクリプト↓

void Start ()
    {
        if (photonView.isMine) {
            this.gameObject.transform.Find (NameUI).gameObject.SetActive (false);
        }

    }

 

 

 

貼ったけど念のために載せておく

プレイヤーにつけるやつ。PhotonViewもちろんつける

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

//動物にアタッチする
public class PlayerName : Photon.MonoBehaviour
{
    public string name;
    public string myName;

    void Start ()
    {
        if (photonView.isMine) {
            ChangeMyName ();
            this.gameObject.tag = MyPlayer;
            this.gameObject.transform.Find (NameUI).gameObject.SetActive (false);
        }

    }

    void ChangeMyName ()
    {
        name = PlayButton.getName ();
        this.gameObject.name = name;
        transform.Find (NameUI).gameObject.GetComponent<TextMesh> ().text = name;
    }

    //情報を送りたいものはplayerUI.text
    void OnPhotonSerializeView (PhotonStream stream, PhotonMessageInfo info)
    {

        if (stream.isWriting) {
            myName = this.gameObject.name;
            stream.SendNext (myName);
        } else {
            myName = (string)stream.ReceiveNext ();
            transform.Find (NameUI).gameObject.GetComponent <TextMesh> ().text = myName;
        }
    }
}

 

テキストをカメラの方向にむかせるやつ

using UnityEngine;
using System.Collections;

public class TextController : MonoBehaviour
{
    public GameObject targetOb;
    public GameObject target;

    void Start ()
    {
        targetOb = GameObject.FindGameObjectWithTag (MyPlayer);
        target = targetOb.transform.Find (MainCamera).gameObject;
    }

    void Update ()
    {
        transform.LookAt (target.transform);
    }
}

コメントする

メールアドレスが公開されることはありません。

CAPTCHA