u1w Never Give 2のスクリプト
スクリプトを全公開。
効率とかいろいろ無視しているので
まあ1週間で作るのならこれでもいいんじゃないかな。
っていうくらいの気持ちでご覧ください。
Controller.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro; //テキストメッシュプロ
public class Controller : MonoBehaviour
{
//public staticはどのスクリプトからも命令ができるのでu1wでよく使ってます(簡単だから)
//[SerializeField]すると=defaultしないと黄色いエラーみたいなの出るのでだいたい=defaultしてます
public static int motion = 0; //0 1stand 2run 3good 4ng
public static int current = 0; //現在のマス
public static bool reset = false;
private bool move_b = false; //動かすブール
private bool dice_mode = false; //サイコロがぐるんぐるんモード
private bool life_mode = false; //lifeゲット用サイコロがぐるんぐるんモード
private float speed = 0.03f; //ユニティちゃんの足の速さ
private GameObject diceroll; //diceroll用のオブジェクト
private int pt = 0; //ポイント
private bool life = false; //ライフの有無
[SerializeField] private TextMeshProUGUI pt_text = default; //ポイントテキスト
[SerializeField] private Image Heart = default; //ライフのイメージ
[SerializeField] private Animator anm = default; //アニメ
[SerializeField] private GameObject canvas = default; //キャンバス
[SerializeField] private GameObject Dice_button = default; //サイコロボタン
[SerializeField] private GameObject Rule = default; //ルール画面
[SerializeField] private GameObject OP = default; //OP画面
//prefab
[SerializeField] private GameObject ground_prefab = default; //地面のセット
private GameObject ground = default; //生成された地面
[SerializeField] private GameObject dice_prefab = default; //ぐるんぐるんサイコロ
[SerializeField] private GameObject get_prefab = default; //ptゲットテキスト
[SerializeField] private GameObject gameover_prefab = default; //ゲームオーバーテキスト
[SerializeField] private GameObject Chance_prefab = default; //チャンス画面
private GameObject Chance = default; //生成されたチャンスを入れる
void Awake()
{
allreset(); //初期化
}
private void allreset() {
StartCoroutine(delayreset()); //一瞬時間を入れないと命令順序でエラーになるのでディレイかけてます
if (Dice_button.activeInHierarchy)
{ //ダイスボタンが表示されているならばそれを非表示へ
Dice_button.SetActive(false);
}
if (Rule.activeInHierarchy)
{
Rule.SetActive(false);
}
if (!OP.activeInHierarchy)
{ //オープニング画面が表示されていないならばそれを表示へ
OP.SetActive(true);
}
motion = 1; //モーションは停止にリセット
current = 0; //今いるマスは0にリセット
pt = 0; //ポイントは0にリセット
life = false; //ライフはなしにリセット
Heart.sprite = Resources.Load<Sprite>("heart0"); //ハートの絵はグレイ表示
}
private IEnumerator delayreset() {
if (ground != null)
{ //地面のセット(地面全部)があるなら一旦削除
Destroy(ground.gameObject);
}
yield return new WaitForSeconds(0.05f);
ground = Instantiate(ground_prefab, transform.parent); //地面セットをまっさらにして生成
}
void Start()
{
}
void Update()
{
pt_text.text = pt.ToString("N0") + " pt"; //ポイント常に表示
switch (motion) {
case 1:
anm.SetTrigger("stand"); //停止アニメ
move_b = false; //動かない
motion = 0; //モーションをリセット
break;
case 2:
anm.SetTrigger("run"); //走るアニメ
move_b = true; //動く
motion = 0;
break;
case 3:
anm.SetTrigger("ng"); //ノーグッドなアニメ
move_b = false;
motion = 0;
break;
case 4:
anm.SetTrigger("good"); //やったーってアニメ
move_b = false;
motion = 0;
break;
default: break;
}
if (move_b) { //ムーブのブールがオンの時は
ground.transform.Translate(0f, 0f, -speed);
//プレイヤーじゃなくて地面が走る方向と逆側に動く(見た目はプレイヤーが走ってるように見える)
}
if (dice_mode)
{ //サイコロを振るモードは2を出してはいけない
if (Input.GetMouseButtonDown(0))
{ //この時はどこをクリックしても反応
StartCoroutine(dice_delay(diceshuffle(), diceroll,true)); //ディレイが必要なのでコルーチン
//diceshuffleで1〜6のランダムな数字を取得、dicerollはオブジェ、trueは2を出さざるべきか2を出すべきか
dice_mode = false;
}
}
if (life_mode)
{ //ライフゲットの時は2を出すとライフゲット
if (Input.GetMouseButtonDown(0))
{
StartCoroutine(dice_delay(diceshuffle(), diceroll,false));
life_mode = false;
}
}
if (reset) { //別のスクリプトからもリセットを受けたらリセットできるように
reset = false;
allreset();
}
}
public void Button_Start()
{ //オープニングのスタートボタン
Sound_man.se = "click";
if (!Dice_button.activeInHierarchy)
{ //サイコロボタンをだして
Dice_button.SetActive(true);
}
if (OP.activeInHierarchy)
{ //オープニング画面を非表示
OP.SetActive(false);
}
}
public void Button_Rule()
{ //ルール確認画面
Sound_man.se = "click";
if (!Rule.activeInHierarchy)
{ //ルール画面を表示
Rule.SetActive(true);
}
}
public void Button_RuleClose()
{ //ルール画面を非表示
Sound_man.se = "click";
if (Rule.activeInHierarchy)
{
Rule.SetActive(false);
}
}
public void Button_Rank()
{ //ランク画面
Sound_man.se = "click";
if (Dice_button.activeInHierarchy)
{ //ダイスボタンを非表示
Dice_button.SetActive(false);
}
if (OP.activeInHierarchy)
{ //オープニング画面を非表示
OP.SetActive(false);
}
naichilab.RankingLoader.Instance.SendScoreAndShowRanking(pt);
//ないちさんのランキングを出すスクリプト(ポイントはなければゼロが入るので更新されない、入ってれば更新)
}
public void Button_Dice()
{ //サイコロを振るボタン
diceroll = Instantiate(dice_prefab, canvas.transform); //サイコロぐるんぐるんのプレファブ
dice_mode = true; //このモードに入るとどこをクリックしてもサイコロを振れるようになる
Dice_button.SetActive(false); //ぐるんぐるんしていないボタン型のサイコロは非表示
}
private IEnumerator dice_delay(int n, GameObject d,bool l)
{ //サイコロの動き
d.GetComponent<Animator>().SetTrigger("roll"); //サイコロのアニメをオン
d.GetComponent<Dice_stop>().num = n; //1〜6のランダムな数字を入れる
yield return new WaitForSeconds(0.2f);
Sound_man.se = "dice";
yield return new WaitForSeconds(1.3f);
if (l)
{ //通常モード
if (n == 2)
{ //もし2がでたら
if (life)
{ //セカンドライフがあった場合
Heart.sprite = Resources.Load<Sprite>("heart0"); //ライフのイメージをグレイに
life = false; //ライフを消費
Sound_man.se = "lifeuse"; //まーだだよ(まだ生きてるぜ)
yield return new WaitForSeconds(0.5f); //ちょっちディレイ
Dice_button.SetActive(true); //サイコロの画面に戻る
goto end;
}
else
{ //ライフがない場合
gameover(); //ゲームオーバー
goto end;
}
}
else
{ //もし2以外の数字が出たら
current += n; //今いるマスにそのサイコロの数値を足す
}
motion = 2; //走る
switch (n)
{ //走る速度を秒数分ディレイ(これ別のやり方の方がいいと思います)
case 1:
case 2:
yield return new WaitForSeconds(0.4f);
break;
case 3:
yield return new WaitForSeconds(1.2f);
break;
case 4:
yield return new WaitForSeconds(1.6f);
break;
case 5:
yield return new WaitForSeconds(2.0f);
break;
case 6:
yield return new WaitForSeconds(2.4f);
break;
}
if (current % 5 == 0)
{ //5の倍数のマスに止まったら
Sound_man.se = "chance";
chance_set(); //チャンスのセットを表示
}
else
{ //それ以外
GameObject get_obj = Instantiate(get_prefab, canvas.transform); //ポイントゲットテキスト表示
Sound_man.se = "ptget";
get_obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = "+ " + numcheck(current) + " pt"; //*いくらかot
pt += numcheck(current); //ポイントを加算
yield return new WaitForSeconds(0.5f);
Dice_button.SetActive(true); //サイコロモードに戻る
}
end:
Destroy(d.gameObject); //ぐるんぐるんサイコロは消える
}
else { //セカンドライフチャレンジの場合は2が出たらライフゲット
if (n == 2)
{ //もし2なら
Sound_man.se = "lifeget";
GameObject get_obj = Instantiate(get_prefab, canvas.transform); //ポイントゲットの要領でテキストが出てくる
get_obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = "2nd LIFE GET"; //テキストはライフゲットの文字
Heart.sprite = Resources.Load<Sprite>("heart1"); //ハートの絵がピンクに染まる
life = true; //ライフあり状態にする
}
else { //2以外なら
Sound_man.se = "lifeno"; //「そんな〜」
GameObject get_obj = Instantiate(get_prefab, canvas.transform);
get_obj.transform.GetChild(0).GetComponent<TextMeshProUGUI>().text = "BAD LUCK";
}
Destroy(Chance.gameObject); //チャンスセットは消える
yield return new WaitForSeconds(0.5f);
Dice_button.SetActive(true); //サイコロボタンがまた出てくる
Destroy(d.gameObject); //ぐるんぐるんサイコロは消える
}
}
private void chance_set() { //チャンスの画面とサイコロぐるん。モード切り替えで2が出たらゲットになっている
Chance = Instantiate(Chance_prefab, canvas.transform);
diceroll = Instantiate(dice_prefab, canvas.transform);
life_mode = true;
}
private int diceshuffle() { //乱数を計算するだけ
int r_num;
r_num = Random.Range(1, 7);
return r_num;
}
private void gameover() {
Sound_man.se = "gameover";
motion = 3; //ひざまづく
Instantiate(gameover_prefab, canvas.transform);
}
private int numcheck(int gnum)
{ //ポイントの計算
int num = 1;
if (gnum >= 7 && gnum <= 12)
{
num = 2;
}
else if (gnum >= 13 && gnum <= 18)
{
num = 3;
}
else if (gnum >= 19 && gnum <= 24)
{
num = 4;
}
else if (gnum >= 25 && gnum <= 30)
{
num = 5;
}
else if (gnum >= 31 && gnum <= 36)
{
num = 6;
}
else if (gnum >= 37 && gnum <= 48)
{
num = 7;
}
else if (gnum >= 49 && gnum <= 60)
{
num = 8;
}
else if (gnum >= 61 && gnum <= 72)
{
num = 9;
}
else if (gnum >= 73 && gnum <= 84)
{
num = 10;
}
else if (gnum >= 85)
{
num = 20;
}
return gnum * num;
}
}
Dice_stop.cs
using UnityEngine;
using UnityEngine.UI;
public class Dice_stop : MonoBehaviour
{ //ぐるんぐるんサイコロの止まった時の命令を入れるスクリプト
public int num;
private Image img;
private Animator anm;
private void Awake()
{
img = GetComponent<Image>();
anm = GetComponent<Animator>();
}
public void dice_stop() {
switch (num) { //数値に合わせてイメージを変える
case 1:
img.sprite = Resources.Load<Sprite>("dicea1");
break;
case 2:
img.sprite = Resources.Load<Sprite>("dicea2");
break;
case 3:
img.sprite = Resources.Load<Sprite>("dicea3");
break;
case 4:
img.sprite = Resources.Load<Sprite>("dicea4");
break;
case 5:
img.sprite = Resources.Load<Sprite>("dicea5");
break;
case 6:
img.sprite = Resources.Load<Sprite>("dicea6");
break;
}
anm.enabled = false; //アニメを止める
}
}
Pop_con.cs
using System.Collections;
using UnityEngine;
using TMPro;
public class Pop_con : MonoBehaviour
{ //ポップ(画面中央に出てくるテキスト)の命令
[SerializeField]
private bool over = false; //インスペクタでゲームオーバーのオブジェかポイントゲットのオブジェかをブールで判断
private void Start()
{
if (over)
{
StartCoroutine(gameover());
}
else {
StartCoroutine(get());
}
}
private IEnumerator gameover()
{ //ゲームオーバーのテキスト
transform.GetComponent<TextMeshProUGUI>().color = new Color(1f, 0f, 0f, 0f); //透明
for (var c = 0f; transform.GetComponent<TextMeshProUGUI>().color.a < 1f; c += Time.deltaTime * 1f)
{ //繰り返す
transform.GetComponent<TextMeshProUGUI>().color = new Color(1f, 0f, 0f, c); //徐々に現れる
yield return null;
}
transform.GetComponent<TextMeshProUGUI>().color = new Color(1f, 0f, 0f, 1f); //表示=透過率0
yield return new WaitForSeconds(3f); //待機
for (var c = 1f; transform.GetComponent<TextMeshProUGUI>().color.a > 0f; c -= Time.deltaTime * 1f)
{ //繰り返す
transform.GetComponent<TextMeshProUGUI>().color = new Color(1f, 0f, 0f, c); //徐々に消える
yield return null;
}
transform.GetComponent<TextMeshProUGUI>().color = new Color(1f, 0f, 0f, 0f); //透明
GameObject con = GameObject.Find("EventSystem"); //Contollerスクリプトの入っているオブジェを検索
con.GetComponent<Controller>().Button_Rank(); //その中のランキング表示命令を発動
Destroy(gameObject); //ゲームオーバーのオブジェごと削除
}
private IEnumerator get()
{ //ポイントゲットのテキスト
transform.localPosition = new Vector3(800f,0f,0f); //だいぶ右に発生
for (var x = 800f; transform.localPosition.x > 0f; x -= Time.deltaTime * 1600f)
{ //繰り返す
transform.localPosition = new Vector3(x, 0f, 0f); //中央まで一気に移動
yield return null;
}
transform.localPosition = new Vector3(0f, 0f, 0f); //ピタッと中央に停止
yield return new WaitForSeconds(1.5f); //待機
for (var x = 0f; transform.localPosition.x > -900f; x -= Time.deltaTime * 1600f)
{ //繰り返す
transform.localPosition = new Vector3(x, 0f, 0f); //だいぶ左まで移動
yield return null;
}
transform.localPosition = new Vector3(-800f, 0f, 0f); //ピタッと停止
Destroy(gameObject); //ポイントゲットのオブジェごと削除
}
}
Ground_con.cs
using UnityEngine;
using TMPro;
public class Ground_con : MonoBehaviour
{ //地面の親分につけるスクリプト
public int g_current = 0; //この地面の番号
[SerializeField]
private GameObject g_prefab = default; //地面プレファブをインスペクタで収納
private void OnTriggerEnter(Collider other)
{ //触れたら発動命令
if (other.gameObject.tag == "Player" && g_current == Controller.current)
{ //地面がプレイヤーに触れている & この地面の番号がプレイヤーのいる地面番号と一致している
Controller.motion = 1; //プレイヤーは停止モーションへ
}
if (other.gameObject.tag == "Destroy")
{ //画面外に出たら(画面外にDestroyというコライダーオブジェを置いてある)
GameObject new_g = Instantiate(g_prefab,transform.parent.parent); //新しい地面一列
GameObject new_gcon = new_g.transform.GetChild(0).gameObject; //スクリプトが入っているオブジェ
int newg_current = g_current + 12; //この地面の12マス億の場所
new_gcon.GetComponent<Ground_con>().g_current = newg_current; //新しくできた地面の番号を振る
new_g.transform.localPosition = new Vector3(0f, 0f, newg_current); //新しくできた地面をだいぶ奥に設置
if (newg_current % 5 == 0)
{ //マス目が5の倍数の場合チャンスマス(黄色マス)
new_gcon.transform.GetChild(0).GetComponent<TextMeshPro>().text = "CHANCE";
new_gcon.GetComponent<Renderer>().material = Resources.Load<Material>("Material_y");
}
else if (newg_current % 2 == 0)
{ //マス目が2の倍数の場合グレイマス(見やすいように)
new_gcon.transform.GetChild(0).GetComponent<TextMeshPro>().text = numcheck(newg_current).ToString("N0"); //ポイントの数値はnucheckで計算
new_gcon.GetComponent<Renderer>().material = Resources.Load<Material>("Material_g");
}
else if (newg_current % 2 == 1)
{ //マス目が2の倍数の場合白マス(見やすいように)
new_gcon.transform.GetChild(0).GetComponent<TextMeshPro>().text = numcheck(newg_current).ToString("N0");
new_gcon.GetComponent<Renderer>().material = Resources.Load<Material>("Material_w");
}
Destroy(transform.parent.gameObject); //新しい地面の設定ができたら古い地面一列は削除
}
}
private int numcheck(int gnum) { //新しいマスのポイントを計算
int num = 1;
if (gnum >= 7 && gnum <= 12) {
num = 2;
}
else if (gnum >= 13 && gnum <= 18)
{
num = 3;
}
else if (gnum >= 19 && gnum <= 24)
{
num = 4;
} else if (gnum >= 25 && gnum <= 30)
{
num = 5;
} else if (gnum >= 31 && gnum <= 36)
{
num = 6;
} else if (gnum >= 37 && gnum <= 48)
{
num = 7;
} else if (gnum >= 49 && gnum <= 60)
{
num = 8;
} else if (gnum >= 61 && gnum <= 72)
{
num = 9;
} else if (gnum >= 73 && gnum <= 84)
{
num = 10;
} else if (gnum >= 85)
{
num = 20;
}
return gnum * num;
}
}
Sound_man.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //Toggleで必要
public class Sound_man : MonoBehaviour
{ //音専用スクリプト
private AudioSource bgm_as; //bgmプレイヤーの場所
private AudioSource se_as; //seプレイヤーの場所
public static string se; //音を鳴らす受け皿(どのスクリプトからでも命令可能)
[SerializeField]
private Toggle tog = default; //音オンオフのトグルの場所
private List<msta> musics = new List<msta>(); //いろいろやった結果、Listに情報をまとめることにしました
[SerializeField]
private AudioClip se_0 = default; //SE
[SerializeField]
private AudioClip se_1 = default;
[SerializeField]
private AudioClip se_2 = default;
[SerializeField]
private AudioClip se_3 = default;
[SerializeField]
private AudioClip se_4 = default;
[SerializeField]
private AudioClip se_5 = default;
[SerializeField]
private AudioClip se_6 = default;
[SerializeField]
private AudioClip se_7 = default;
void Awake()
{
musics.Add(new msta("dice", se_0)); //se 他のスクリプトからでもSound_man.se = "dice"で呼べる
musics.Add(new msta("ptget", se_1));
musics.Add(new msta("gameover", se_2));
musics.Add(new msta("chance", se_3));
musics.Add(new msta("lifeget", se_4));
musics.Add(new msta("lifeno", se_5));
musics.Add(new msta("click", se_6));
musics.Add(new msta("lifeuse", se_7));
AudioSource[] audiosources = GetComponents<AudioSource>(); //プレイヤーを二つ作る
bgm_as = audiosources[0]; //0番はbgmのプレイヤー
se_as = audiosources[1]; //1番はseのプレイヤー
bgm_as.enabled = false; //一旦音をオフ
se_as.enabled = false;
}
void Start()
{
StartCoroutine(opbgm()); //最初に音が出ちゃうのを防止するため一瞬待機してからオーディオをオン
}
private IEnumerator opbgm()
{ //その格納された場所
yield return new WaitForSeconds(0.05f);
bgm_as.enabled = true; //ディレイをかけてオンにすることで暴発を防ぐ
se_as.enabled = true;
}
void Update()
{
if (bgm_as.enabled)
{
if (bgm_as.clip == !bgm_as.isPlaying)
{ //もしbgmが終わってもまたプレイ(ループ再生)
bgm_as.Play();
}
}
if (se != null)
{ //外からse命令を受けたら
foreach (var ms in musics)
{ //listに入れたデータを全部参照
if (ms.mname == se)
{ //一致するものを見つけ
if (se_as.enabled)
{ //seオフ時に命令を受けてオン状態に変えるとその瞬間暴発するのでそれを阻止
se_as.PlayOneShot(ms.mclip); //1度だけseを鳴らす
}
se = null; //se命令を初期化
}
}
}
if (tog != null)
{ //音オンオフのトグルを使うなら
if (tog.isOn)
{
bgm_as.enabled = true;
se_as.enabled = true;
}
else
{
bgm_as.enabled = false;
se_as.enabled = false;
}
}
}
}
public class msta
{ //list情報のフォーマットを設定
public string mname;
public AudioClip mclip;
public msta(string m_name, AudioClip m_clip)
{
mname = m_name;
mclip = m_clip;
}
}
あとは[SerializeField]になってるのは
インスペクタでペタって貼っちゃえばOK。
アニメはトリガーでアニメ遷移を作ってあげれば。
ボタン系は普通にUIボタンのとこで適したものを選ぶ。
作ろうと思ったものをイメージして
それを形にするにはどうプログラムして
それを1週間以内で完成させるには
どのタイミングでどれができてなければいけなくて。
この辺だけ考えて完成させてます。
今の私は中級者なのだろうか初心者の上くらいなのだろうか。
まるでわからずゲームを作ってます。
ではまた。
この記事が気に入ったらサポートをしてみませんか?