質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

3135閲覧

【Unity&C#】アイテムショップの実装

k2zu1112

総合スコア18

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

0クリップ

投稿2019/01/05 13:54

編集2019/01/06 05:10

前提・実現したいこと

現在、サッカーをモチーフにしたクリッカーゲームを作っている者です。
クリックによるスコアの上昇などの機能は出来たのですが、アイテムショップの機能を追加することに苦戦しています。
Scriptについてもですが、そもそもの構成要素などにも不安を抱えています。
まずは実装までの考え方を「文字で」理解したいです。
最終地点は、ゲーム内通貨を消費してアイテムを購入するシステムの構築です。
まさに以下の画像のようなイメージです。
イメージ説明

現状

UIのButton機能を使って配置・装飾(画像の挿入など)止まり

試したこと

右も左も分からない状態でどこへ向かえば良いのかわからず、とにかく書店やサイトを探しましたが類似例はほとんど見つかりませんでした。

### 仕様
・アイテムは大きく分けて2種類(1クリック当たりの生産を増やす物、自動生成ぺースを高める物)
・ゲーム内で生産したゲーム内通貨を消費してアイテムを購入
・レベルマックス、アンロックはグレーアウト
・アイテム購入の際は「購入しますか?はいorいいえ」のようなシーンは設けず、クリック後すぐに購入・実装

見つけた参考になりそうなページ

理想は以下のようなものですが、用語を置き換えるだけで成立するのでしょうか...?
http://yasuaki-ohama.hatenablog.com/entry/2015/05/16/092032
http://yasuaki-ohama.hatenablog.com/entry/2016/07/06/235528

C#

