8パズル(スライドパズル)

My 8 Puzzle!


チュートリアル作成日

2020年9月5日

2021年3月26日一部追記 

 

ゲームのルール

1枚の絵を9つのピースに分けたもののうち8枚が3×3のマスにはめられており、スペースが1つ空いている。プレイヤーはピースを移動させて、ピースを元の絵の位置に戻すことができればクリアとなる。

 

制作環境

Unity 2019.4.6f1

C#

 

完成予想画像

 

遊び方

プレイヤーがピースをタップすると、そのピースの上下左右のどこかにスペースがあればそこに移動する。1枚の絵がバラバラの8枚のピースになっており、それらを元の位置に戻すことができればクリア。

 

 


プロジェクトの新規作成

プロジェクトの新規作成

2D。

名前、保存場所は自由。

2分程度でプロジェクトが作成される。

 

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>のフォルダも作成する。

 


パズルピースの作成

パズルにしたい絵の入手

今回はパブリックドメインのゴッホの絵にしました。以降、この絵を使用して説明します。

https://images.metmuseum.org/CRDImages/ep/original/DP-19279-001.jpg

 

Windowsのペイント3Dにて、3で割り切れるよう画像サイズを調整。

8パズルにするには、タテとヨコのサイズが3で割り切れたほうがやりやすい。

そこで、キャンバスサイズをタテ300ピクセル、ヨコ390ピクセルにする。

これで保存すると、ファイルサイズもかなり小さくなる。

 

Unityへ絵を取り込む

<Project>--<Assets>--<Images>フォルダに、いま作成した絵をドラッグアンドドロップ。

取り込んだ絵の上で右クリック、<Rename>。名前を<Gogh8Puzzle>にした。

 

絵を9つに分割する。

<Images>--<Gogh8Puzzle>を選択し、<Inspector>にて以下のように設定。

<Texture Type>--> Sprite (2D and UI)

<Sprite Mode>--> Multiple

<Pixels Per Unit>--> 100 (元画像の幅が300なので、100にすると幅がちょうど3Unitになる)

 

<Sprite Editor>をクリックすると、<Sprite Editor>ウィンドウが表示される。

 

<Slice>--<Type>--> Grid By Cell Count

<Column & Row>--> C3  R3

<Slice>をクリックすると、9つに分割される。

最後に、<Apply>をクリック。

 

フレームの作成

絵の外枠を作成する。

<Project>--<Images>にて、<Create>--<Sprite>--<Square>を作成。名前はそのまま。

 

これを<Hierarchy>ウィンドウにドラッグアンドドロップして、名前を<Frame>にする。これを複製して4つにする。

以下の画像を参考に、絵のフレームを作る。

<Frame>

<Position>--> X:0 Y:-1.5 Z:0

<Scale>--> X:3 Y:1 Z:1

 

以降、下図のように設定してください。

 

これでフレームの内側のタテが4マス、ヨコが3マスとなる。

 

4つの<Frame>に、<Add Component>--<Physics2D>--<Box Collider 2D>をつける。

 

最後に、<Frame (1)~(3)>を<Frame>の子オブジェクトにしておく(あとで移動が便利)。

 

 

ピースオブジェクトを作成する。

<Project>--<Assets>--<Images>の<Gogh8Puzzle>の9つの中からどれかひとつを<Hierarchy>ウィンドウにドラッグアンドドロップ。

名前を<PieceBase>に。

<Inspector>--<Add Component>--<Physics 2D>--<Box Collider 2D>を選択。

 

スクリプトを書く。

<Project>--<Assets>--<Scripts>フォルダ内で右クリック、<Create>--<C# Script>を選択。スクリプト名を<PieceMove>にする。(異なる名前で作成してしまった場合、一度削除して、新しく作り直してください)

<PieceMove>スクリプトを<Hierarchy>--<PieceBase>にアタッチ。

 

<PieceMove>をダブルクリックして、Visual Studioを開く。

 

このスクリプトでやりたいことは、

・タップしたら空いてるスペースに移動する。

ということである。

 

考え方としては、そのピースの上下左右にRayを飛ばし、そこに他のピースか<Frame>があるか調べ、無いところに移動する、というものである。

Rayとはレーザー光線のようなものであり、コライダーを認識する(My Lights Out!チュートリアル参照)

 

移動は、左右であればX座標に±1、上下であればY座標に±1.3移動する(もしこのチュートリアルと異なるサイズの絵を使っている場合は、別途調整してください)。

 

