前回は、羊から羊毛(wool)オブジェクトが出てくるようになりました。
前回の記事↓

今回はその刈り取った羊毛(Wool)の売却処理を実装していきます。
Walletの作成
まず手持ちのお金を管理・表示するオブジェクト用意しましょう。
お金が入っているのはWallet(財布)なので、Walletオブジェクトを作ります。
Hierarchyの第2回で作成したCanvas/Panel(Header) を選択し、UI→Text を追加します。
追加されたTextは以下のように設定しておきます。
- 名前 Text(Wallet)
- RectTransform
- Anchor Min X:0 Y:0
- Anchor Max X:1 Y:1
- Left 0 Top 0 Right 0 Bottom 0
-
上記設定はAnchorPresetsからShift+Altを押しながら右下のボタンをクリックでも良いです
- Text
- Font : ShigotoMatomegaki-Regular-1-01
- Font Style:Bold
- Font Size:48
- Alignment: 中央寄せ(水平センタリング・垂直センタリング)
- Wallet スクリプトを追加 (Add Component → New Scripts → Wallet)
では、Walletスクリプトをそのまま修正していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using System.Collections; using System.Collections.Generic; using System.Numerics; using UnityEngine; using UnityEngine.UI; public class Wallet : MonoBehaviour { public BigInteger money; [SerializeField] private Text walletText; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { walletText.text = money.ToString("C0"); } } |
まず、using を2行追加しています。
using System.Numerics; は BigInteger (後述)を使用するために、
using UnityEngine.UI; は Text をスクリプトで使用するために宣言しています。
次に所持金を管理するために BigInteger
で money
を宣言しています。
この BigInteger
というのは int(Integer:整数)の桁数が多いバージョンです。
クリッカーゲームをやった事ある方はご存知かと思いますが、どんどんと所持金(クッキーなど)の増加量が増えてきてインフレしていくのが魅力の一つです。
そうなってくると、普通のint
での表現できる数(-2,147,483,648 から 2,147,483,647)を超えてしまう可能性があります。 では、long
にすれば?というと、long
でも表現できる数は-9,223,372,036,854,775,808 から 9,223,372,036,854,775,807 になります。 これでも足りない可能があるので、理論上上限が無い BigInteger
を使う事にします(考えすぎかもしれませんが)
そして、
1 2 |
[SerializeField] private Text walletText; |
でInspectorから所持金を表示するためのTextをセット出来るようにしています。
この、walletTextに表示する所持金をセットしているのが Update関数の中にある
1 |
walletText.text = money.ToString("C0"); |
になります。
ここで、BigInteger型の変数 money を ToString メソッドで文字列に変換しているんですが、“C0”という引数が渡されています。
これは、書式指定というものになります。 色々な指定があるのですが(参考:https://docs.microsoft.com/ja-jp/dotnet/standard/base-types/standard-numeric-format-strings) よく使うのは D (Decimal:10進数)やN(Number:数値)ですが、今回はC(Currency:通貨)を使っています。 通貨を表すための書式指定なので
- 勝手に \ や $ が付く
- 桁区切りの「,」が入る
といった特徴があります。 Cの後ろの0 は小数点以下の数を指定しています。 0なので、小数点以下は無し。という意味です。
usingについて
using というのは 雑に言うと「苗字を省略するための構文」になります。
BigInteger
は 本当は System.Numerics.BigInteger
が正式なクラス名ですし、
Text
は UnityEngine.UI.Text
が正式なクラス名です。
この「フルネーム」を毎回書くのが大変なので、先に苗字(System.Numerics
や UnityEngine.UI
など)だけをusing で宣言しておいて、実際のプログラムでは末端の名前だけで済むようにしている。というわけです。
では確認の為に再生してみましょう。
所持金は0円から増えていないので、「\0」と表示されています。
売却ボタンの作成
では、次に籠に溜まった羊毛(Wool)を売却できるように、売却ボタンを作りましょう
先ほどのPanel(Header)にTextを追加したのと同様に、Canvas/Panel(Sell) を選択し、今度は UI→Button を追加します。
追加されたButtonは以下のように設定しておきます。
- 名前 Button(Sell)
- RectTransform
- Anchor Min X:0 Y:0
- Anchor Max X:1 Y:1
- Left 0 Top 0 Right 0 Bottom 0
-
上記設定はAnchorPresetsからShift+Altを押しながら右下のボタンをクリックでも良いです
- Button(Sell)子要素のText
- Text:売却
- Font : ShigotoMatomegaki-Regular-1-01
- Font Style:Bold
- Font Size:48
- Alignment: 中央寄せ(水平センタリング・垂直センタリング)
この時点で、実行画面は以下のようになるはずです。
もちろん、売却ボタンを押してもなにも起きません(何もスクリプトを書いてませんしね)
GameMainオブジェクトの作成
では、この売却ボタン(Button(Sell)) をクリックしたら、実際に籠に溜まった羊毛(Wool)を売却できるようにしていきます。
HierarchyでCTRL+SHIFT+Nを押し、新規オブジェクトを作成します。
- 名前:GameMain
- AddComponent → New script → GameMain でスクリプト追加
このGameMainスクリプトを作っていきます。
メンバ変数
まず、「売却ボタンを押したら」という処理を組みたいので、InspectorでButtonを受け取れるように 変数 sellButton を [SerializeField]で宣言しておきます。
1 2 |
[SerializeField] private Button sellButton; |
次に、売却するということは、財布(Wallet)のお金(money)を増やすという事なので、同じくInspectorでWalletオブジェクトが受け取れるように、変数 wallet を [SerializeField]で宣言しておきます。
1 2 |
[SerializeField] private Wallet wallet; |
売却メソッド
売却用のメソッド SellAllWool() を用意します。
1 2 3 4 5 6 7 8 9 |
private void SellAllWool() { var wools = FindObjectsOfType<Wool>(); //画面上の全てのWoolスクリプトが付いたオブジェクトを検索してWool配列woolsに格納 foreach (var wool in wools) { wallet.money += 100; //TODO 本当は羊毛毎に金額を変えたい Destroy(wool.gameObject); } } |
メソッド内ではまず FindOBjectsOfType<Wool>()
で(コメントに書いてある通りではありますが)画面上のWoolスクリプトが付いているオブジェクトを全て探索して、woolsに格納しています。
それを foreach で全て回し、
- walletのmoneyを(とりあえず)100増加
- Destroy で削除
させています。
ボタンクリックイベントの追加
まだこのままでは、ボタンをクリックしてもSellAllWoolは呼ばれません。
Inspectorからクリック時に呼ぶメソッドを指定する方法もありますが、今回はスクリプト上でクリック時に呼ぶメソッドを指定する方法をとります。
1 2 3 4 |
void Start() { sellButton.onClick.AddListener( SellAllWool ); } |
1行ではありますが、細かく説明をすると
- sellButton は、Inspectorでセットする予定の売却ボタンが格納されています。
- そのsellButton の onClick.AddListener で、クリック時の処理について追加をしようとしています。
- AddListener には 今回の場合はonClick=クリック時に、どの関数を呼ぶか指定する必要があるため先ほど用意した SellAllWoolメソッドを指定しています。
GameMainスクリプト全体は以下のようになります(using宣言を忘れずに)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; public class GameMain : MonoBehaviour { [SerializeField] private Button sellButton; [SerializeField] private Wallet wallet; private void SellAllWool() { var wools = FindObjectsOfType<Wool>(); //画面上の全てのWoolスクリプトが付いたオブジェクトを検索してWool配列woolsに格納 foreach (var wool in wools) { wallet.money += 100; //TODO 本当は羊毛毎に金額を変えたい Destroy(wool.gameObject); } } // Start is called before the first frame update void Start() { sellButton.onClick.AddListener( SellAllWool ); } // Update is called once per frame void Update() { } } |
ではスクリプトを忘れずに保存して、UnityEditor上でのInspectorでButtonオブジェクトとWalletオブジェクトをセットし、再生して確認をしてみましょう。
羊毛(Wool)の売却金額設定
今はGameMainスクリプトでは羊毛の売却金額を
1 |
wallet.money += 100; //TODO 本当は羊毛毎に金額を変えたい |
として、一律100円に決め打ちして所持金に加算していますが、本来羊毛(Wool)の価値は羊毛自身が持っているべきなので、売却価格を表すメンバ変数 priceと、今後の事を考えてWoolスクリプトに売却処理を示すメソッド、Sell を追加しましょう。
Woolスクリプトを以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Wool : MonoBehaviour { [SerializeField] private Rigidbody2D _rigidbody2D; //羊毛の売却価格 public int price = 100; //羊毛の売却処理 public void Sell(Wallet wallet) { wallet.money += price; Destroy(gameObject); } // Start is called before the first frame update void Start() { _rigidbody2D.AddForce(Quaternion.Euler(0, 0, Random.Range(-15, 15)) * Vector2.up * 4, ForceMode2D.Impulse); transform.localScale = Vector3.one * Random.Range(0.4f, 1.5f); } // Update is called once per frame void Update() { if (transform.position.y < -5) { Destroy(gameObject); } } } |
priceはとりあえず100円にしてあります。
Sellメソッドでは 引数で受け取った Walletオブジェクトに金額を足しこんで、自分自身をDestroy(削除)するようにしました。
GameMainスクリプト修正
WoolスクリプトにWalletへ金額を足しこむ処理及び羊毛(Wool)の削除処理=Sellメソッドが入りましたので、GameMainスクリプトではそのメソッドを呼ぶだけになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GameMain : MonoBehaviour { [SerializeField] private Button sellButton; [SerializeField] private Wallet wallet; private void SellAllWool() { var wools = FindObjectsOfType<Wool>(); //画面上の全てのWoolスクリプトが付いたオブジェクトを検索してWool配列woolsに格納 foreach (var wool in wools) { wool.Sell(wallet); } } // Start is called before the first frame update void Start() { sellButton.onClick.AddListener( SellAllWool ); } // Update is called once per frame void Update() { } } |
忘れずに2つのスクリプト(WoolとGameMain)を保存したら、UnityEditorで挙動が変わらない事を確認しましょう。
おさらいと次回予告
今回は羊毛オブジェクトの売却処理を作りました。
次回は、羊オブジェクトを作り込んでいきます。
次回の記事↓

コメント