
RAYSER 進捗(20230920)
トーク部分のクラス化
RAYSERのシーンスタート時のトーク部分をクラス化して、一行で呼び出せるようにしてみました。
RAYSERのトーク部分を修正していました。テキストの表示については直りましたが、今度はトークの合間のインターバルがないのが気になるので、後日少し調整してみようと思います。 pic.twitter.com/byvDA21pW5
— Cz_mirror (@Cz_mirror) September 20, 2023
using System;
using System.Threading;
using _RAYSER.Scripts.UI.Title;
using Cysharp.Threading.Tasks;
using Rayser.CustomEditor;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using VRM;
namespace _RAYSER.Scripts.UI
{
public class MissionStartWindowUI : MonoBehaviour, IWindowUI
{
UIActiveSetter _uiActiveSetter = new UIActiveSetter();
private IWindowUI _iuiImplementation;
UIEffect _uiEffect = new UIEffect();
private IUIEffect _ieffectImplementation;
private Vector3 _initialGameStartUIPosition = Vector3.zero;
private Vector2 _initialGameStartUISizeDelta = Vector2.zero;
private Vector3 _initialMissionWindowPosition = Vector3.zero;
private Vector2 _initialMissionWindowSizeDelta = Vector2.zero;
// private Vector3 _inUIPosition;
// private Vector3 _outUIPosition;
private String _messege;
private float _message_speed = 0.05f;
private Vector3 _initialPosition = Vector3.zero;
private Vector2 _initialUISizeDelta = Vector2.zero;
private CancellationTokenSource cts = new CancellationTokenSource();
private float setDeltaMinx = 0;
private float setDeltaMinY = 2f;
private float setDeltaDuration = 1f;
private float setmissionLightUITopEndValue = 1000;
private float setmissionLightUIBottomEndValue = -1000;
private float setmissionLightDuration = -0.5f;
[SerializeField] private CanvasGroup menuButtonsCanvasGroup;
[SerializeField] private RectTransform menuButtonsRectTransform;
[SerializeField] private CanvasGroup gameStartUICanvasGroup;
[SerializeField] private RectTransform gameStartUIRectTransform;
[SerializeField] private CanvasGroup missionWindowCanvasGroup;
[SerializeField] private RectTransform missionWindowRectTransform;
[SerializeField] private CanvasGroup missionLightUITopCanvasGroup;
[SerializeField] private RectTransform missionLightUITopRectTransform;
[SerializeField] private CanvasGroup missionLightUIBottomCanvasGroup;
[SerializeField] private RectTransform missionLightUIBottomRectTransform;
[SerializeField] private CanvasGroup faceWindowCanvasGroup;
[SerializeField] private CanvasGroup roydFaceWindowCanvasGroup;
[SerializeField] private CanvasGroup sophieFaceWindowCanvasGroup;
[SerializeField] private CanvasGroup roydTalkWindowCanvasGroup;
[SerializeField] private TextMeshProUGUI roydTextMeshPro;
[SerializeField] private CanvasGroup sophieTalkWindowCanvasGroup;
[SerializeField] private TextMeshProUGUI sophieTextMeshPro;
[SerializeField] private GameObject roydCamera;
[SerializeField] private GameObject sophieCamera;
[SerializeField] private MissionStartTalk _missionStartTalk;
[SerializeField] private SceneObject gameScene;
public UIActiveSetter UIActiveSetter
{
get => _iuiImplementation.UIActiveSetter;
set => _iuiImplementation.UIActiveSetter = value;
}
/// <summary>
/// キャンセルトークンにキャンセル要求を発行する
/// </summary>
private void Cancel()
{
cts.Cancel();
}
private void Awake()
{
_initialGameStartUIPosition = gameStartUIRectTransform.position;
_initialGameStartUISizeDelta = gameStartUIRectTransform.sizeDelta;
_initialMissionWindowPosition = missionWindowRectTransform.position;
_initialMissionWindowSizeDelta = missionWindowRectTransform.sizeDelta;
InitializeUI();
// UI無効
SetActive(false);
}
public void SetActive(bool isActive)
{
_uiActiveSetter.SetActive(gameObject, isActive);
}
private void InitializeUI()
{
_uiEffect.SetAlphaZero(gameStartUICanvasGroup);
_uiEffect.SetSizeDeltaZero(gameStartUIRectTransform);
_uiEffect.SetAlphaZero(missionWindowCanvasGroup);
_uiEffect.SetSizeDeltaZero(missionWindowRectTransform);
_uiEffect.SetAlphaZero(roydTalkWindowCanvasGroup);
_uiEffect.SetAlphaZero(sophieTalkWindowCanvasGroup);
_uiEffect.SetAlphaZero(roydFaceWindowCanvasGroup);
_uiEffect.SetAlphaZero(sophieFaceWindowCanvasGroup);
TalkMessageReset(roydTextMeshPro);
TalkMessageReset(sophieTextMeshPro);
// _inUIPosition = new Vector3(0, 0, 0);
// _outUIPosition = new Vector3(2000, 0, 0);
// gameStartUIRectTransform.position = _outUIPosition;
}
private void TalkMessageReset(TextMeshProUGUI textMeshProUGUI)
{
textMeshProUGUI.text = String.Empty;
}
public async UniTask ShowUI()
{
try
{
SetActive(true);
// GameStartUI表示
gameStartUIRectTransform.position = _initialGameStartUIPosition;
await _uiEffect.FadeIn(gameStartUICanvasGroup, cts.Token);
await _uiEffect.SizeDelta(gameStartUIRectTransform,
new Vector2(_initialGameStartUISizeDelta.x, setDeltaMinY), setDeltaDuration, cts.Token);
await _uiEffect.SizeDelta(gameStartUIRectTransform,
new Vector2(_initialGameStartUISizeDelta.x, _initialGameStartUISizeDelta.y), setDeltaDuration,
cts.Token);
await _uiEffect.FadeIn(gameStartUICanvasGroup, cts.Token);
// Mission表示
missionWindowRectTransform.position = _initialMissionWindowPosition;
await _uiEffect.FadeIn(missionWindowCanvasGroup, cts.Token);
await _uiEffect.SizeDelta(missionWindowRectTransform,
new Vector2(_initialMissionWindowSizeDelta.x, setDeltaMinY), setDeltaDuration, cts.Token);
await _uiEffect.SizeDelta(missionWindowRectTransform,
new Vector2(_initialMissionWindowSizeDelta.x, _initialMissionWindowSizeDelta.y), setDeltaDuration,
cts.Token);
// Mission光演出
_uiEffect.LocalMoveX(missionLightUITopRectTransform, setmissionLightUITopEndValue,
setmissionLightDuration, cts.Token);
await _uiEffect.LocalMoveX(missionLightUIBottomRectTransform, setmissionLightUIBottomEndValue,
setmissionLightDuration, cts.Token);
// ロイドカメラ有効
roydCamera.SetActive(true);
// ロイド顔ウインドウ表示
await _uiEffect.FadeIn(roydFaceWindowCanvasGroup, cts.Token);
// ロイドトークウインドウ表示
await _uiEffect.FadeIn(roydTalkWindowCanvasGroup, cts.Token);
await _missionStartTalk.Talk(roydTextMeshPro, Character.Character.Royd, "こちらロイド、宇宙海賊の戦艦付近に到着した。",
_message_speed, cts.Token);
// ソフィーカメラ有効
sophieCamera.SetActive(true);
// ソフィー顔ウインドウ表示
await _uiEffect.FadeIn(sophieFaceWindowCanvasGroup, cts.Token);
// ソフィートークウインドウ表示
await _uiEffect.FadeIn(sophieTalkWindowCanvasGroup, cts.Token);
await _missionStartTalk.Talk(sophieTextMeshPro, Character.Character.Sophie, "了解、ロイド。まずは敵戦艦付近の偵察機と思わしき数体の機体の掃討をお願い。",
_message_speed, cts.Token);
await _missionStartTalk.Talk(roydTextMeshPro, Character.Character.Royd, "了解、これより攻撃を開始する",
_message_speed, cts.Token);
HideUI();
}
catch (OperationCanceledException)
{
// キャンセルされた場合の処理
Debug.Log("ShowUI Canceled");
}
}
public async UniTask HideUI()
{
try
{
await _uiEffect.FadeOut(roydTalkWindowCanvasGroup, cts.Token);
await _uiEffect.FadeOut(sophieTalkWindowCanvasGroup, cts.Token);
await _uiEffect.FadeOut(roydFaceWindowCanvasGroup, cts.Token);
await _uiEffect.FadeOut(sophieFaceWindowCanvasGroup, cts.Token);
await _uiEffect.FadeOut(sophieFaceWindowCanvasGroup, cts.Token);
await _uiEffect.SizeDelta(missionWindowRectTransform, new Vector2(_initialUISizeDelta.x, setDeltaMinY),
setDeltaDuration, cts.Token);
await _uiEffect.FadeOut(missionWindowCanvasGroup, cts.Token);
await _uiEffect.SizeDelta(missionWindowRectTransform, new Vector2(_initialUISizeDelta.x, setDeltaMinY),
setDeltaDuration, cts.Token);
SceneManager.LoadScene(gameScene);
}
catch (OperationCanceledException)
{
// キャンセルされた場合の処理
Debug.Log("HideUI Canceled");
}
}
}
}
トーク部分
トーク部分はenumで受け渡された値で分岐するようにキャラクター毎の口の動きを制御するように設定してみました。
テキストの処理自体はDOTextで実施しています。
using System.Threading;
using _RAYSER.Scripts.Tweening;
using _RAYSER.Scripts.UI.Title;
using Cysharp.Threading.Tasks;
using TMPro;
namespace _RAYSER.Scripts.UI
{
public interface ITalk
{
TweenExecution TweenExecution { get; set; }
UniTask Talk(TextMeshProUGUI textMeshProUGUI, Character.Character character, string text, float speed,
CancellationToken cancellationToken);
}
}
using System.Threading;
using _RAYSER.Scripts.Tweening;
using Cysharp.Threading.Tasks;
using TMPro;
using UnityEngine;
using VRM;
namespace _RAYSER.Scripts.UI.Title
{
public class MissionStartTalk : MonoBehaviour, ITalk
{
TweenExecution _tweenExecution = new TweenExecution();
private IUIEffect _iuiImplementation;
[SerializeField] private MouthAnimation roydMouthAnimation;
[SerializeField] private MouthAnimation sophieMouthAnimation;
public TweenExecution TweenExecution
{
get => _iuiImplementation.TweenExecution;
set => _iuiImplementation.TweenExecution = value;
}
/// <summary>
/// enum Characterをキーにして、MouthAnimationを取得する
/// </summary>
/// <param name="character"></param>
/// <returns></returns>
private MouthAnimation GetMouthAnimation(Character.Character character)
{
switch (character)
{
case Character.Character.Royd:
return roydMouthAnimation;
case Character.Character.Sophie:
return sophieMouthAnimation;
default:
return null;
}
}
/// <summary>
/// トーク処理
/// </summary>
/// <param name="textMeshProUGUI"></param>
/// <param name="character"></param>
/// <param name="text"></param>
/// <param name="speed"></param>
/// <param name="cancellationToken"></param>
public async UniTask Talk(TextMeshProUGUI textMeshProUGUI, Scripts.Character.Character character, string text, float speed,
CancellationToken cancellationToken)
{
var mouthAnimation = GetMouthAnimation(character);
mouthAnimation.MouthAnimationStart();
await _tweenExecution.HideText(textMeshProUGUI, cancellationToken);
await _tweenExecution.ShowText(textMeshProUGUI, text, speed, cancellationToken);
mouthAnimation.MouthAnimationStop();
}
}
}
namespace _RAYSER.Scripts.Character
{
public enum Character
{
Royd,
Sophie
}
}
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using TMPro;
using UnityEngine;
namespace _RAYSER.Scripts.Tweening
{
/// <summary>
/// UIのトゥイーン処理を実行するクラス
/// </summary>
public class TweenExecution
{
private const float defalutFadoInEndValue = 1f;
private const float defalutFadoInDuration = 0.3f;
private const float defalutFadoOutEndValue = 0f;
private const float defalutFadoOutDuration = 0.3f;
/// <summary>
/// フェード実行
/// </summary>
/// <param name="canvasGroup"></param>
/// <param name="endValue"></param>
/// <param name="duration"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask Fade(
CanvasGroup canvasGroup,
float endValue,
float duration,
CancellationToken cancellationToken
)
{
return canvasGroup.DOFade(endValue, duration)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// フェードイン実行
/// </summary>
/// <param name="canvasGroup"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask FadeIn(
CanvasGroup canvasGroup,
CancellationToken cancellationToken
)
{
return canvasGroup
.DOFade(defalutFadoInEndValue, defalutFadoInDuration)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// フェードアウト実行
/// </summary>
/// <param name="canvasGroup"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask FadeOut(
CanvasGroup canvasGroup,
CancellationToken cancellationToken
)
{
return canvasGroup.DOFade(defalutFadoOutEndValue, defalutFadoOutDuration)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// サイズ変更
/// </summary>
/// <param name="rectTransform"></param>
/// <param name="endValue"></param>
/// <param name="duration"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask SizeDelta(
RectTransform rectTransform,
Vector2 endValue,
float duration,
CancellationToken cancellationToken
)
{
return rectTransform.DOSizeDelta(endValue, duration)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// X軸への移動
/// </summary>
/// <param name="rectTransform"></param>
/// <param name="endValue"></param>
/// <param name="duration"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask LocalMoveX(
RectTransform rectTransform,
float endValue,
float duration,
CancellationToken cancellationToken
)
{
return rectTransform.DOLocalMoveX(endValue, duration)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// 文字の非表示
/// </summary>
/// <param name="textMeshProUGUI"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask HideText(TextMeshProUGUI textMeshProUGUI, CancellationToken cancellationToken)
{
return textMeshProUGUI.DOText(String.Empty, 0)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
/// <summary>
/// 文字の表示
/// </summary>
/// <param name="textMeshProUGUI"></param>
/// <param name="text"></param>
/// <param name="speed"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public UniTask ShowText(TextMeshProUGUI textMeshProUGUI, string text, float speed, CancellationToken cancellationToken)
{
return textMeshProUGUI
.DOText(text, text.Length * speed)
.SetEase(Ease.Linear)
.Play()
.ToUniTask(cancellationToken: cancellationToken);
}
}
}
よかったらいいねやコメントなどいただけると嬉しいです。