坊主アプリの作成が完了しました。
次の作成に入る前に理解を深めるためコードの見直しを入れます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class GameManager : MonoBehaviour
{
private const int MAX_ORB = 30;
private const int RESPAWN_TIME = 2;
private const int MAX_LEVEL = 2;
private const string KEY_SCORE = "SCORE";
private const string KEY_LEVEL = "LEVEL";
private const string KEY_ORB = "ORB";
private const string KEY_TIME = "TIME";
public GameObject orbPrefab;
public GameObject smokePrefab;
public GameObject kusudamaPrefab;
public GameObject canvasGame;
public GameObject textScore;
public GameObject imageTemple;
public GameObject imageMokugyo;
private int score = 0;
private int nextScore = 10;
private int currentOrb = 0;
private int templeLevel = 0;
private DateTime lastDateTime;
private int[] nextScoreTable = new int[] { 10, 100, 1000 };
private AudioSource audioSource;
private int numOfOrb;
// Start is called before the first frame update
void Start()
{
audioSource = this.gameObject.GetComponent<AudioSource>();
PlayerPrefs.DeleteAll();
score = PlayerPrefs.GetInt(KEY_SCORE, 0);
templeLevel = PlayerPrefs.GetInt(KEY_LEVEL,0);
nextScore = nextScoreTable[templeLevel];
imageTemple.GetComponent<TempleManager>().SetTemplePicture(templeLevel);
imageTemple.GetComponent<TempleManager>().SetTempleScale(score, nextScore);
RefreshScoreText();
}
// Update is called once per frame
void Update()
{
while (numOfOrb > 0)
{
Invoke("CreateNewOrb", 0.1f * numOfOrb);
numOfOrb--;
}
}
void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
}
else
{
string time = PlayerPrefs.GetString(KEY_TIME, "");
if (time == "")
{
lastDateTime = DateTime.UtcNow;
}
else
{
long temp = Convert.ToInt64(time);
lastDateTime = DateTime.FromBinary(temp);
}
numOfOrb = 0;
TimeSpan timeSpan = DateTime.UtcNow - lastDateTime;
if (timeSpan >= TimeSpan.FromSeconds(RESPAWN_TIME))
{
while (timeSpan > TimeSpan.FromSeconds(RESPAWN_TIME))
{
if(numOfOrb < MAX_ORB)
{
numOfOrb++;
}
timeSpan -= TimeSpan.FromSeconds(RESPAWN_TIME);
}
}
}
}
public void CreateNewOrb()
{
lastDateTime = DateTime.UtcNow;
if(currentOrb >= MAX_ORB)
{
return;
}
CreateOrb();
currentOrb++;
SaveGameData();
}
public void CreateOrb()
{
GameObject orb = (GameObject)Instantiate(orbPrefab);
orb.transform.SetParent(canvasGame.transform, false);
orb.transform.localPosition = new Vector3(UnityEngine.Random.Range(-100.0f, 100.0f), UnityEngine.Random.Range(-300.0f, -450.0f));
int kind = UnityEngine.Random.Range(0, templeLevel + 1);
switch (kind)
{
case 0:
orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.BLUE);
break;
case 1:
orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.GREEN);
break;
case 2:
orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.PURPLE);
break;
}
orb.GetComponent<OrbManager>().FlyOrb();
AnimatorStateInfo stateInfo =
imageMokugyo.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);
if(stateInfo.fullPathHash == Animator.StringToHash("Base Layer.get@ImageMokugyo"))
{
imageMokugyo.GetComponent<Animator>().Play(stateInfo.fullPathHash, 0, 0.0f);
}
else
{
imageMokugyo.GetComponent<Animator>().SetTrigger("isGetScore");
}
}
public void GetOrb(int getScore)
{
AnimatorStateInfo stateInfo = imageMokugyo.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0);
if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.get@ImageMokugyo"))
{
imageMokugyo.GetComponent<Animator>().Play(stateInfo.fullPathHash, 0, 0.0f);
}
else
{
imageMokugyo.GetComponent<Animator>().SetTrigger("isGetScore");
}
if (score < nextScore)
{
score += getScore;
if (score > nextScore)
{
score = nextScore;
}
TempleLevelUp();
RefreshScoreText();
imageTemple.GetComponent<TempleManager>().SetTempleScale(score, nextScore);
if ((score == nextScore) && (templeLevel == MAX_LEVEL))
{
ClearEffect();
}
}
currentOrb--;
SaveGameData();
}
void RefreshScoreText()
{
textScore.GetComponent<Text>().text = "徳:" + score + "/" + nextScore;
}
void TempleLevelUp()
{
if(score >= nextScore)
{
if(templeLevel < MAX_LEVEL)
{
templeLevel++;
score = 0;
TempleLevelUpEffect();
nextScore = nextScoreTable[templeLevel];
imageTemple.GetComponent<TempleManager>().SetTemplePicture(templeLevel);
}
}
}
void TempleLevelUpEffect()
{
GameObject smoke = (GameObject)Instantiate(smokePrefab);
smoke.transform.SetParent(canvasGame.transform, false);
smoke.transform.SetSiblingIndex(2);
Destroy(smoke, 0.5f);
}
void ClearEffect()
{
GameObject kusudama = (GameObject)Instantiate(kusudamaPrefab);
kusudama.transform.SetParent(canvasGame.transform, false);
}
void SaveGameData()
{
PlayerPrefs.SetInt(KEY_SCORE, score);
PlayerPrefs.SetInt(KEY_LEVEL, templeLevel);
PlayerPrefs.SetInt(KEY_ORB, currentOrb);
PlayerPrefs.SetString(KEY_TIME, lastDateTime.ToBinary().ToString());
PlayerPrefs.Save();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class OrbManager : MonoBehaviour
{
private GameObject gameManager;
public Sprite[] orbPicture = new Sprite[3];
public enum ORB_KIND
{
BLUE,
GREEN,
PURPLE,
}
private ORB_KIND orbKind;
// Start is called before the first frame update
void Start()
{
gameManager = GameObject.Find("GameManager");
}
// Update is called once per frame
void Update()
{
}
public void FlyOrb()
{
RectTransform rect = GetComponent<RectTransform>();
Vector3[] path = {
new Vector3(rect.localPosition.x * 4.0f, 300f, 0f),
new Vector3(0f, 250f, 0f),
};
rect.DOLocalPath(path, 0.5f, PathType.CatmullRom)
.SetEase(Ease.OutQuad)
.OnComplete(AddOrbPoint);
rect.DOScale(
new Vector3(0.5f, 0.5f, 0f),
0.5f
);
}
void AddOrbPoint()
{
switch (orbKind)
{
case ORB_KIND.BLUE:
gameManager.GetComponent<GameManager>().GetOrb(5);
break;
case ORB_KIND.GREEN:
gameManager.GetComponent<GameManager>().GetOrb(50);
break;
case ORB_KIND.PURPLE:
gameManager.GetComponent<GameManager>().GetOrb(500);
break;
}
Destroy(this.gameObject);
}
public void SetKind (ORB_KIND kind)
{
orbKind = kind;
switch (orbKind)
{
case ORB_KIND.BLUE:
GetComponent<Image>().sprite = orbPicture[0];
break;
case ORB_KIND.GREEN:
GetComponent<Image>().sprite = orbPicture[1];
break;
case ORB_KIND.PURPLE:
GetComponent<Image>().sprite = orbPicture[2];
break;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MokugyoManager : MonoBehaviour
{
public GameObject gameManager;
void Start()
{
}
void Update()
{
}
public void TapMokugyo()
{
gameManager.GetComponent<GameManager>().CreateNewOrb();
}
}
//tips
//Canvasの作成:ボタンなどの部品を配置する土台。子オブジェクトを一度に移動・サイズ変更など制御できる。
画面内に収まる2Dゲームで使われそうだがzepetoなどのSNSのTOPページもこれが活かせそう。
・UI/Canvas
・作成直後のcanvasは表示範囲がmain cameraの写すゲーム画面と整合性が取れていないのでインスペクターのRenderMode-ScreenSpace-cameraを選択し、render cameraにmaincameraを入れ、カメラの範囲と同期させる。
さらに、canvasscalerコンポーネントでキャンバス上のパーツサイズをscale with screen sizeとし、解像度をデバイスのサイズreference resolutionに設定する。
・canvasの子オブジェクトの画像サイズはset native sizeで元画像のサイズに合わせて表示される
※renderとは
レンダリングとは、何らかの抽象的なデータ集合を元に、一定の処理や演算を行って画像や映像、音声などを生成すること。
http://e-words.jp/w/%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0.html
//recttransform
UIパーツはtransformコンポーネントの代わりにrecttransformを持っている。
違いは、recttransformではアンカーによって位置やサイズを自動調整でき、親オブジェクトとの相対位置を表す点。
Anchorsにあるpivotはオブジェクトの基準点(操作点)を表し、基本的には中央値だが、オブジェクトのサイズを変化させるときに下辺、または上辺などに寄せて、オブジェクトの成長方向を固定できる。
rectは英語のrectangle 長方形からきているのか。直感的に意味はわからない。
//raycasttarget
Imageコンポーネントのraycastはタッチ判定の対象になるか、透明になるかを表し、ボタンにはつけ、その他のタッチ判定を与えたくないものにはオフにしておく。
オフにしないと、判定を吸い取り、タッチ判定を与えたいオブジェクトに判定がいかないことがある。