概要
Udemyの映像講座「Learn how create 2D Idle Clicker Game in Unity Section2」のメモです。
後で見返しやすくするために、クラス図、コメント等を追記します。
図
gifアニメ
1.スペースキーを押すとShaftMinerが右に動き始めます。
2.ShaftMinerが右端到達後、一定時間採掘するモーションを取ります。
3.ShaftMinerが採掘終了後 金を入手し、金を貯めるために左端のDepositに移動します。
4.ShaftMinerがDepositまで移動し再び右端に移動します。
2と4のループ
状態遷移図
クラス図
クラス名 | 説明 |
---|---|
BaseMiner | Minerについてのクラス。継承先はShaftMinerの他にElevatorMiner WarehouseMinerがある |
ShaftMiner | ShaftMinerのクラス。MiningLocationで金を入手してDepositに金を貯める動きをしている。 |
Deposit | Depositに金を貯める機能のみ。 |
開発環境
IDE:Rider
Unity:2019.4.40
OS:Windows10
実装
Unity Editor側の設定(viewの設定)
オブジェクト名 | 説明 |
---|---|
MiningLocation | Minerが動ける右端 コンポーネントのアイコンを使っているのでゲーム画面には表示されない |
DepositLocation | Minerが動ける左端 コンポーネントのアイコンを使っているのでゲーム画面には表示されない |
Deposit | Depositの画像 Depositスクリプトがアタッチされている |
Miner | 左右に動くオブジェクト ShaftMinerスクリプトがアタッチされている。 |
animationの設定は今回は省きます。
コード
実行されている処理の順番を確認したいので、Debug.Logを加えます。
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
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
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を2往復するまでの様子を記録します。。
gifアニメ
コンソール画面の静止画
実行されるメソッドの順番を調べるために貼りました。
赤色のログ:ShaftMinerクラス
青色のログ:BaseMinerクラス
黄色のログ:Depositクラス
となっております。
感想
なんとなくわかった。実際に組めるかは自信無いですね。
DotTween、アニメーション部分はスルーしました。
参考
Section2 ShaftWoker