Learn how create 2D Idle Clicker Game in Unity  Section2 メモ

# 概要
Udemyの映像講座「Learn how create 2D Idle Clicker Game in Unity  Section2」のメモです。
後で見返しやすくするために、クラス図、コメント等を追記します。


# 図
## gifアニメ
この動きを実装する
![UnityOutPut.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/3a30e0aa-454a-7a10-b1e9-278abee18afd.gif)


1.スペースキーを押すとShaftMinerが右に動き始めます。
2.ShaftMinerが右端到達後、一定時間採掘するモーションを取ります。
3.ShaftMinerが採掘終了後　金を入手し、金を貯めるために左端のDepositに移動します。
4.ShaftMinerがDepositまで移動し再び右端に移動します。

2と4のループ


## 状態遷移図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b6a81124-ceb4-ed1c-41ad-2bd3b1bfae46.png)

## クラス図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d54163cf-3d5f-619c-d80f-9c4a32e268bb.png)


クラス名|説明
------|----
BaseMiner|Minerについてのクラス。継承先はShaftMinerの他にElevatorMiner WarehouseMinerがある
ShaftMiner|ShaftMinerのクラス。MiningLocationで金を入手してDepositに金を貯める動きをしている。
Deposit|Depositに金を貯める機能のみ。

# 開発環境
IDE:Rider
Unity:2019.4.40
OS:Windows10
# 実装

## Unity Editor側の設定（viewの設定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0007523a-8a36-9ba3-8122-e13edd80835c.png)

オブジェクト名|説明
--------------|-----
MiningLocation|Minerが動ける右端　コンポーネントのアイコンを使っているのでゲーム画面には表示されない
DepositLocation|Minerが動ける左端　コンポーネントのアイコンを使っているのでゲーム画面には表示されない
Deposit|Depositの画像　Depositスクリプトがアタッチされている
Miner|左右に動くオブジェクト ShaftMinerスクリプトがアタッチされている。


animationの設定は今回は省きます。



## コード
実行されている処理の順番を確認したいので、Debug.Logを加えます。

### BaseMiner.cs
```cs:BaseMiner.cs
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;

public class BaseMiner : MonoBehaviour
{
    [SerializeField] protected Transform miningLocation;
    [SerializeField] protected Transform depositLocation;
    [SerializeField] protected float moveSpeed;
    [SerializeField] protected Deposit shaftDeposit;
    
    [Header("Initial Values")] 
    [SerializeField] private float initialCollectCapacity;
    [SerializeField] private float initialCollectPerSecond;

    public float CurrentGold { get; set; }
    public float CollectCapacity { get; set; }
    public float CollectPerSecond { get; set; }
    // true：次の目的地でMinerが金を入手するとき
    // false: 次の目的地でMinerがDepositに金を移すとき
    public bool IsTimeToCollect { get; set; }

    protected Animator _animator;
    
    private void Start()
    {
        Debug.Log("<color=blue>BaseMinerクラスのStartが実行されました。</color>");
        _animator = GetComponent<Animator>();
        IsTimeToCollect = true;

        CollectCapacity = initialCollectCapacity;
        CollectPerSecond = initialCollectPerSecond;
    }

    protected virtual void MoveMiner(Vector3 newPosition)
    {
        transform.DOMove(newPosition, moveSpeed).SetEase(Ease.Linear).OnComplete((() =>
        {
            if (IsTimeToCollect)
            {
                CollectGold();
            }
            else
            {
                DepositGold();
            }

        })).Play();
    }
    
    // Spaceキーを押したとき用の処理
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Vector3 xPos = new Vector3(miningLocation.position.x, transform.position.y);
            MoveMiner(xPos);
        }
    }

    protected virtual void CollectGold()
    {
        
    }
    //　継承先で使う
    protected virtual IEnumerator IECollect(float gold, float collecTime)
    {
        yield return null;
    }
    
    // 継承先で使う
    protected virtual void DepositGold()
    {
        
    }
    
    protected void ChangeGoal()
    {
        Debug.Log("<color=blue>BaseMinerクラスのChangeGoalが実行されました。</color>");
        IsTimeToCollect = !IsTimeToCollect;
    }

    // 採掘完了後 or Depositに金を置いた後に逆向きに移動するため方向転換
    protected void RotateMiner(int direction)
    {
        Debug.Log("<color=blue>BaseMinerのRotateが実行されました。</color>");
        if (direction == 1)
        {
            transform.localScale = new Vector3(1, 1, 1);
        }
        else
        {
            transform.localScale = new Vector3(-1, 1, 1);
        }
    }
}


```

### ShaftMiner.cs

```cs:ShaftMiner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShaftMiner : BaseMiner
{
    private int walkAnimation = Animator.StringToHash("Walk");
    private int miningAnimation = Animator.StringToHash("Mining");
    
    // animationの設定 
    protected override void MoveMiner(Vector3 newPosition)
    {
        Debug.Log("<color=red>ShaftMinerクラスのMoveMinerが実行されました。</color>");
        base.MoveMiner(newPosition);
        _animator.SetTrigger(walkAnimation);
    }

    // animationの設定　詳細の処理はIECollectで行う
    protected override void CollectGold()
    {
        Debug.Log("<color=red>ShaftMinerクラスのCollectGoldが実行されました。</color>");
        _animator.SetTrigger(miningAnimation);
        float collectTime = CollectCapacity / CollectPerSecond;
        StartCoroutine(IECollect(CollectCapacity, collectTime));
    }

    // 採掘完了するまで非同期処理　採掘完了後depositに移動する。
    protected override IEnumerator IECollect(float gold, float collectTime)
    {
        yield return new WaitForSeconds(collectTime);
        Debug.Log("<color=red>ShaftMinerクラスのIECollectが実行されました。</color>");
        CurrentGold = gold;
        ChangeGoal();
        RotateMiner(-1);
        Vector3 depositPos = new Vector3(depositLocation.position.x, transform.position.y);
        MoveMiner(depositPos);
    }

    // MinerがDepositに金を移し、MiningLocationに移動する処理
    protected override void DepositGold()
    {
        Debug.Log("<color=red>ShaftMinerクラスのDepositGoldが実行されました。</color>");
        shaftDeposit.DepositGold(CurrentGold);
        
        CurrentGold = 0;
        ChangeGoal();
        RotateMiner(1);
        Vector3 xPos = new Vector3(miningLocation.position.x, transform.position.y);
        MoveMiner(xPos);
    }
}


```

### Deposit.cs

```cs:Deposit.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Deposit : MonoBehaviour
{
    public float CurrentGold { get; set; }

    // Minerが持っている金をdepositに移す。
    public void DepositGold(float amount)
    {
        Debug.Log("<color=yellow>DepositクラスのDepositGoldが実行されました。</color>");
        CurrentGold += amount;
    }
}


```


# 動かして確認
depositを２往復するまでの様子を記録します。。
## gifアニメ
![Section2 GIf2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2da4a716-c413-c39f-605b-78c2d7a692b6.gif)


## コンソール画面の静止画
実行されるメソッドの順番を調べるために貼りました。
赤色のログ：ShaftMinerクラス
青色のログ：BaseMinerクラス
黄色のログ：Depositクラス
となっております。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/b029c5b2-a721-0aa6-ed1e-3dfb35bb5028.png)


# 感想
なんとなくわかった。実際に組めるかは自信無いですね。
DotTween、アニメーション部分はスルーしました。

# 参考
Section2 ShaftWoker

https://www.udemy.com/course/learn-how-to-create-a-2d-idle-clicker-game-in-unity-2021/learn/lecture/24816604#overview