//tips
//vivox理解
Chat機能を追加するためのUIをまずは整備し、スクリプトを書き加えていく。
UIを追加し、スタートメソッドにあらかじめ作成した文言の生成を実行させたが一行分しか生成しない。
[SerializeField] Text txt_UserName;
[SerializeField] Text txt_ChannelName;
[SerializeField] Text txt_Message_Prefab;
[SerializeField] TMP_InputField tmp_Input_Username;
[SerializeField] TMP_InputField tmp_Input_ChannelName;
[SerializeField] TMP_InputField tmp_Input_SendMessages;
[SerializeField] Image container;
void Start()
{
//loginCallback = new AsyncCallback(Login_Result);
Instantiate(txt_Message_Prefab,container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
}
Containaerを下に広げていくと文字が表示されるが、一行目と次の行までの間隔がかなり広くなっている。
Unityのscrollviewの使い方をおさらいする必要がありそう。
まず別途シーンにscrollviewを作成。
スクロールの範囲が上限いっぱいのためかスクロールバーが右下ともに動かない。実行ボタンを押すとどちらのバーも消えてしまう。
記載内容がないからかもしれないので、表示内容を納めるviewportのcontentに内容を追加。
スクロールが必要な程度の長い数字の羅列を記載した。
アンカーをストレッチに変更。さらにcontentsizefitterをコンポーネントに追加することでバーのスクロールを可能にし、下部まで表示することができるようになった。
元のシーンに戻り、containerに対して、contentsizefitterをコンポーネントに追加、アンカーをストレッチに変更することでスクロールは可能になった。
ただ、文言の間の空白は消えない。containerに生成されるtextのy座標を見ていると130程度の間隔で生成が行われている。
containerのgrid layout groupのcellsizeを変更することで間隔を調整することができた。
ただ、なぜか表示領域が上から順にではなく真ん中でのscrollview表示となっている。
このスクロールビューの使い方については後で見直す。
C#のregionを使い、後から見やすいように、スクリプトのregion部分を折り畳めるようにしながら、記述を進める。
Visual studio for Macでは下記参考に設定を行う。
https://docs.microsoft.com/ja-jp/visualstudio/mac/source-editor?view=vsmac-2019
Chatのところは次にしてチャンネルログインの部分を実装した。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VivoxUnity;
using System.ComponentModel;
using System;
using UnityEngine.UI;
using TMPro;
public class LoginCredentials : MonoBehaviour
{
VivoxUnity.Client client;
private Uri server = new Uri("https://mt1s.www.vivox.com/api2");
private string issuer = "akihir3052-vo35-dev";
private string domain = "mt1s.vivox.com";
private string tokenKey = "bulb358";
private TimeSpan timeSpan = TimeSpan.FromSeconds(90);//new TimeSpan(90);//TimeSpan.FromSeconds(90);
//private AsyncCallback loginCallback;
private ILoginSession loginSession;
private IChannelSession channelSession;
[SerializeField] Text txt_UserName;
[SerializeField] Text txt_ChannelName;
[SerializeField] Text txt_Message_Prefab;
[SerializeField] TMP_InputField tmp_Input_Username;
[SerializeField] TMP_InputField tmp_Input_ChannelName;
[SerializeField] TMP_InputField tmp_Input_SendMessages;
[SerializeField] Image container;
private void Awake()
{
client = new Client();
client.Uninitialize();
client.Initialize();
DontDestroyOnLoad(this);
}
private void OnApplicationQuit()
{
client.Uninitialize();
}
void Start()
{
//loginCallback = new AsyncCallback(Login_Result);
Instantiate(txt_Message_Prefab,container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
Instantiate(txt_Message_Prefab, container.transform);
}
public void Bind_Login_Callback_Listeners(bool bind,ILoginSession loginSesh)
{
if (bind == true)
{
loginSesh.PropertyChanged += Login_Status;
}
else
{
loginSesh.PropertyChanged -= Login_Status;
}
}
public void Bind_Channelsession_Callback_Listeners(bool bind, IChannelSession channelSesh)
{
if (bind == true)
{
channelSesh.PropertyChanged += On_Channel_Status_Changed;
}
else
{
channelSesh.PropertyChanged -= On_Channel_Status_Changed;
}
}
#region Login Method
public void LoginUser()
{
Login(tmp_Input_Username.text);
}
public void Login(string userName)
{
AccountId accountId = new AccountId(issuer, userName, domain);
loginSession = client.GetLoginSession(accountId);
Bind_Login_Callback_Listeners(true, loginSession);
loginSession.BeginLogin(server, loginSession.GetLoginToken(tokenKey, timeSpan), ar =>
{//loginCallback,Login_Resultを作成すると下記が不要になる。
try
{
loginSession.EndLogin(ar);//ログインが終わったらログイン完了のresult非同期
}
catch (Exception e)
{
Bind_Login_Callback_Listeners(false, loginSession);
Debug.Log(e.Message);
}
});
}
public void Logout()
{
loginSession.Logout();
Bind_Login_Callback_Listeners(false, loginSession);
}
public void Login_Status(object sender, PropertyChangedEventArgs loginArgs)
{
var source = (ILoginSession)sender;
switch (source.State)
{
case LoginState.LoggingIn:
Debug.Log("Logging In");
break;
case LoginState.LoggedIn:
Debug.Log($"Logged In");
break;
}
}
#endregion
#region Join Channel Methods
public void JoinChannel(string channelName,bool IsAudio,bool IsText,bool switchTransmission,ChannelType channelType) {
ChannelId channelId = new ChannelId(issuer, channelName, domain,channelType);
channelSession = loginSession.GetChannelSession(channelId);
Bind_Channelsession_Callback_Listeners(true,channelSession);
channelSession.BeginConnect(IsAudio, IsText, switchTransmission, channelSession.GetConnectToken(tokenKey, timeSpan),ar=>
{//ここの引数をtrueではなく視覚的にわかりやすくするためにbool IsAudioなどでメソッドの引数をそのまま渡す形にしている。
try
{
channelSession.EndConnect(ar);
}
catch(Exception e)
{
Bind_Channelsession_Callback_Listeners(false, channelSession);
Debug.Log(e.Message);
}
});
}
public void Leave_Channel(IChannelSession channelToDisconnect,string channelName)
{
channelToDisconnect.Disconnect();
loginSession.DeleteChannelSession(new ChannelId(issuer, channelName, domain));
}
public void Btn_Join_Channel()
{
JoinChannel(tmp_Input_ChannelName.text, true, true, true, ChannelType.NonPositional);
}
public void Btn_Leave_Channel_Clicked()
{
Leave_Channel(channelSession,tmp_Input_ChannelName.text);
}
public void On_Channel_Status_Changed(object sender,PropertyChangedEventArgs channelArgs)
{
IChannelSession source = (IChannelSession)sender;
switch(source.ChannelState)
{
case ConnectionState.Connecting:
Debug.Log("Connecting");
break;
case ConnectionState.Connected:
Debug.Log($"{source.Channel.Name} Connected");
break;
case ConnectionState.Disconnecting:
Debug.Log("Disconnecting");
break;
case ConnectionState.Disconnected:
Debug.Log("Disconnected");
break;
}
}
#endregion
}
Sampleのvivoxmanagerのものを使わないで自らの手で少しずつ描いていくので理解が深まる。