質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Unity

    3590questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

RPCを使ったチャットについて教えてください。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 136

4063sk

score 1

 前提・実現したいこと

RPCを使ってチャットシステムを作っています。
GUILayoutを使って書いてあるデモの表示がバグる時があるので、
GUILayoutから半分コピペをしながら、UIに書き換えている時に以下の問題が発生しました。
コードが汚くて申し訳ないです。
初心者なのでわかりやすく教えていただけると嬉しいです。

 発生している問題

[PunRPC]
    public void Chat(Vector3 senderposition, string newLine, bool isAll, PhotonMessageInfo mi)
のところの`PhotonMessageInfo mi`nullになってしまう。

 ソースコード

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

[RequireComponent(typeof(PhotonView))]
public class RoomChatScript : Photon.MonoBehaviour
{

    GameObject[] players;   //全てのプレイヤーキャラ取得用
    //GameObject sender;      //送信キャラ取得用
    GameObject myPlayer;    //自分のキャラ取得用
    //GUIStyle ChatStyle = new GUIStyle();    //範囲チャットStyle
    //GUIStyleState ChatStyleState = new GUIStyleState();
    //GUIStyle AllChatStyle = new GUIStyle(); //全体チャットStyle
    //GUIStyleState AllChatStyleState = new GUIStyleState();
    public bool IsVisible = true;   //チャットUI表示非表示フラグ
    public bool AlignBottom = true;
    public List<string> messages = new List<string>();  //チャットログ格納用List
    public List<bool> chatKind = new List<bool>(); //チャットログの種類格納用(範囲チャor全チャ)
    public string inputLine = "";//入力文章格納用String
    public Scrollbar scrollPos;
    public Text UItext;
    public InputField mesetext;
    public GameObject[] UI;
    public Image RoomChatUI;

    private Color RCUColor;
    private bool all;
    private bool send;
    PhotonView photonViews;

    // Use this for initialization
    void Start () {
        photonViews = GetComponent<PhotonView>();
        RCUColor = RoomChatUI.color;
        //myPlayerオブジェクト取得(範囲チャット発言時にpositionとmyPM使う)
        GetmyPlayer();
        Debug.Log(myPlayer);
        //範囲チャットの場合は白文字にし、文字がUIからあふれた場合は折り返す設定
        //ChatStyleState.textColor = Color.white;
        //ChatStyle.normal = ChatStyleState;
        //ChatStyle.wordWrap = true;
        //全体チャットの場合は赤文字にし、文字がUIからあふれた場合は折り返す設定
        //AllChatStyleState.textColor = Color.blue;
        //AllChatStyle.normal = AllChatStyleState;
        //AllChatStyle.wordWrap = true;
    }

    // Update is called once per frame
    void Update()
    {
        inputLine = mesetext.text;
        //FocusがチャットUIに乗ってるときにEnterを押すとチャット発言が実行される
        if (Input.GetKeyDown(KeyCode.Return))
        {
            if (!string.IsNullOrEmpty(this.inputLine))  //チャット入力欄がNullやEmptyでない場合
            {
                //範囲チャット送信関数実行
                SendChat(false);
                return;
            }
            else
            {
                this.GetComponent<RoomChatUIScript>().PanelClick = true;
            }
        }

        UItext.text = "";

        for (int i = 0; i <= messages.Count - 1; i++)
        {
            if (chatKind[i] != true)    //範囲チャットであれば
            {
                if (i != 0) UItext.text += System.Environment.NewLine;
                UItext.text += string.Format("<color=white>{0}</color>", messages[i]);

                //GUILayout.Label(messages[i], ChatStyle);
            }
            else                        //全チャットであれば
            {
                if (i != 0) UItext.text += System.Environment.NewLine;
                UItext.text += string.Format("<color=green>{0}</color>", messages[i]);
                //GUILayout.Label(messages[i], AllChatStyle);
            }
        }

        //「Send」ボタンを生成かつ押したときには範囲チャット送信
        /*if (GUILayout.Button("Send", GUILayout.ExpandWidth(false)))
        {
            //範囲チャット送信関数実行
            SendChat(false);
        }
        //Allボタンを生成かつ押したときには全体チャット送信
        if (GUILayout.Button("All", GUILayout.ExpandWidth(false)))
        {
            //全体チャット送信関数実行
            SendChat(true);
        }*/
        if (myPlayer != null)
        {
            if (send)
            {
                //範囲チャット送信関数実行
                SendChat(false);
                send = false;
            }
            if (all)
            {
                //全体チャット送信関数実行
                SendChat(true);
                all = false;
            }
        }else{
            GetmyPlayer();
            Debug.Log(myPlayer);
        }
        if(IsVisible || PhotonNetwork.inRoom){
            for(int i = 0; i <= UI.Length - 1; i++){
                UI[i].SetActive(true);
            }
            RoomChatUI.color = RCUColor;
        }else{
            for (int i = 0; i <= UI.Length - 1; i++)
            {
                UI[i].SetActive(false);
            }
            RoomChatUI.color = new Color(0, 0, 0, 0);
        }
    }

