-->

using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
/// <summary>
/// Coroutineを使ったアニメーション実装
/// </summary>
public class TestCoroutine : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
StartCoroutine(CommonSlideAction(rightEndPosX, rightSlideSec));
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
StartCoroutine(CommonSlideAction(leftEndPosX, leftSlideSec));
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private IEnumerator CommonSlideAction(float endPosX, float duration)
{
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//1秒待機
yield return new WaitForSeconds(1);
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for(int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//0.2秒秒待機
yield return new WaitForSeconds(flashInterval);
}
infoText.text = "やりましたね!!";
}
}
using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
/// <summary>
/// UniTaskを使ったアニメーション実装
/// </summary>
public class TestUniTask : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
//CommonSlideActionの非同期処理を実行後、このOnTapRightButton関数は何もすることが無いのでForgetで待機を破棄する。
CommonSlideAction(rightEndPosX, rightSlideSec).Forget();
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
//CommonSlideActionの非同期処理を実行後、このOnTapLeftButton関数は何もすることが無いのでForgetで待機を破棄する。
CommonSlideAction(leftEndPosX, leftSlideSec).Forget();
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private async UniTask CommonSlideAction(float endPosX, float duration)
{
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//UniTaskで1秒待機
await UniTask.WaitForSeconds(1)
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for(int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//TimeSpan.FromSecondに0.2を渡しているので0.2秒待機
await UniTask.WaitForSeconds(flashInterval);
}
infoText.text = "やりましたね!!";
}
}

using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using System.Threading.Tasks;
/// <summary>
/// Taskを使ったアニメーション実装
/// </summary>
public class TestTask : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
CommonSlideAction(rightEndPosX, rightSlideSec);
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
CommonSlideAction(leftEndPosX, leftSlideSec);
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private async Task CommonSlideAction(float endPosX, float duration)
{
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//Task.Delayは基本はミリ秒を渡す設計だが(1000ミリ秒=1秒)、TimeSpan.FromSecondを渡すことで秒数指定できる
await Task.Delay(TimeSpan.FromSeconds(1));
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for(int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//TimeSpan.FromSecondに0.2を渡しているので0.2秒待機
await Task.Delay(TimeSpan.FromSeconds(flashInterval));
}
infoText.text = "やりましたね!!";
}
}

