チュートリアル作成日
2020年9月7日
追記 2023年10月18日
ゲームのルール
5色のボールがランダムに40個ある。プレイヤーは、同じ色のボールが3個以上隣り合っているものを探し出してなぞると、ボールを消すことができる。消えたボールと同数のボールが上から追加される。1分間で何個のボールを消すことができるか競う。
制作環境
Unity2019.4.6f1
Unity2022.3.11f1(追記分)
C#
完成予想画像
遊び方
プレイヤーは3個以上同色のボールがつながっているところを探し出し、そこを指でなぞる。するとボールが消える。消えたボールと同数のボールが上から降ってくる。制限時間は1分。
2D。Unity 2Dコア。
名前、保存場所は自由。
2~3分で、プロジェクトが作成される。
AndroidへSwitch Platform
<Unity>--<File>--<Build Settings>
Androidを選択して、<Switch Platform>をクリック。2分程度で処理が終わる。
処理が終わったら、右上Xボタンで<Build Settings>を閉じる。
画面設定を16:9 Portraitに。
<Game>ウィンドウにて、サイズを<16:9 Portrait>にする。
<Scene>の名前を変更する。
<Project>--<Scene>フォルダの<SampleScene>で右クリック。名前を<Game>に変更。
ポップアップが出るので、<Reload>をクリック。
3つのフォルダを作る。
<Project>--<Assets>にて右クリック、<Create>--<Folder>を選択。名前を<Images>にする。
同じ要領で、<Prefabs>と<Scripts>のフォルダも作成する。
Frameオブジェクトの作成
<Project>--<Images>フォルダ内で右クリック、<Create>--<2D>--<Sprite>--<Square>を選択。名前はそのままでよい。
作成した<Square>を<Hierarchy>ウィンドウにドラッグアンドドロップ。
<Hierarchy>--<Square>を選択し、<Inspector>にて名前を<Frame>に変更。
<Transform>を以下のように設定。
<Position>--> X:0、Y:-5.5
<Scale>--> X:5、Y:1
<Add Component>--<Physics2D>--<Box Collider 2D>を選択。
これで、画面下に床ができた。
同様に、画面左右に壁を作る。
<Hierarchy>--<Frame>を2つ複製する。Ctrl + D。
<Frame(1)>の<Transform>にて、
<Position>--> X:-3、Y:0
<Scale>--> X:1、Y:10
<Frame(2)>を以下のように調整
<Position>--> X:3、Y:0
<Scale>--> X:1、Y:10
3つの<Frame>の<SpriteRenderer>--<Color>を黒にする。
Ballオブジェクトの作成
<Project>--<Images>フォルダ内にて右クリック、<Create>--<Sprite>--<Circle>を選択。名前はそのままでよい。
作成した<Circle>を<Hierarchy>ウィンドウにドラッグアンドドロップ。
名前を<RedBall>にする。
<Inspector>--<Transform>--<Scale>--> X:0.9、Y:0.9
<Inspector>--<SpriteRenderer>--<Color>にて、色を赤に。
<Add Component>--<Physics2D>--
<Circle Collider 2D>
<Rigidbody 2D>
をつける。
オブジェクトの摩擦をなくす。
<Project>--<Assets>フォルダにて右クリック、<Create>--<Physics Materal 2D>をクリック(リストの下のほうにある)。
名前はそのままでよい。
<Inspector>にて、<Friction>--> 0 にする。
摩擦係数0ということである。
この<New Physics Material 2D>を、<Hierarchy>--<RedBall>にアタッチ。
<RedBall>の<Inspector>--<Circle Collider 2D>--<Material>にアタッチされていることがわかる。
<YellowBall><BlueBall><GreenBall><AquaBall>を作る。
<RedBall>を複製して、名前と<Color>を変更すればよい。
位置を少しずつずらして表示したものが、下図である。
ここでテストプレイすると、ボールが落下して、床の上で止まることがわかる。
もし、床の上で止まらないならば、<Frame>オブジェクトにBox Collider 2Dをつけ忘れているかもしれない。
5つのタグを作る。
ボールオブジェクトを一つ選び、<Inspector>ウィンドウの<Tag>--<Untagged>の下向き▼をクリック。リストが表示されるので、一番下の<Add Tag>をクリック。
<Tags>--<List is Empty>の+マークをクリック。
<New Tag Name>--> <Red>と入れて<Save>をクリック。
同様にして、<Red><Yellow><Blue><Green><Aqua>の5つのタグを作成する。
作成したら、<Hierarchy>--<RedBall>をクリック。
<Inspector>--<Tag>--<Untagged>をクリックして、リストの中から<Red>を選択。
同様に、<YellowBall>には<Yellow>タグ、<BlueBall>には<Blue>タグをつけていく。
ボールをプレハブにする。
<Hierarchy>--<RedBall>を、<Project>--<Assets>--<Prefabs>フォルダにドラッグアンドドロップしてプレハブにする。
ほかのボールも同様にプレハブにする。
<Hierarchy>ウィンドウにて、青いアイコンで表示されるようになる。
プレハブにしたら、<Hierarchy>ウィンドウのボールオブジェクトはすべて削除する。
Playerオブジェクトを作成する。
<Hierarchy>にて、<Create Empty>を作成。名前を<Player>にする。
<Project>--<Scripts>にて右クリック、<Create>--<C# Script>を選択。
名前を<PlayerController>にする。(違う名前で作成してしまった場合、一度削除して、もう一度やり直してください)
<PlayerController>スクリプトを、<Player>オブジェクトにアタッチ。
<PlayerController>をダブルクリックして、Visual Studioを開く。
スクリプトを書く。
40個のボールを生成したいので、先ほどのボールオブジェクトを定義づける。
public class PlayerController : MonoBehaviour
{
public GameObject[] Balls;
----------------------
ボールを生成するSpawnBalls関数を作成。
void SpawnBalls()
{
for (int i = 0; i < 40; i++)
{
int r = Random.Range(0, 5);
var ball = Instantiate(Balls[r]);
ball.transform.position = new Vector2(Random.Range(-2f, 2f), Random.Range(2f, 4f));
}
}
-------------------
5種類のうちどのボールを生成するか、ランダムにしている。
また、ボールの生成位置もランダムで指定している。一か所に40個生成してしまうと、すべて重なってしまい、うまくいかない。(ぜひ試してみてください)
Start関数に、SpawnBall関数を実行するよう記述する。
void Start()
{
SpawnBalls();
}
--------------
保存してUnityへ戻る。
<Hierarchy>--<Player>を選択し、<Inspector>--<PlayerController(Script)>--<Balls>に、<Project>--<Prefabs>の5つのボールプレハブをアタッチする。
保存して、テストプレイ。
40個のボールがうまくできただろうか?
Visual Studioの<PlayerController>へ戻る。
これから作成するスクリプトは、
1.一つ目のボールをタッチしたときの処理
2.ドラッグしているときの処理
3.指を離したときの処理
の3つである。
一つ目のボールは何色でも構わないが、2つ目のボールは1つ目と同じ色かどうか、隣り合っているかどうか判定する必要がある。指を離したときに、同じ色のボールを3つ以上つなげているか判定し、つながっていればボールを消す。
まず、なぞったボールを管理するListを定義。そして、そのListに入った最後のボールを管理する変数を定義する。
private List<GameObject> listOfBalls = new List<GameObject>();
private GameObject lastBall;
Update関数に以下のように記述。Input.GetMouseButtonXXX(0)というのは決まり文句なのでスペルミスのないように注意。
void Update()
{
//一つ目のボールをタッチしたとき
if (Input.GetMouseButtonDown(0))
{
FirstBall();
}
//指でなぞり中のとき
if (Input.GetMouseButton(0) && listOfBalls.Count>0)
{
Dragging();
}
//指を離したとき
if (Input.GetMouseButtonUp(0))
{
DeleteBalls();
}
}
------------------------
タッチしはじめのFirstBall関数を作成する。
RaycastHit2Dについては、「My Lights Out! チュートリアル」に詳細な説明があるのでご参考に。
void FirstBall()
{
//Rayをマウスカーソル(タップ)したところから0.5fの距離で画面左下(Vector2.zero)に飛ばす。
RaycastHit2D hit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, 0.5f);
if (hit2D.collider!=null)
{
//もしRayが何かに当たり、かつそれがボールオブジェクトの時。
if (hit2D.collider.gameObject.CompareTag("Red")||hit2D.collider.gameObject.CompareTag("Yellow")
|| hit2D.collider.gameObject.CompareTag("Blue") || hit2D.collider.gameObject.CompareTag("Green")
|| hit2D.collider.gameObject.CompareTag("Aqua"))
{
//ヒットしたボールを変数として定義
var thisBall = hit2D.collider.gameObject;
//thisBallをリストに追加
listOfBalls.Add(thisBall);
//ボールのColor情報を取得
Color ballColor = thisBall.GetComponent<SpriteRenderer>().color;
//色を半透明になるように指定(aは透明度)
ballColor.a = 0.5f;
//ボールを半透明にする
thisBall.GetComponent<SpriteRenderer>().color = ballColor;
//このボールを、なぞった最後のボールとする
lastBall = thisBall;
}
}
}
--------------------------
Dragging関数を作成し、以下のように記述。FirstBall関数と同じところも多い。
void Dragging()
{
RaycastHit2D hit2D = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, 0.5f);
if (hit2D.collider != null)
{
//1つ前のボールのタグと同じタグの時。
if (hit2D.collider.gameObject.tag==lastBall.tag)
{
var thisBall = hit2D.collider.gameObject;
//このボールと、ひとつ前のボールの距離を取得
Vector2 distance = thisBall.transform.position - lastBall.transform.position;
//もしthisBallがListになく、かつdistanceが1.1f以下のとき、以下の処理を行う。
//つまり、2つのボールを行ったり来たりとなぞっても意味がないようにし、
//かつ、遠いボールはつながらないようにしている。
if (!listOfBalls.Contains(thisBall) && distance.magnitude<=1.1f)
{
listOfBalls.Add(thisBall);
Color ballColor = thisBall.GetComponent<SpriteRenderer>().color;
ballColor.a = 0.5f;
thisBall.GetComponent<SpriteRenderer>().color = ballColor;
lastBall = thisBall;
}
}
}
}
---------------------------
指を離したときのDeleteBalls関数を作成する。
ボールを消した後、新しいボールを生成する関数はあとで記述する。
void DeleteBalls()
{
//Listに3つ以上のボールが入っているなら。
if (listOfBalls.Count>=3)
{
//リストのボールを消去
foreach (var item in listOfBalls)
{
Destroy(item);
}
//新しいボールを生成する処理
}
//Listのボールが2つ以下ならば。
else
{
//色を元に戻す。
foreach (var item in listOfBalls)
{
Color ballColor = item.GetComponent<SpriteRenderer>().color;
ballColor.a = 1;
item.GetComponent<SpriteRenderer>().color = ballColor;
}
}
//Listを空にする
listOfBalls.Clear();
}
------------------------
保存してUnityへ戻る。
テストプレイ。
うまく動くだろうか?
<PlayerController>スクリプトへ戻る。
消したボールと同数のボールを生成するNewBalls関数を作成する。
//引数(パラメータ)として、int型のballsを定義
void NewBalls(int balls)
{
for (int i = 0; i < balls; i++)
{
int r = Random.Range(0, 5);
var ball = Instantiate(Balls[r]);
ball.transform.position = new Vector2(Random.Range(-2f, 2f), Random.Range(4,4.5f));
}
}
---------------------
forの中で、ballsを使っている。
DeleteBalls関数の一部に追記。
List内のボールの数を指定して、NewBalls関数を実行。
//新しいボールを生成する処理
NewBalls(listOfBalls.Count);
---------------------
保存してUnityへ戻る。
テストプレイ。
うまく動くだろうか?
ゲームの基本的な部分はこれで完成である。
画面の上部に60秒の制限時間を表示する。
Canvasオブジェクトの設置。
<Hierarchy>--<UI>--<Canvas>をクリック。
以下のように調整
<Render Mode>--> Screen Space - Camera
<Render Camere>--> <Main Camera>をアタッチ
<Plane Distance>--> 5
<UI Scale Mode>--> Scale With Screen Size
<Reference Resolution>--> X:720, Y:1280 (X:1080, Y;1920)
<Screen Match Mode>--> Expand
Textオブジェクトを作成する。(Textに関して、大きく変更。スクロールしていただいて、追記分をご覧ください)
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Text>を選択。
名前を<TimeLimitText>とする。
<Inspector>にて、
<Rect Transform>--> PosX;200、PosY:550
<Text>--<Text>--> 0
<Font Size>--> 60
<Alignment>--> 中央ぞろえ
<Horizontal Overflow><Vertical Overflow>--> Overflow
<Color>--> 白
Adminオブジェクトの作成
<Hierarchy>にて<Create Empty>。名前を<Admin>にする。
<Project>--<Scripts>にて右クリック、<Create>--<C# Script>。名前を<Admin>とする。
<Admin>スクリプトを、<Hierarchy>--<Admin>オブジェクトにアタッチ。
<Admin>スクリプトをダブルクリックして、Visual Studioへ。
スクリプトを書く。
<Admin>スクリプトでやりたいことは、
・時間の計測
・60秒経過したらゲームを終了する
・NewGameボタンの処理(あとで作成)
である。
スクリプトを以下の通り記述する。
using UnityEngine;
//忘れずに以下の1行を記述
using UnityEngine.UI;
public class Admin : MonoBehaviour
{
public Text timeLimitText;
private float timeLimit;
// Start is called before the first frame update
void Start()
{
timeLimit = 60;
//ToString("f0")とすると、整数で表示される。
timeLimitText.text = timeLimit.ToString("f0")+"秒";
}
// Update is called once per frame
void Update()
{
if (timeLimit>0)
{
timeLimit -= Time.deltaTime;
}
if (timeLimit<=0)
{
timeLimit = 0;
}
timeLimitText.text = timeLimit.ToString("f0") + "秒";
}
}
-----------------------
Unityへ戻る。
<Hierarchy>--<Admin>を選択。
<Inspector>--<Admin(Script)>--<TimeLimitText>に、<Hierarchy>--<TimeLimitText>オブジェクトをアタッチ。
テストプレイしてうまく制限時間が減っていくことを確認。
「Finish!」と表示する。
あらたにTextオブジェクトを作成する。
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Text>を選択。
名前を<FinishText>とする。
<Inspector>にて、
<Rect Transform>--> PosX:0、PosY:0
<Text>--<Text>--> Finish!
その他は<TimeLimitText>と同じに設定。
<Admin>スクリプトへ戻る。ここから下は、Unity2022でも同じですので、そのまま使えます。
作成した<FinishText>をGameObject型として定義。
public class Admin : MonoBehaviour
{
public Text timeLimitText;
private float timeLimit;
public GameObject finishText; //ここです。
-----------------
Start関数内に追記。
void Start()
{
timeLimit = 60;
timeLimitText.text = timeLimit.ToString("f0")+"秒";
finishText.SetActive(false); //まずfalseにしておきます。つまり、画面に表示されません。
}
---------------------
Update関数内の、制限時間が過ぎたところに1行追記。
if (timeLimit<=0)
{
timeLimit = 0;
finishText.SetActive(true); //時間切れになったら、true
}
-----------------------
保存してUnityへ戻る。
<Hierarchy>--<Admin>を選択。<Inspector>--<Admin(Script)>--<Finish Text>に、<Hierarchy>--<Canvas>--<FinishText>をアタッチ。
Text Mesh Proオブジェクトを作成する。
Unityでは、Textではなく、Text Mesh Proというものを使うことになりました。
これは、ひらがなや漢字を使いたいときは、前もっていくつか作業が必要になります。
したがって、追記分においては簡単に、英数字のみを使っていきます。
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Text-TextMeshPro>を選択。
名前を<TimeLimitText>とする。
<Inspector>にて、
<Rect Transform>--> Pos X:380, PosY:800
Width:300, Height:50
Textの内容をとりあえず0としておく。
Font Size:80
Vertex Color :白(お好み)
Allignmentは、中央ぞろえに。
Adminオブジェクトの作成
<Hierarchy>にて<Create Empty>。名前を<Admin>にする。
<Project>--<Scripts>にて右クリック、<Create>--<C# Script>。名前を<Admin>とする。
<Admin>スクリプトを、<Hierarchy>--<Admin>オブジェクトにアタッチ。
<Admin>スクリプトをダブルクリックして、Visual Studioへ。
スクリプトを書く。
<Admin>スクリプトでやりたいことは、
・時間の計測
・60秒経過したらゲームを終了する
・NewGameボタンの処理(あとで作成)
である。
スクリプトを以下の通り記述する。
以下、TextMeshProを使うときのスクリプトです。
using UnityEngine;
//以下の1行を入れる。
using TMPro;
public class Admin : MonoBehaviour
{
public TMP_Text timeLimitText;
private float timeLimit;
// Start is called before the first frame update
void Start()
{
timeLimit = 60;
timeLimitText.SetText(timeLimit.ToString("f0") + "sec"); //"f0"で整数表示。漢字が使えないので、"秒"ではなく、"sec"にしておきました。
}
// Update is called once per frame
void Update()
{
if(timeLimit > 0)
{
timeLimit -= Time.deltaTime;
}
if(timeLimit <= 0)
{
timeLimit = 0;
}
timeLimitText.SetText(timeLimit.ToString("f0") + "sec");
}
Unityエディターに戻る。
<Hierarchy>--<Admin>を選択。
<Inspector>--<Admin(Script)>--<TimeLimitText>に、<Hierarchy>--<TimeLimitText>オブジェクトをアタッチ。
テストプレイしてうまく制限時間が減っていくことを確認。
「Finish!」と表示する。
あらたにTextMeshProオブジェクトを作成する。
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Text-TextMeshPro>を選択。
名前を<FinishText>とする。
<Inspector>にて、文字が画面の真ん中に出るように設定。
文字サイズなどは、TimeLimitTextと同じでもいいし、Finishの方が大きくてもいいかもしれません。
Text内容は、FINISH!
<Admin>スクリプトへ戻る。
ここからは、従前のチュートリアルと同じなので、上に戻ってください。
様々な得点計算方法が考えられるが、単純にボールを消した数を数えることにする。
得点を表示するTextオブジェクトを作成する。ここもTextMeshProになります。お好みで文字サイズ、カラーは調節してください。
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Text>を作成。
名前を<BallCountText>とする。
<Rect Transform>--> PosX;0、PosY:400
下記画像を参考に、ちょうどよい大きさ・色に設定する。
<PlayerController>スクリプトへ移動。
冒頭に、<BallCountText>と消したボールを数える変数を定義するとともに、時間切れとなったときに操作できなくするためのboolを定義する。
//これを忘れずに。
using UnityEngine.UI;
//TextMeshProの場合は、
using TMPro;
public class PlayerController : MonoBehaviour
{
(中略)
//
public Text ballCountText; //従来のTextの場合。
public TMP_Text ballCountText; //TextMeshProの場合は、上ではなく、こちらです。
private int ballsDeleted = 0;
public bool isFinished;
----------------------
Start関数に1行追記。
void Start()
{
ballCountText.text = ballsDeleted.ToString(); //この書き方で、TextもTMPもOK。
SpawnBalls();
}
-----------------------
Update関数の冒頭に追記。
void Update()
{
if (isFinished)
{
return;
}
------------------
DeleteBalls関数内の、新しいボールを生成する処理の後に、追記。
//新しいボールを生成する処理
NewBalls(listOfBalls.Count);
//消したボールをカウントして表示する。
ballsDeleted += listOfBalls.Count;
ballCountText.text = ballsDeleted.ToString();
-------------------
保存して、<Admin>スクリプトへ。
時間切れとなったときに、<PlayerController>のisFinishedをtrueにする。
public class Admin : MonoBehaviour
{
(中略)
//
private PlayerController playerControllerCS;
//Start関数内に追記。
void Start()
{
timeLimit = 60;
timeLimitText.text = timeLimit.ToString("f0")+"秒";
finishText.SetActive(false);
//playerControllerCSを定義。
playerControllerCS = FindObjectOfType<PlayerController>();
}
-----------------------------
Update関数内に追記。
if (timeLimit<=0)
{
timeLimit = 0;
finishText.SetActive(true);
//
playerControllerCS.isFinished = true;
}
--------------------------------------
保存してUnityへ戻る。
<Hierarchy>--<Player>を選択し、<Inspector>--<PlayerController(Script)>--<Ball Count Text>に、<Hierarchy>--<Canvas>--<BallCountText>オブジェクトをアタッチ。
ゲームのやり直しができるように、NewGameボタンを作成する。
Buttonオブジェクトを作成する。
<Hierarchy>--<Canvas>にて右クリック、<UI>--<Button>を選択。<UI>--<Button-TextMeshPro>
名前を<NewGameBtn>とする。
<Inspector>にて、//位置、サイズはお好みで。
<Rect Transform>--> PosX:-250、PosY:550
Width:100、Height:100
に設定。
<NewGameBtn>の子オブジェクトとなっている<Text>を以下のように設定。
<TextMeshPro>の場合も、似たような感じで。
スクリプトを書く。
<Admin>スクリプトへ移動。
以下のように記述する。
//忘れずに記述。
using UnityEngine.SceneManagement;
//新しく関数を作成。
public void NewGameBtn()
{
SceneManager.LoadScene("Game");
}
------------------
保存してUnityへ戻る。
<Hierarchy>--<Canvas>--<NewGameBtn>を選択し、<Inspector>--<Button>--<On Click()>の+マークをクリック。
<Admin>オブジェクトをアタッチして、NewGameBtn関数を関連付ける。
<Unity>--<File>--<Build Settings>を開く。
<Add Open Scenes>をクリック。
<Hierarchy>--<Main Camera>を選択、<Inspector>にて、
<Camera>--
<Clear Flags>--> Solid Color
<Background>--> 黒
<Projection>--> Orthgraphic
<Size>--> 5
テストプレイ。
タイトルを入れたり、色を調整したりして、ほぼ完成!
スマートフォン端末(Android)の「開発者向けオプション」と「USBデバッグの有効化」を設定する。
以下のサイトを参照。
https://developer.android.com/studio/debug/dev-options?hl=ja
スマートフォンとPCを、USBケーブルでつなぐ。(おそらく充電器のコードがUSBケーブル)
<Unity>--<File>--<Build Settings>--<Player Settings>をクリック。
<CompanyName><ProductName>を適当に決め、下の画像の<Default Orientation>を<Portrait>にする。これでスマートフォンを傾けてもゲーム画面が回転しない。
設定したら、右上の×ボタンで<Project Settings>を閉じる。
スマートフォンとPCがケーブルで接続されていることを確認し、<Build And Run>をクリック。
ファイル名を求められるので、「TestSample」などとしておく。
おそらく3分くらいでビルド処理が終了する。
終わったら、右上Xボタンで<Build Settings>を閉じる。
Unityに、ビルドが正常に終了したことを示すメッセージが出ている。
USBケーブルを抜いて、スマートフォンでテストプレイしてみる。
これで、あなたオリジナルのゲームの完成です!
より面白くするために、
・BGMをつける。
・連鎖の数によって得点を変える。
・消えると高得点になるボールを加える。
・ボールの数を増やしてみる。
などなど、いろいろ試してみましょう。
それでは!
Feel free to Share and Comment!
ホームへ戻る。
コメントをお書きください
moi (金曜日, 26 3月 2021 00:47)
こちらも完成いたしました!
かなりリアルタイムさを感じられるゲームっぽいので、かなり身構えていましたが、一つ一つ細かく見ていくと、やっぱりプログラムの集まりなんだなと実感しました!(?)
でもこのようにチュートリアルとして提示されているから自分でもあとから理解できますが、自分で構成を考えるとなるとまだまだ難しそうです。
クリエイターには脱帽です!
次のゲームも作ってみます、ありがとうございました!
ケンヤ (土曜日, 31 7月 2021 17:25)
よろしくお願いします
Renoboy (土曜日, 31 7月 2021 21:53)
ケンヤさん、ガンバレー!
moiさん、お疲れさまでした。ここまで理解できれば、自分のイメージ通りのゲームを作れるようになると思いますよ!
kaz (火曜日, 10 8月 2021 11:35)
ハマってしまいました。
listOfBallsとlastBallの定義は以下の通りでよろしいでしょうか?
List<GameObject> listOfBalls;
GameObject lastBall;
PlayerController.csの先頭に記述したのですが、以下のようなエラーが出てしまいます
NullReferenceException: Object reference not set to an instance of an object
Renoboy (火曜日, 10 8月 2021 13:03)
kazさん、それ書き忘れてました、コメントしてくれてありがとうございます。
そこは、以下のように定義すればよいと思います。
private List<GameObject> listOfBalls = new List<GameObject>();
private GameObject lastBall;
これで大丈夫だと思います。がんばってください!
kaz (水曜日, 11 8月 2021 11:09)
出来ました!
ありがとうございます。
私のPCだとマウスの選択判定が厳しすぎるので
頑張って調整したみたいと思います。
Renoboy (水曜日, 11 8月 2021 12:14)
kazさん、おめでとう!
いろいろいじったり、足したりしてみてくださいね。
あ (日曜日, 27 2月 2022 16:12)
楽しみ
Renoboy (月曜日, 28 2月 2022)
あさん、
新しいことにチャレンジするのは楽しいものですね。
気楽に楽しんでください!