見出し画像

RAYSER 進捗(20230920)

トーク部分のクラス化

RAYSERのシーンスタート時のトーク部分をクラス化して、一行で呼び出せるようにしてみました。


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);
        }
    }
}

よかったらいいねやコメントなどいただけると嬉しいです。

この記事が気に入ったらサポートをしてみませんか?