見出し画像

RAYSER 進捗(20230919)

RAYSERという3DシューティングゲームのUI周りの修正を進めていました。
まだ色々修正中ですが、UniTaskとDOTweenを組み合わせる形でゲームスタートのUIを作り直しています。

using System;
using _RAYSER.Scripts.UI;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using Rayser.CustomEditor;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using VRM;

namespace UI.Title
{
    [RequireComponent(typeof(Button))]
    public class ButtonStart : MonoBehaviour
    {
        /// <summary>
        /// 対象ボタン
        /// </summary>
        [SerializeField] private Button _button;

        /// <summary>
        /// メニューUI
        /// </summary>
        [SerializeField] private TitleMenuButtonsUI titleMenuButtonsUI;

        /// <summary>
        /// ゲームスタートUI
        /// </summary>
        [SerializeField] private MissionStartWindowUI missionStartWindowUI;

        /// <summary>
        /// マニュアルUI
        /// </summary>
        [SerializeField] private ManualWindowUI manualWindowUI;

        /// <summary>
        /// LicenseUI
        /// </summary>
        [SerializeField] private LicenseWindowUI licenseWindowUI;

        private void Reset()
        {
            _button = GetComponent<Button>();
        }

        private void Awake()
        {
            _button.OnClickAsObservable().Subscribe(
                _ => { PushButton(); }
            ).AddTo(this);
        }

        private void TalkMessageReset(TextMeshProUGUI textMeshProUGUI)
        {
            textMeshProUGUI.text = String.Empty;
        }

        public async UniTask PushButton()
        {
            //初期選択ボタンの初期化
            EventSystem.current.SetSelectedGameObject(null);
            titleMenuButtonsUI.HideUI();

            manualWindowUI.HideUI();
            licenseWindowUI.HideUI();
            missionStartWindowUI.ShowUI();      
        }
    }
}
using System;
using System.Threading;
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 MouthAnimation roydMouthAnimation;
        [SerializeField] private MouthAnimation sophieMouthAnimation;

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

                roydMouthAnimation.MouthAnimationStart();
                await _uiEffect.ShowText(roydTextMeshPro, "こちらロイド、宇宙海賊の戦艦付近に到着した。", _message_speed, cts.Token);
                roydMouthAnimation.MouthAnimationStop();

                // ソフィーカメラ有効
                sophieCamera.SetActive(true);

                // ソフィー顔ウインドウ表示
                await _uiEffect.FadeIn(sophieFaceWindowCanvasGroup, cts.Token);

                // ソフィートークウインドウ表示
                await _uiEffect.FadeIn(sophieTalkWindowCanvasGroup, cts.Token);

                sophieMouthAnimation.MouthAnimationStart();
                await _uiEffect.ShowText(sophieTextMeshPro, "了解、ロイド。まずは敵戦艦付近の偵察機と思わしき数体の機体の掃討をお願い。", _message_speed,
                    cts.Token);
                sophieMouthAnimation.MouthAnimationStop();

                roydMouthAnimation.MouthAnimationStart();
                await _uiEffect.ShowText(roydTextMeshPro, "了解、これより攻撃を開始する", _message_speed, cts.Token);
                roydMouthAnimation.MouthAnimationStop();

                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");
            }
        }
    }
}
using System.Threading;
using _RAYSER.Scripts.Tweening;
using UnityEngine;
using Cysharp.Threading.Tasks;
using TMPro;

namespace _RAYSER.Scripts.UI
{
    /// <summary>
    /// UIエフェクト管理クラス
    /// </summary>
    public class UIEffect : IUIEffect
    {
        TweenExecution _tweenExecution = new TweenExecution();
        private IUIEffect _iuiImplementation;

        public TweenExecution TweenExecution
        {
            get => _iuiImplementation.TweenExecution;
            set => _iuiImplementation.TweenExecution = value;
        }

        public void SetAlphaZero(CanvasGroup canvasGroup)
        {
            canvasGroup.alpha = 0;
        }

        public void SetSizeDeltaZero(RectTransform rectTransform)
        {
            rectTransform.sizeDelta = Vector2.zero;
        }

        public UniTask FadeIn(CanvasGroup canvasGroup, CancellationToken cancellationToken)
        {
            return _tweenExecution.FadeIn(canvasGroup, cancellationToken);
        }


        public UniTask FadeOut(CanvasGroup canvasGroup, CancellationToken cancellationToken)
        {
            return _tweenExecution.FadeOut(canvasGroup, cancellationToken);
        }

        public UniTask Fade(
            CanvasGroup canvasGroup,
            float endValue,
            float duration,
            CancellationToken cancellationToken
        )
        {
            return _tweenExecution.Fade(canvasGroup, endValue, duration, cancellationToken);
        }

        public UniTask SizeDelta(RectTransform rectTransform, Vector2 endValue, float duration,
            CancellationToken cancellationToken)
        {
            return _tweenExecution.SizeDelta(rectTransform, endValue, duration, cancellationToken);
        }

        public UniTask LocalMoveX(RectTransform rectTransform, float endValue, float duration,
            CancellationToken cancellationToken)
        {
            return _tweenExecution.LocalMoveX(rectTransform, endValue, duration, cancellationToken);
        }

        public UniTask HideText(TextMeshProUGUI textMeshProUGUI, CancellationToken cancellationToken)
        {
            return _tweenExecution.HideText(textMeshProUGUI, cancellationToken);
        }

        public UniTask ShowText(TextMeshProUGUI textMeshProUGUI, string text, float speed,
            CancellationToken cancellationToken)
        {
            return _tweenExecution.ShowText(textMeshProUGUI, text, speed, cancellationToken);
        }
    }
}
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);
        }

        public UniTask HideText(TextMeshProUGUI textMeshProUGUI, CancellationToken cancellationToken)
        {
            return textMeshProUGUI.DOText(String.Empty, 0)
                .Play()
                .ToUniTask(cancellationToken: cancellationToken);
        }

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

よかったら感想やいいねなどいただけますと非常にありがたいです。

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