日報(6月24日)

今日やったこと

ワーキングメモリーレーニン

勉強

ゲーム開発(玉転がし)

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の測定結果

f:id:alberto_hojo:20190625095945p:plain:w250

作業時間 6h20m

集中時間 2h

集中率 32%

今日は用事があったので半日オフにしました