たとえば上にRayを飛ばして、何もなければ上に移動するスクリプトは以下のとおり。

 

        //上にRayを飛ばす。

        RaycastHit2D hitUp = Physics2D.Raycast(transform.position + Vector3.up, Vector2.up, 0.1f);

        if (!hitUp)

        {

            transform.position += new Vector3(0, 1.3f,0);

        }

-----------------------

まず、ピースの中心座標(transform.position)からY座標で1上(Vector3.up)を起点に、上方向に(Vector2.up)、距離0.1fのレーザー光線を飛ばしている。いま作成しているピースは、タテ1.3、ヨコ1の長さなので、自身に当たらないように設定することがポイント。

次に、そのレーザーに何も当たっていなければ(if ( !hitUp))、Y座標で1.3上に移動する。

 

新しくPieceMoving関数を作り、以下のように記述する。

 

void PieceMoving()

    {

        //上にRayを飛ばす。

        RaycastHit2D hitUp = Physics2D.Raycast(transform.position + Vector3.up, Vector2.up, 0.1f);

        if (!hitUp)

        {

            transform.position += new Vector3(0, 1.3f,0);

        }

        //下にRayを飛ばす。

        RaycastHit2D hitDown = Physics2D.Raycast(transform.position + Vector3.down, Vector2.down, 0.1f);

        if (!hitDown)

        {

            transform.position -= new Vector3(0, 1.3f, 0);

        }

        //右にRayを飛ばす。

        RaycastHit2D hitRight = Physics2D.Raycast(transform.position + Vector3.right, Vector2.right, 0.1f);

        if (!hitRight)

        {

            transform.position += new Vector3(1, 0, 0);

        }

        //左にRayを飛ばす。

        RaycastHit2D hitLeft = Physics2D.Raycast(transform.position + Vector3.left, Vector2.left, 0.1f);

        if (!hitLeft)

        {

            transform.position -= new Vector3(1, 0, 0);

        }

    }

-----------------

4つあるので、間違えないように注意。

 

ピースをタップしたときにPieceMoving関数を動かしたいので、OnMouseDown関数を作る。

 

private void OnMouseDown()

    {

        PieceMoving();

    }

---------------

Unityの機能で、OnMouseDown関数にすると、タップしたら反応する関数になる。

 

保存してUnityに戻る。

 

<Hierarchy>--<PieceBase>を、<Project>--<Prefabs>にドラッグアンドドロップして、プレハブ化する。

<Hierarchy>にある<PieceBase>は削除。

 

 


8つのパズルピースを並べる

GameManagerオブジェクトを作る。

<Hierarchy>にて、<Create Empty>を作成。名前を<GameManager>にする。

<Project>--<Scripts>にて右クリック、<Create>--<C# Script>を選択。名前を<GameController>にする。

<GameController>スクリプトを、<GameManager>にアタッチ。

 

<GameController>をダブルクリックして、Visual Studioへ。

 

 

スクリプトを書く。

<GameController>スクリプトでやりたいことは、

・8枚のピースを生成して、並べる。

・ピースが正解の位置に到達したらクリアを知らせる。

主にこの2点である。

 

まずはじめに、<PieceBase>プレハブと、8つの絵、さらにピースをいれておくListを定義する。

 

public class GameController : MonoBehaviour

{

    public GameObject PieceBase;

    public Sprite[] PieceFaces;

    private List<GameObject> PieceList = new List<GameObject>();

----------------------

 

Unityに戻る。

<Hierarchy>--<GameManager>を選択し、<GameController(Script)>の<Piece Base>と<Piece Faces>に関連するオブジェクトをアタッチ。

 

<PieceBase>には、<Project>--<Prefabs>の<PieceBase>をアタッチ。

 

<Piece Faces>に、<Project>--<Images>フォルダ内の<Gogh8Puzzle_0~7>を順番通りにアタッチ。<Inspector>ウィンドウの右上にあるカギマークをクリックして作業するとやりやすい。作業後はカギマークをクリックして、ロックを外す。

 

 

Visual Studioへ戻る。

<GameController>スクリプトに、CreatePieces関数を作る。

8個のピースオブジェクトを作り、対象の画像を割り当て、Listに追加する。

 

 void CreatePieces()

    {

        for (int i = 0; i < 8; i++)

        {

            var piece = Instantiate(PieceBase);

            piece.GetComponent<SpriteRenderer>().sprite = PieceFaces[i];

            PieceList.Add(piece);

        }

    }

--------------

 

ピースを並べるDealing関数を作る。

1段目に左から3枚、2段目に左から2枚、3段目は2枚並べる。

1段目と2段目の高さの差は1.3。

 