1 2using System.Collections; 3using Sy![![イメージ](f07998b715d0964338192328b8d658e7.png)ollections.Generic; 4using UnityEngine; 5using UnityEngine.UI; 6using System; 7 8public class GameManager : MonoBehaviour { 9 10 //定数定義 11 private const int MAX_ORB = 5000; //オーブ最大数 12 private const int RESPAWN_TIME = 15; //オーブが発生する秒数 13 private const int MAX_LEVEL = 5; //最大キーパーレベル 14 15 //データセーブ用キー 16 private const string KEY_SCORE = "SCORE"; //スコア 17 private const string KEY_LEVEL = "LEVEL"; //レベル 18 private const string KEY_ORB = "ORB"; //オーブ数 19 private const string KEY_TIME = "TIME"; //時間 20 21 //オブジェクト参照 22 public GameObject orbPrefab; //オーブプレハブ 23 public GameObject trophyPrefab; //トロフィープレハブ 24 public GameObject canvasGame; //ゲームキャンバス 25 public GameObject textScore; //スコアテキスト 26 public GameObject imageKeeper; //キーパー 27 public float clickrate = 0.5f; 28 public GameObject ball; 29 30 //メンバ変数 31 private int score = 0; //現在のスコア 32 private int nextScore = 400; //レベルアップまでに必要なスコア 33 34 private int currentOrb = 0; //現在のオーブ数 35 36 private int keeperLevel = 0; //キーパーのレベル 37 38 private DateTime lastDateTime; //前回オーブを生成した瞬間 39 40 private int[] nextScoreTable = new int[] { 100,200,300,400,500 }; //レベルアップ値 41 42 private int numOfOrb; //まとめて生成するオーブの数 43 44 // Use this for initialization 45 void Start () { 46 47 //データ削除メソッド 48 //PlayerPrefs.DeleteAll(); 49 50 //初期設定 51 score = PlayerPrefs.GetInt(KEY_SCORE, 0); 52 keeperLevel = PlayerPrefs.GetInt(KEY_LEVEL, 0); 53 54 nextScore = nextScoreTable[keeperLevel]; 55 imageKeeper.GetComponent<KeeperManager>().SetKeeperPicture(keeperLevel); 56 imageKeeper.GetComponent<KeeperManager>().SetKeeperScale(score, nextScore); 57 58 RefreshScoreText(); 59 60 } 61 62 // Update is called once per frame 63 void Update () { 64 //まとめて生成するオーブがあれば生成 65 while (numOfOrb > 0) 66 { 67 Invoke("CreateNewOrb",0.1f*numOfOrb); 68 numOfOrb--; 69 } 70 } 71 72 //バックグラウンドへの移行時と復帰時(アプリ起動時も含む)に呼び出される 73 74 private void OnApplicationPause(bool pauseStatus) 75 { 76 if (pauseStatus) 77 { 78 //アプリがバックグラウンドへ移行 79 } 80 else 81 { 82 //バックグラウンドから復帰 83 //時間の復元 84 string time = PlayerPrefs.GetString(KEY_TIME, ""); 85 if (time == "") 86 { 87 lastDateTime = DateTime.UtcNow; 88 } 89 else 90 { 91 long temp = Convert.ToInt64(time); 92 lastDateTime = DateTime.FromBinary(temp); 93 } 94 95 numOfOrb = 0; 96 //時間によるオーブ自動生成 97 TimeSpan timeSpan = DateTime.UtcNow - lastDateTime; 98 if (timeSpan >= TimeSpan.FromSeconds(RESPAWN_TIME)) 99 { 100 while (timeSpan >= TimeSpan.FromSeconds(RESPAWN_TIME)) 101 { 102 if (numOfOrb < MAX_ORB) 103 { 104 numOfOrb++; 105 } 106 timeSpan -= TimeSpan.FromSeconds(RESPAWN_TIME); 107 } 108 } 109 } 110 } 111 112 //新しいオーブの生成 113 public void CreateNewOrb() 114 { 115 lastDateTime = DateTime.UtcNow; 116 if (currentOrb >= MAX_ORB) 117 { 118 return; 119 } 120 CreateOrb(); 121 currentOrb++; 122 123 SaveGameData(); 124 } 125 126 //オーブ生成 127 public void CreateOrb() 128 { 129 GameObject orb = (GameObject)Instantiate(orbPrefab); 130 orb.transform.SetParent(canvasGame.transform, false); 131 orb.transform.localPosition = new Vector3( 132 UnityEngine.Random.Range (-100.0f, 100.0f), 133 UnityEngine.Random.Range (-300.0f, -450.0f), 134 0f); 135 136 orb.GetComponent<OrbManager>().Flyorb(); 137 138 //ボールアニメーション 139 StartCoroutine("ClickAnim");//"ClickAnim"のコルーチンを呼ぶ. 140 141 } 142 143 144 145 //オーブ入手 146 public void GetOrb() 147 { 148 score += 1; 149 //キーパー画像切り替えメソッド挿入予定 150 151 //レベルアップ値を超えないように制限 152 if (score > nextScore) 153 { 154 score = nextScore; 155 } 156 157 KeeperLevelUp(); 158 RefreshScoreText(); 159 imageKeeper.GetComponent<KeeperManager>().SetKeeperScale(score, nextScore); 160 SaveGameData(); 161 162 163 164 } 165 166 //スコアテキスト更新 167 void RefreshScoreText() 168 { 169 textScore.GetComponent<Text>().text = 170 score + "GOAL"; 171 } 172 173 //キーパーのレベル管理 174 void KeeperLevelUp() 175 { 176 if (score >= nextScore) 177 { 178 if (keeperLevel < MAX_LEVEL) 179 { 180 keeperLevel++; 181 score = 0; 182 183 KeeperLevelUpEffect(); 184 185 nextScore = nextScoreTable[keeperLevel]; 186 imageKeeper.GetComponent<KeeperManager>().SetKeeperPicture(keeperLevel); 187 } 188 } 189 } 190 191 //レベルアップ時の演出 192 void KeeperLevelUpEffect() 193 { 194 GameObject trophy = (GameObject)Instantiate(trophyPrefab); 195 trophy.transform.SetParent(canvasGame.transform, false); 196 trophy.transform.SetSiblingIndex(5); 197 198 Destroy(trophy, 0.5f); 199 } 200 201 //ゲームデータをセーブ 202 void SaveGameData() 203 { 204 PlayerPrefs.SetInt(KEY_SCORE, score); 205 PlayerPrefs.SetInt(KEY_LEVEL,keeperLevel); 206 PlayerPrefs.SetInt(KEY_ORB,currentOrb); 207 PlayerPrefs.SetString(KEY_TIME,lastDateTime.ToBinary().ToString()); 208 209 210 PlayerPrefs.Save(); 211 }

有識者の方、どうぞよろしくお願い致します。

bochan2👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/01/05 16:45

質問されているアイテムショップとは、実際のユーザー課金によるアイテム販売のお話でしょうか?
k2zu1112

2019/01/06 00:59

説明が不足しておりました。 この質問では、ゲーム内のコインを消費して購入するアイテムのことを意図しております。 ユーザー課金ではありません。 ご指摘ありがとうございます。
yukkuri

2019/01/06 03:42

コードは```で囲むと、コードブロックというものになって見やすくなるので、編集してください。
k2zu1112

2019/01/06 03:51

yukkuri様、ただいま編集しました。 もし編集に仕方が違うようであれば、その際は一言いただけると幸いです。
yukkuri

2019/01/06 03:52

すいません、私の説明がだめでした。 ```C# using ... ``` みたいな感じにしてください。
k2zu1112

2019/01/06 04:09

今回はちゃんと修正出来たと思います。 大変勉強になりました、ありがとうございます。
guest

回答1

0

ベストアンサー

質問いただきありがとうございます!
大まかな方針としてはゲーム内通貨をPlayerPrefsに書き込んで処理するのが良いと思います。

###コード
これを好きなクラス名にして(MonoBehaviorは継承)ショップのシーンに貼り付けて下さい
UIのボタンからBuyを指定するとイベントを登録出来ます。
pricesをinspector画面から指定すると値段を設定できます(設定しないとエラー吐きます)。
moneydialogはお金が足りないときに表示されるダイアログのgameobjectです。使う場合は閉じるボタンにイベントを設定して下さい。いらなかったら消してください

アイテムの種類が多いのであればscriptableObjectを使った方がいいと思います

C#

1public GameObject moneydialog; 2public List<int> prices; 3public void Buy(int id){ 4 int a=0; 5 string key="ITEM"+id; 6 if(PlayerPrefs.HasKey(key)){ 7 a=PlayerPrefs.GetInt(key); 8 } 9 int m=0; 10 if(PlayerPrefs.HasKey("SCORE")){ 11 m=PlayerPrefs.GetInt("SCORE"); 12 } 13 if(m<prices[id]){ 14 moneydialog.SetActive(true); 15 return; 16 } 17 m-=prices[id]; 18 a+=1; 19 PlayerPrefs.SetInt(key,a); 20 PlayerPrefs.SetInt("SCORE",m); 21}

投稿2019/01/06 01:15

編集2019/01/06 06:54
bochan2

総合スコア2050

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k2zu1112

2019/01/06 03:26

bochan2様、昨夜に引き続きご質問への返答ありがとうございます。 大まかな方針の件、理解いたしました。 出来れば動くコードも頂戴したいと思っております。 現在のスクリプトを追記しました。 よろしくお願いいたします。
k2zu1112

2019/01/06 06:14

動くコードの作成ありがとうございます。 ダイアログまで付けていただけて非常に嬉しいです。 そこでコードについて1点質問なのですが、今回のゲーム中ではクリックにより生成されたものを”ORB”と呼んでおり、それがゴールへ飛んでいく演出を付けております。そして、飛んで行って消滅した後は「score」として得点を保存しております。 それを踏まえた場合では、先ほどいただいたコードの”ORB”の部分は「score」への変更が必要でしょうか? 同時並行で2つの質問にご回答いただいて本当に感謝しております。 何度もお手数をおかけしますが回答の方宜しくお願い致します。
bochan2

2019/01/06 06:53

scoreでしたか 修正しておきまづしておきます
k2zu1112

2019/01/06 09:07

すみません、非常に助かります。 現在は作成していただいた文章をお借りして作業をしているのですが、文章の3~5行目の public void Buy(int id){ int a=0; string key="ITEM"+id; 部分の理解に少々苦しんでおります。 他に出てきた変数を言葉でいうと、a=アイテム保有数、m=所持金(score)で合っているかと思いますが、"ITEM"と変数idは何を表しているのでしょうか? また、新たに"ITEM"を作る必要があるかと思いますが、"SCORE"や"ORB"などと同じように、データセーブ用のキーを作れば良いということでしょうか? 初歩的な質問かもしれませんがよろしくお願いします。
bochan2

2019/01/06 10:01

仰るとおりアイテムごとに新しいキーを作るということです
k2zu1112

2019/01/06 10:37

ありがとうございます。 コードがだいぶ読み取れるようになりました。 コードのところであと一つだけ教えていただきたいのですが、変数idは言葉でいうと何と表現されるものでしょうか...? Buy(int id) は何を引数に取ったメソッドなのかがもう一つ分かりません。 よろしくお願いします。
bochan2

2019/01/06 12:02

BuyはUIのボタンのInspector画面でイベントを設定するもので、Inspector画面からボタンごとに対応するidの値を設定するようにしました
k2zu1112

2019/01/06 12:20

ということはつまり、idの値=各Prices(アイテムの価格)ということでよろしいのでしょうか?
k2zu1112

2019/01/11 04:04

体調を崩して数日間寝込んでおり、返信が遅れてしまいました。 ご回答本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問