今日やったこと
ワーキングメモリートレーニング
瞑想
勉強
ゲーム開発(玉転がし)
PlayerPresenterの作成
主な役割は以下の2つ
PlayerViewの関数、プロパティにアクセスできるように関数、プロパティを持つ
PlayerViewインスタンスの生成
using UnityEngine; using Zenject; using UniRx; using Domain.UseCase; namespace Presentation.Presenter { public class PlayerPresenter : IPlayerPresenter{ private IPlayerView playerView; public Transform Tr => playerView.Tr; public IReadOnlyReactiveProperty<Transform> TransformProperty => playerView.TransformProperty; [Inject] IFactory<IPlayerView> playerViewFactory; public IPlayerView CreatePlayer(){ playerView = playerViewFactory.Create(); return playerView; } public void UpdatePlayerPosition(Vector3 pos){ playerView.UpdatePosition(pos); } public void DestroyPlayer() { playerView.DestroyPlayer(); } } }
PlayerUseCaseが継承しているIPlayerUseCaseというインターフェースも作成。
using UnityEngine; using UniRx; using Presentation.Presenter; namespace Domain.UseCase { public interface IPlayerPresenter { Transform Tr { get; } IReadOnlyReactiveProperty<Transform> TransformProperty { get; } IPlayerView CreatePlayer(); void UpdatePlayerPosition(Vector3 pos); void DestroyPlayer(); } }
CreatePlayerUseCaseの作成
Playerを生成する処理を行う。
using UnityEngine; using Zenject; using UniRx; namespace Domain.UseCase { public class CreatePlayerUseCase : IInitializable, ICreatePlayerUseCase { [Inject] IPlayerPresenter playerPresenter; void IInitializable.Initialize() { // 開始時にPlayerを生成 playerPresenter.CreatePlayer(); } } public interface ICreatePlayerUseCase { } }
DestroyPlayerUseCaseの作成
Playerが場外に落ちた時にPlayerを消去して、また生成し直すという処理を持つ。
using System.Collections; using System.Collections.Generic; using UnityEngine; using Zenject; using UniRx; namespace Domain.UseCase { public class DestroyPlayerUseCase : IDestroyPlayerUseCase, IInitializable { [Inject] IPlayerPresenter playerPresenter; void IInitializable.Initialize() { playerPresenter .TransformProperty .Where(x => x.position.y < -1) .Subscribe(_ => ReInitializePlayer()); } public void ReInitializePlayer() { playerPresenter.DestroyPlayer(); playerPresenter.CreatePlayer(); } } public interface IDestroyPlayerUseCase { } }
PlayerPresenterTestの作成
PlayerPresenterに対するテスト
using System.Collections; using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using Zenject; using Presentation.View; using Presentation.Presenter; using Domain.UseCase; namespace Tests { public class PlayerPresenterTest : ZenjectIntegrationTestFixture { [SetUp] public void SetUp() { PreInstall(); GameObject playerPrefab = new GameObject(); playerPrefab.AddComponent<PlayerView>(); Container .BindIFactory<IPlayerView>() .To<PlayerView>() .FromComponentInNewPrefab(playerPrefab) .WithGameObjectName("Player"); Container .Bind<IPlayerView>() .To<PlayerView>() .AsTransient(); Container .Bind<IPlayerPresenter>() .To<PlayerPresenter>() .AsCached(); PostInstall(); } // A Test behaves as an ordinary method [UnityTest] public IEnumerator PlayerPresenterTestSimplePasses() { var playerPresenter = Container.Resolve<IPlayerPresenter>(); Assert.IsNotNull(playerPresenter); yield return null; var playerView = playerPresenter.CreatePlayer(); Assert.IsNotNull(playerView); Assert.AreEqual(new Vector3(0, 1, 0), playerPresenter.Tr.position); Assert.AreEqual(new Vector3(0, 1, 0), playerView.Tr.position); yield return null; playerPresenter.UpdatePlayerPosition(new Vector3(1, 1, 0)); Assert.AreEqual(new Vector3(1, 1, 0), playerPresenter.Tr.position); Assert.AreEqual(new Vector3(1, 1, 0), playerView.Tr.position); yield return null; playerPresenter.UpdatePlayerPosition(new Vector3(2, 1, 2)); Assert.AreEqual(new Vector3(2, 1, 2), playerPresenter.Tr.position); playerPresenter.DestroyPlayer(); yield return null; var playerObject = GameObject.Find("Player"); Assert.IsNull(playerObject); playerPresenter.CreatePlayer(); playerObject = GameObject.Find("Player"); Assert.IsNotNull(playerObject); } } }
ViewとPresenterは一緒にテストしてしまってよいのではないかと感じた。
CreatePlayerUseCaseTestの作成
CreatePlayerUseCaseに対するテスト。
using System.Collections; using System.Collections.Generic; using NUnit.Framework; using UnityEngine; using UnityEngine.TestTools; using Zenject; using Domain.UseCase; using Presentation.View; using Presentation.Presenter; namespace Tests { public class CreatePlayerUseCaseTest : ZenjectIntegrationTestFixture { private string player = "Player"; [SetUp] public void SetUp() { PreInstall(); Container .BindIFactory<IPlayerView>() .To<PlayerView>() .FromNewComponentOnNewGameObject() .WithGameObjectName(player); Container .Bind<IPlayerView>() .To<PlayerView>() .AsTransient(); Container .Bind<IPlayerPresenter>() .To<PlayerPresenter>() .AsCached(); Container .BindInterfacesAndSelfTo<CreatePlayerUseCase>() .AsCached(); PostInstall(); } // A Test behaves as an ordinary method [Test] public void CreatePlayerUseCaseSimplePasses() { // Use the Assert class to test conditions var createPlayerUseCase = Container.Resolve<CreatePlayerUseCase>(); Assert.IsNotNull(createPlayerUseCase); var playerObject = GameObject.Find(player); Assert.IsNotNull(playerObject); Assert.AreEqual(new Vector3(0, 1, 0), playerObject.transform.position); } } }
JINS MEME ESの測定結果
作業時間 6h20m
集中時間 2h
集中率 32%
今日は用事があったので半日オフにしました