 void Dealing()

    {

        float offsetY = -1.3f;

        int number = 0;

 

        for (int i = 0; i < 3; i++)

        {

            for (int j = 0; j < 3; j++)

            {

                PieceList[number].transform.position = new Vector2(j, i*offsetY);

                number++;

                if (number>7)

                {

                    break;

                }

            }

        }

    }

-----------------

PieceList[0]を(0,0)に、PieceList[1]を(1,0)に・・・と並べている。

new Vector2の中は、"j"がX座標となっていることに注意。

"i"が1と2のときは、offsetYを乗じているので、Y座標で下に1.3f、2.6f下がる。

念のため、numberが7より大きくなったところでbreakしている。

 

これらをStart関数からつなげる。

 

void Start()

    {

        CreatePieces();

    }

void CreatePieces()

    {

        for (int i = 0; i < 8; i++)

        {

            var piece = Instantiate(PieceBase);

            piece.GetComponent<SpriteRenderer>().sprite = PieceFaces[i];

            PieceList.Add(piece);

        }

        Dealing();

    }

void Dealing()

    {

        float offsetY = -1.3f;

        int number = 0;

 

        for (int i = 0; i < 3; i++)

        {

            for (int j = 0; j < 3; j++)

            {

                PieceList[number].transform.position = new Vector2(j, i*offsetY);

                number++;

                if (number>7)

                {

                    break;

                }

            }

        }

    }

------------------------

保存してUnityに戻る。

 

テストプレイ。

 

Frameの位置とずれているし、ゲーム画面の真ん中に来ていない。

 

 

<Frame>を調整する。

 

親オブジェクトとなっている<Frame>の<Transform>--<Position>をX:1、Y:-3.8に。

 

4つの<Frame>すべてについて、<SpriteRenderer>--<Sprite>をNoneにして、透明にしてしまう。

 

 

Main Cameraの調整

<Hierarchy>--<Main Camera>を選択し、<Inspector>にて以下のように調整。

<Transform>--<Position>--> X:1, Y:-1.3, Z:-10

<Camera>--

<Clear Flags>--> Solid Color

<Background>--> 好きな色

<Projection>--> Orthgraphic

<Size>--> 3

 

 

テストプレイ

 

うまく動くだろうか?

 

うまくいかないときは、オブジェクトにBox Collider 2Dがついているかどうか、OnMouseDown関数でスペルミスをしていないかどうか確認してみよう。

 


8パズルの問題を作成する。

8パズルには解けない初期位置がある。

8パズルには解法のない初期位置があるので、ランダムにパズルピースを並べてはいけない。したがって、こちらで定めてやる必要がある。

 

正解位置を、

(0,1,2

 3,4,5

 6,7,8)

としたら(8は空きスペース)、

 

たとえば、

(2,6,0

 7,8,5

 1,3,4)

は正解のある初期位置であるから、このように並べることを考える。

 

Visual Studioに戻って、問題の配列を作る。

 

public class GameController : MonoBehaviour

{

    public GameObject PieceBase;

    public Sprite[] PieceFaces;

    private List<GameObject> PieceList = new List<GameObject>();

    //

    private int[,] puzzle1 = new int[3, 3]

    {

        {2,6,0 },

        {7,8,5 },

        {1,3,4 },

    };

----------------

3×3の2次元配列である。書き方が難しいので気をつける。

 

先に作ったDealing関数を書き換える。

 

void Dealing()

    {

        float offsetY = -1.3f;

        

        for (int i = 0; i < 3; i++)

        {

            for (int j = 0; j < 3; j++)

            {

                if (puzzle1[i,j]==8)

                {

                    continue;

                }

                PieceList[puzzle1[i,j]].transform.position = new Vector2(j, i*offsetY);

            }

        }

    }

------------

int number=0; を削除した。

PieceList[number]としていたところを、PieceList[puzzle1[i,j]]に変えた。

puzzle1[i,j]=8のときはPieceListがないので、continueする。

 

保存してUnityへ戻る。

 

テストプレイ。

 

うまく動いただろうか?

 

 


クリア判定を作る

8枚のピースが正しい位置にそろったときに、"CLEAR!"と表示され、9枚目のピースが出てきて絵が完成するようにしたい。

 

 

クリアの考え方

PieceList[0]のピースが1段目の左に、PieceList[1]のピースが1段目の中央に……と8枚そろえばよいので、8つのゲームオブジェクトの座標を認識し、それらが正解の座標にあるか確かめればよい。

 

Visual Studioに戻る。

 

<GameController>スクリプトにて、正解の座標を入れる配列を定義し、あたらしくSetCorrectPos関数を作る。

 

public class GameController : MonoBehaviour

{