using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
/// <summary>
/// Coroutineを使ったアニメーション実装
/// </summary>
public class TestCoroutine : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
//中断処理のための変数を追加
private Coroutine slideCoroutine;
private Tweener slideTweener;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
//実行中のコルーチンがある場合中断
if (slideCoroutine != null)
{
StopCoroutine(slideCoroutine);
slideTweener.Kill();
}
slideCoroutine = StartCoroutine(CommonSlideAction(rightEndPosX, rightSlideSec));
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
//実行中のコルーチンがある場合中断
if (slideCoroutine != null)
{
StopCoroutine(slideCoroutine);
slideTweener.Kill();
}
slideCoroutine = StartCoroutine(CommonSlideAction(leftEndPosX, leftSlideSec));
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private IEnumerator CommonSlideAction(float endPosX, float duration)
{
star.gameObject.SetActive(true);
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
//中断処理のため実行したTweenは変数に保存
slideTweener = star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//1秒待機
yield return new WaitForSeconds(1);
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for (int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//0.2秒秒待機
yield return new WaitForSeconds(flashInterval);
}
infoText.text = "やりましたね!!";
}
}
using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Threading;
/// <summary>
/// UniTaskを使ったアニメーション実装
/// </summary>
public class TestUniTask : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
//中断処理のための変数を追加
private CancellationTokenSource slideTokenSource;
private Tweener slideTweener;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
//実行中のタスクがある場合中断
if (slideTokenSource != null)
{
slideTokenSource.Cancel();
slideTweener.Kill();
}
slideTokenSource = new CancellationTokenSource();
CommonSlideAction(rightEndPosX, rightSlideSec, slideTokenSource.Token).Forget();
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
//実行中のタスクがある場合中断
if (slideTokenSource != null)
{
slideTokenSource.Cancel();
slideTweener.Kill();
}
slideTokenSource = new CancellationTokenSource();
CommonSlideAction(leftEndPosX, leftSlideSec, slideTokenSource.Token).Forget();
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private async UniTask CommonSlideAction(float endPosX, float duration, CancellationToken token)
{
//中断を実行したタイミングによっては後半の点滅で
//star.gameOjbectが消えてる可能性があるのでtrueにする
star.gameObject.SetActive(true);
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
//中断処理のため実行したTweenは変数に保存
slideTweener = star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//1秒待機
await UniTask.WaitForSeconds(1);
//タスクの中断の命令が出ていればreturn
if(token.IsCancellationRequested)
{
return;
}
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for(int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//TimeSpan.FromSecondに0.2を渡しているので0.2秒待機
await UniTask.WaitForSeconds(flashInterval);
//タスクの中断の命令が出ていればreturn
if(token.IsCancellationRequested)
{
return;
}
}
infoText.text = "やりましたね!!";
}
}
if(token.IsCancellationRequested)
{
return;
}
using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using System.Threading.Tasks;
using System.Threading;
/// <summary>
/// Taskを使ったアニメーション実装
/// </summary>
public class TestTask : MonoBehaviour
{
[SerializeField]
private Button rightButton;
[SerializeField]
private Button leftButton;
[SerializeField]
private Text infoText;
[SerializeField]
private Transform star;
private float rightSlideSec = 5f;
private float leftSlideSec = 3f;
private float rightEndPosX = 500;
private float leftEndPosX = -500;
private int flashCount = 3;
private float flashInterval = 0.2f;
//中断処理のための変数を追加
private CancellationTokenSource slideTokenSource;
private Tweener slideTweener;
private void Start()
{
//ボタンイベントをスクリプトから登録
rightButton.onClick.AddListener(OnTapRightButton);
leftButton.onClick.AddListener(OnTapLeftButton);
}
/// <summary>
/// 右のボタンを押した時の処理
/// </summary>
private void OnTapRightButton()
{
//実行中のタスクがある場合中断
if (slideTokenSource != null)
{
slideTokenSource.Cancel();
slideTweener.Kill();
}
slideTokenSource = new CancellationTokenSource();
CommonSlideAction(rightEndPosX, rightSlideSec, slideTokenSource.Token);
}
/// <summary>
/// 左のボタンを押した時の処理
/// </summary>
private void OnTapLeftButton()
{
//実行中のタスクがある場合中断
if (slideTokenSource != null)
{
slideTokenSource.Cancel();
slideTweener.Kill();
}
slideTokenSource = new CancellationTokenSource();
CommonSlideAction(leftEndPosX, leftSlideSec, slideTokenSource.Token);
}
/// <summary>
/// アニメーションの共通処理
/// </summary>
private async Task CommonSlideAction(float endPosX, float duration, CancellationToken token)
{
//中断を実行したタイミングによっては後半の点滅で
//star.gameOjbectが消えてる可能性があるのでtrueにする
star.gameObject.SetActive(true);
infoText.text = "経過時間0秒";
//星をTweenを使って移動させ、1秒置きにテキストを更新する
//中断処理のため実行したTweenは変数に保存
slideTweener = star.DOLocalMoveX(endPosX, duration).SetEase(Ease.Linear);
var remainTime = duration;
while (remainTime > 0)
{
//Task.Delayは基本はミリ秒を渡す設計だが(1000ミリ秒=1秒)、TimeSpan.FromSecondを渡すことで秒数指定できる
await Task.Delay(TimeSpan.FromSeconds(1));
//タスクの中断の命令が出ていればreturn
if(token.IsCancellationRequested)
{
return;
}
remainTime--;
infoText.text = "経過時間" + (duration - remainTime) + "秒";
}
//星が目的地に着いたら点滅させる
for(int i = 0; i < flashCount * 2; i++)
{
//偶数かどうか判定
var isEven = i % 2 == 0;
//偶数なら星を非表示、奇数なら表示
star.gameObject.SetActive(isEven ? false : true);
//TimeSpan.FromSecondに0.2を渡しているので0.2秒待機
await Task.Delay(TimeSpan.FromSeconds(flashInterval));
//タスクの中断の命令が出ていればreturn
if(token.IsCancellationRequested)
{
return;
}
}
infoText.text = "やりましたね!!";
}
}

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Linq;
public class TestUniTaskMeasure : MonoBehaviour
{
[SerializeField]
private Button startMeasureButton;
[SerializeField]
private Text keyDownStatusText;
[SerializeField]
private Transform star;
//keyDownRecordにAddする文字列を事前にreadonlyで定義
private readonly string leftString = "Left";
private readonly string rightString = "Right";
//計測終了までに必要なキーの押下回数
private readonly int needKeyDownCount = 5;
private int curKeyDownCount = 0;
//計測結果に応じて移動させる星の最終座標
private float leftEndPosX = -500;
private float rightEndPosX = 500;
//どちらのキーを押したかの記録を保存するためのList
private List<string> keyDownRecord = new List<string>();
private void Start()
{
//ボタンイベントをスクリプトから登録
startMeasureButton.onClick.AddListener(() => OnTapStartMeasure().Forget());
}
/// <summary>
/// 計測スタートのボタンを押した時の処理
/// </summary>
private async UniTask OnTapStartMeasure()
{
//ボタン表示を一時的に消す
startMeasureButton.gameObject.SetActive(false);
keyDownStatusText.text = "計測中...";
//初期化処理
keyDownRecord.Clear();
curKeyDownCount = 0;
Vector2 curPos = star.localPosition;
star.localPosition = new Vector3(0, curPos.y);
//Measure関数の終了をawaitで待機し、結果はresultに代入
string resultString = await Measure();
//結果が左ならleftEndPosXを、右ならrightEndPosをresultPosに代入
float resultPos = resultString == leftString ? leftEndPosX : rightEndPosX;
//星のx座標を移動させる
star.localPosition = new Vector3(resultPos, curPos.y);
//ボタン表示を復活させる
startMeasureButton.gameObject.SetActive(false);
keyDownStatusText.text = "計測終了! 結果 = " + resultString;
}
/// <summary>
/// キーダウンの計測を開始。右矢印、もしくは左矢印を計5回押すまで計測を続ける
/// 計測が終わったら、どちらの矢印をより多く押したかの結果を返す
/// </summary>
private async UniTask<string> Measure()
{
while(true)
{
//キーボードの左矢印を押下
if(Input.GetKeyDown(KeyCode.LeftArrow))
{
keyDownRecord.Add(leftString);
curKeyDownCount++;
keyDownStatusText.text = leftString + "のキーを押下! 押下回数" + curKeyDownCount;
}
//キーボードの右矢印を押下
if(Input.GetKeyDown(KeyCode.RightArrow))
{
keyDownRecord.Add(rightString);
curKeyDownCount++;
keyDownStatusText.text = rightString + "のキーを押下! 押下回数" + curKeyDownCount;
}
//キーの押下回数がneedKeyDownCountに達したら計測終了処理へ
if(curKeyDownCount >= needKeyDownCount)
{
//LINQでkeyDownRecord内の左矢印を押した回数と右矢印を押した回数を取得
int leftCount = keyDownRecord.Count(x => x == leftString);
int rightCount = keyDownRecord.Count(x => x == rightString);
//leftCountの方が大きければleftStringを、そうでなければrightStringを結果として返す
return leftCount > rightCount? leftString : rightString;
}
//1フレームだけ待機
await UniTask.Yield();
}
}
}
//Measure関数の終了をawaitで待機し、結果はresultに代入
string resultString = await Measure();
private async UniTask<string> Measure()
//キーの押下回数がneedKeyDownCountに達したら計測終了処理へ
if(curKeyDownCount >= needKeyDownCount)
{
//LINQでkeyDownRecord内の左矢印を押した回数と右矢印を押した回数を取得
int leftCount = keyDownRecord.Count(x => x == leftString);
int rightCount = keyDownRecord.Count(x => x == rightString);
//leftCountの方が大きければleftStringを、そうでなければrightStringを結果として返す
return leftCount > rightCount? leftString : rightString;
}