    void GetmyPlayer()
    {
        //自キャラのID取得
        int myPlayerID = PhotonNetwork.player.ID;
        //全てのプレイヤーオブジェクトを取得
        players = GameObject.FindGameObjectsWithTag("Player");
        //全てのプレイヤーオブジェクトから自キャラをIDで検索し、取り出す
        foreach (GameObject player in players)
        {
            int playerLoopId = player.GetComponent<PhotonView>().owner.ID;
            if (playerLoopId == myPlayerID)
            {
                //自プレイヤーオブジェクトを取得
                myPlayer = player;
            }
        }
        return;
    }

    void SendChat(bool isAll)
    {
        //chatRPC
        this.photonViews.RPC("Chat", PhotonTargets.All, myPlayer.transform.position, this.inputLine, isAll, null);
        //送信後、入力欄を空にし、スクロール最下位置に移動
        mesetext.text = "";
        scrollPos.value = 0;
        return;
    }

    [PunRPC]
    public void Chat(Vector3 senderposition, string newLine, bool isAll, PhotonMessageInfo mi)
    {
        Debug.Log("mi : " + mi);
        if (messages.Count >= 100)          //チャットログが多くなって来たらログを削除してから受信
        {
            messages.Clear();               //全てのチャットログを削除
            chatKind.Clear();               //全てのチャットの種類情報削除
        }
        if (!isAll) //範囲チャとして受信
        {
            //myPlayerとsenderの距離から受信するか判断
            if (Vector3.Distance(myPlayer.transform.position, senderposition) < 10)
            {
                //chat受信
                ReceiveChat(newLine, isAll, mi);
            }
        }
        else if (isAll) //全チャとして受信
        {
            //chat受信
            ReceiveChat(newLine, isAll, mi);
        }
        //受信したときはスクロール最下位置
        scrollPos.value = 0;
        return;
    }

    void ReceiveChat(string _newLine, bool isAll, PhotonMessageInfo _mi)
    {
        Debug.Log("_mi : " + _mi);
        //送信者の名前用変数
        string senderName = "anonymous";
        if (_mi.sender != null)
        {
            //送信者の名前があれば
            if (!string.IsNullOrEmpty(_mi.sender.NickName))
            {
                senderName = _mi.sender.NickName;
            }
            else
            {
                senderName = "player " + _mi.sender.ID;
            }
        }
        //受信したチャットをログに追加
        this.messages.Add(senderName + " : " + _newLine);
        this.chatKind.Add(isAll);
        return;
    }

    public void AddLine(string newLine)
    {
        this.messages.Add(newLine);
    }

    public void aall(bool t){
        all = t;
    }
    public void asend(bool t)
    {
        send = t;
    }
}

 試したこと

はじめはどこでエラーが出ているのかわからなくてDebug.Logを使って、いろいろ出力したところ原因はわかったのですが、ネットを使っても日本語での前例が見つからず、お手上げの状態です。

 補足情報

Unity 2017.4.1f1
Photon
参考サイトhttp://uniblo.biz/unity/mmogame/chapter8_chat

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

ざっくり見ただけなんで間違っているかもしれませんが、
void SendChat(bool isAll)の中で
this.photonViews.RPC("Chat", PhotonTargets.All, myPlayer.transform.position, this.inputLine, isAll, null);
これを呼んでいます。
これだと引数的にChat()のmiがnullになると思うのですが、原因ではないでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/21 16:00

    とてもわかりやすい回答ありがとうございました。
    無事に動きました。
    こんな単純なミスで申し訳ないです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    Unityでのナビゲーションラインの実装について

    unityでナビゲーションラインを実装したいと思っています。 画像中央の青いラインみたいなもの、プレイヤーから特定のオブジェクトに対して線を引き、方向を教える。 現在LineRe

  • 解決済

    unityのチャット機能について

    unityでチャットを実装しようとし、以下のスクリプトをかきpreftext(テキストのプレファブです)にネットワーク関連のコンポーネントとキャンバスを足したのですが、スタートして

  • 解決済

    unityでのキャラクターの復活

    unityで特定のオブジェクトにプレイヤーが触れた時プレイヤーがDestroyさせ、3秒後に初期位置で復活させるといった スクリプトを書きたいのですが、キャラクターをDestro

  • 受付中

    unityのCube四方向判定

    今playerの四方向を当たり判定を別々で 取ろうとしていますが上手く行きません 今やろうとしてるのは player(Cube)の上下左右がtrueなら playerを

  • 受付中

    Unity:Destroyした敵のリスポーン・復活

    前提・実現したいこと Unityにて3Dシューティングを作っています。 「弾が当たったら敵が消え、その3秒後に同じ位置にまた復活する」というコードを書きたいのですが、敵が消えるとこ

  • 解決済

    Unity UIの動的生成

    「B」というタグがついたCubeが「A」というタグのついたCubeに衝突したとき、所定の位置にUIを生成させようとしたのですが、なぜか見当違いな位置に生成されてしまいます。そして、

  • 解決済

    UnityでTCPを利用したチャットのやりとりをできるようにしたい(C#)

     前提・実現したいこと UnityでTCPを利用したチャットのやりとりをできるようにしたいんです。C# AcceptSocket(); を使っても BeginAcceptTcpCl

  • 解決済

    ゲームが終了した時GameOverにならない

    【Unity5】uGUIでタイトルとゲームオーバー画面を実装!Canvas, Text, Button【フラッピーバード風5】 ↑ こちらのサイトを参考にIsTriggerがOFに

同じタグがついた質問を見る

  • Unity

    3590questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。