    (中略)

    //

  public Vector3[] Pos;

 

    void Start()

    {

        SetCorrectPos();

        CreatePieces();

    }

 

    void SetCorrectPos()

    {

        int n = 0;

        float offsetY = -1.3f;

 

        for (int i = 0; i < 3; i++)

        {

            for (int j = 0; j < 3; j++)

            {

                Pos[n] = new Vector2(j, i * offsetY);

                n++;

            }

        }

    }

 

-----------------

Vector3配列はpublicにしないとうまくいかない。

あとでUnityに戻ったら、GameManagerの<Inspector>で、Posのsizeを9にする(2021年3月26日追記)。

SetCorrectPos関数はDealing関数と似ている。

 

 

クリアを認識する関数を作る。

各ピースの座標とPosの座標が一致しているか確かめるClearCheck関数を作る。これは<PieceMove>スクリプトから動かしたいので、publicな関数にする。

 

public void ClearCheck()

    {

        if (PieceList[0].transform.position==Pos[0]

            && PieceList[1].transform.position==Pos[1]

            && PieceList[2].transform.position == Pos[2]

            && PieceList[3].transform.position == Pos[3]

            && PieceList[4].transform.position == Pos[4]

            && PieceList[5].transform.position == Pos[5]

            && PieceList[6].transform.position == Pos[6]

            && PieceList[7].transform.position == Pos[7] )

        {

            //クリアしたときの演出

           

        }

    }

----------------

ifの中身が単純だが、長い。

 

クリアしたときに9枚目のピースを表示させたいので、先に作ったCreatePieces関数を少し手直しする。

先ほどは8枚の画像を入れていたので、9枚入れるようにする。

 

void CreatePieces()

    {

        for (int i = 0; i < 9; i++)

        {

            var piece = Instantiate(PieceBase);

            piece.GetComponent<SpriteRenderer>().sprite = PieceFaces[i];

            PieceList.Add(piece);

        }

        PieceList[8].SetActive(false);

        Dealing();

    }

------------------------

for ( int i =0; i < 9; i++)と、9までにした。

さらに、PieceList[8]には休んでおいてもらう命令を記述した。

 

そして、ClearCheck関数に9枚目のピースを表示するように追記する。

 

{

            //クリアしたときの演出

            PieceList[8].SetActive(true);

            PieceList[8].transform.position = new Vector2(2, -2.6f);

        }

----------------------

 

ここで、<PieceMove>スクリプトへ移動。

冒頭に、<GameController>スクリプトを認識するように設定し、あわせてStart関数にて定義する。

 

public class PieceMove : MonoBehaviour

{

    private GameController gameControllerCS;

 

    private void Start()

    {

        gameControllerCS = FindObjectOfType<GameController>();

    }

-----------------------

そして、PieceMoving関数の末尾に、1行追記。

 

//左にRayを飛ばす。

        RaycastHit2D hitLeft = Physics2D.Raycast(transform.position + Vector3.left, Vector2.left, 0.1f);

        if (!hitLeft)

        {

            transform.position -= new Vector3(1, 0, 0);

        }

        //

        gameControllerCS.ClearCheck();

---------------------

<GameController>のClearCheck関数を実行するよう記述した。

 

Unityへ戻る。

 

9枚目の画像をセットする。

<Hierarchy>--<GameManager>を選択し、<GameController(Script)>--<Piece Faces>に、<Project>--<Images>--<Gogh8Puzzle_8>をアタッチ。

 

 

CLEAR!メッセージを作る。

クリアしたら、「CLEAR!」という文字が画面中央に表示され、それが上にあがっていくような演出を作る。

 

<Hierarchy>にて<Create Empty>を作成。

名前を<ClearMessage>にする。

<Add Component>--<Mesh>--<Text Mesh>を選択。

<Transform>--<Position>--> X:1, Y:-1.3, Z:0

<Text Mesh>--

<Font Size>--> 100

<Character Size>--> 0.05

<Anchor>--> Middle center

 

Text Meshの文字サイズの設定は少し特殊である。

 

スクリプトを書く。

<Project>--<Scripts>にて右クリック、<Create>--<C# Script>を選択。

名前を<ClearMessageMove>とする。

<ClearMessageMove>スクリプトを、<Hierarchy>--<ClearMessage>にアタッチ。

<ClearMessageMove>をダブルクリックして、Visual Studioへ移動。

 

初期位置から上へ移動して止まるようにしたい。

 

一度にすべてのスクリプトを載せるが、コメントを参考に理解していただきたい。

 

using UnityEngine;

 

public class ClearMessageMove : MonoBehaviour

{

    //初期位置、止まる位置、移動スピードを計算する変数を定義

    private Vector2 StartPos;

    private Vector2 EndPos;

    private float step = 0;

 

    void Start()

    {

        //初期位置と止まる位置を指定

        StartPos = transform.position;

        EndPos = new Vector2(1, 1.3f);

    }

 

    void Update()

    {

        if (step>1)

        {

            return;

        }

        step += Time.deltaTime;

        transform.position = Vector2.Lerp(StartPos, EndPos, step / 1);

    }

}

----------------------

これで、ゆっくりと上に移動して(1,1.3)で止まる。

 

これをクリアしたときに起動させたいので、<GameController>スクリプトにて認識させる。

 

<GameController>スクリプトへ移動。

冒頭と、Start関数に追記。

 

public class GameController : MonoBehaviour

{

  (中略)

    //

    public Vector3[] Pos;

    //

    public GameObject ClearMessage;

 

    // Start is called before the first frame update

    void Start()

    {

        ClearMessage.SetActive(false);

        SetCorrectPos();

        CreatePieces();

    }

-------

 

ClearCheck関数を変更する。

クリアしたときに、ClearMessageを動かすようにする。

また、9枚目の絵を出す処理をLastPiece関数として別にして、それをInvokeを使ってクリアして1秒後に動くようにする。

 

public void ClearCheck()

    {

    (中略)

        

        {

            //クリアしたときの演出

            ClearMessage.SetActive(true);

            Invoke("LastPiece", 1f);

        }

    }

 

    void LastPiece()

    {

        PieceList[8].SetActive(true);

        PieceList[8].transform.position = new Vector2(2, -2.6f);

    }

----------------------------

Invokeは書き方が特殊なので、間違えないように注意する。

 

現状では、クリアした瞬間から1秒間は、クリアしているにもかかわらずプレイヤーがピースを操作できてしまうので、クリアしたときにピースを操作できないようにしたい。

 

<PieceMove>スクリプトにて、boolを設定。

 

public class PieceMove : MonoBehaviour

{

    private GameController gameControllerCS;

    //

    public bool isClear;

----------------------

 

OnMouseDown関数に追記。

 

private void OnMouseDown()

    {

        if (isClear)

        {

            return;

        }

        PieceMoving();

    }

--------------------

 

<GameController>スクリプトへ戻り、クリア処理に追記。

 

    //クリアしたときの演出

            foreach (var item in PieceList)

            {

                item.GetComponent<PieceMove>().isClear = true;

            }

 

            ClearMessage.SetActive(true);

            Invoke("LastPiece", 1f);

 

----------------------

foreachにて、PieceListすべてのisClearをtrueにしている。これで、クリアしたらピースを操作できないようになった。

 

保存してUnityへ戻る。

 

<GameController(Script)>--<Clear Message>に、<Hierarchy>--<ClearMessage>をアタッチ。

 

 

テストプレイ。

 

うまく動いただろうか?

 

 


NewGameボタンの作成

やり直したいときや、もう一度やりたいときのためにNewGameボタンを作る。

 

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

<Screen Match Mode>--> Expand

 

 

ボタンオブジェクトを作る。

<Hierarchy>--<Canvas>にて右クリック、<UI>--<Button>を選択。

名前を<NewGameBtn>にする。

<Inspector>--<Rect Transform>にて、PosX:250、PosY:-490、Width;100、Height:100に設定。

 

<NextGameBtn>の子オブジェクトの<Text>を調整する。

 

下図のようになればよい。

 

スクリプトを書く。

 

Visual Studioへ戻り、<GameController>スクリプトに新しくNewGameBtn関数を作る。

 

using UnityEngine.SceneManagement;

 

 public void NewGameBtn()

    {

        SceneManager.LoadScene("Game");

    }

--------------------

using UnityEngine.SceneManagement;を記述することを忘れない。

 

保存して、Unityへ戻る。

 

<Hierarchy>--<NewGameBtn>を選択し、<Inspector>--<Button>--<On Click()>に、<GameManager>オブジェクトをアタッチし、<GameController>--<NewGameBtn>スクリプトを関連付ける。

 

 

<File>--<Build Settings>を開き、<Add Open Scene>をクリックする。

右上Xボタンを押して、<Build Settings>を閉じる。

 

 

テストプレイしてみよう。

うまく動いただろうか?

 

 

タイトルを入れたり、ボタンの位置や大きさ、背景をつけてみたり、いろいろ調整しよう。

 


実機ビルド(for Android)

スマートフォン端末(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!

ホームへ戻る。

コメントをお書きください

コメント: 8
  • #1

    moi (木曜日, 25 3月 2021 01:49)

    お世話になっております。
    Unityゲーム制作に関して、貴サイトをありがたく参考にしております。

    こちらの8パズルの作成にあたり、以下のようなエラーが発生してしまいます。

    セクション:クリア判定を作る
    void SetCorrectPos()内
    【 Pos[n] = new Vector2(j, i * offsetY); 】

    エラー内容
    IndexOutOfRangeException: Index was outside the bounds of the array.

    試した内容
    ・代入するVector2をVector3に変更 →同様のエラー
    ・PosをVector2に変更 →同様のエラー
    ・代入するVector2の j , i をfloat型に変更 →同様のエラー
    ・Pos[n] の n を直接数値に変更 →同様のエラー
    ・別のVector2変数(配列ではない)を宣言、そちらに代入 →代入自体は成功

    上記の件に関しまして、同様の事象に陥るか、気をつけるべき点など、
    何か助言等がございましたらご教授くださると幸いです。

  • #2

    Renoboy (木曜日, 25 3月 2021 08:40)

    moiさん、お疲れ様です。
    そのエラーは、「配列の範囲を超えた値を入れてますよ」ということですけれど、、、
    SetCorrectPos()では、ただPos[n]に座標を入れてるだけですから、、、ちょっとわからないですね。
    こちらでも、いくつかいじってみたのですが、そのエラーは出ませんでした。

    別の場所でのエラーかもしれません。それまでのスクリプトも調べてみてください。
    すいません。

  • #3

    moi (金曜日, 26 3月 2021 00:42)

    解決しました!
    単純にインスペクター側を操作しておらず、ずっと要素の個数が0のままになってました。
    うっかりですが、解決してよかったです。
    こちらも完成しました!
    ありがとうございました。

  • #4

    Renoboy (金曜日, 26 3月 2021 07:59)

    moiさん、
    そういうことだったんですね! 気が付きませんでした。すいません。お手数おかけしました。
    でも、完成までたどり着いていただいてよかったです。
    おめでとうございます!

    記事を修正しました。教えていただいてありがとうございました。

  • #5

    kai (日曜日, 27 6月 2021 07:32)

    このサイトからUnityについてたくさん勉強させて貰っています。
    いつも素晴らしいミニゲーム有難うございます。

    1つ質問があり、この�のやり方ができない状態に陥っています。
    「<GameController(Script)>--<Clear Message>に、<Hierarchy>--<ClearMessage>をアタッチ」

    GameController (Script)のClear Message『空欄のボックス』の方にHierarchyにあるClearMessage (GameObject)をドラッグして入れようとしましたができません。
    ドラッグ以外の方法でやっても、Assetsの中にあるPieceBaseしか表示されていません。 
    これは、Unityのバージョンが理由なのでしょうか?
    現在使用しているのは、2020.3.8f1です。(機種はMac)

    よろしくお願いします。

  • #6

    kai (日曜日, 27 6月 2021 07:49)

    先ほど、HierarchyにあるGameManagerの方に、ClearMessage をアタッチした所正常に動きました!このやり方でも大丈夫なのでしょうか?

    初心者なのですみません。_(- _ - )_

  • #7

    Renoboy (日曜日, 27 6月 2021 10:46)

    kaiさん、ゲーム開発お疲れさまです。
    そのやり方でいいと思います。ちょっと説明足らずだったかもしれません。ごめんなさい。

    思ったとおりに動いてるのであればオーケーですよ!
    がんばろー!

  • #8

    kai (月曜日, 28 6月 2021 08:12)

    Renoboyさん
    早い返信有難うございます!
    ミニゲームの解説楽しみにお待ちしています♪

 

 

Profile

string name = "Renoboy";

string message = "《Unity,C#》に詳しくない私による、詳しくない人のためのチュートリアルです。詳しくないので、難しいことは決して教えません。";

 

Appale-Takemuroid