はじめに
unity初めて1ヶ月も経たない初心者です
この記事の知識を使うだけで以下のようなブロック崩しゲーム(2d)を作成することができます
unityで2dゲームを作る時、困った点として
・inspectなどGUI操作を解説してるサイトが少ない
・inspectでの設定とscriptでの設定の違いがあまりよくわからない
・3dゲームの解説は多いが、2dゲームは比較的少ないと感じた
・チュートリアルが英語(大体そうだけど、ほぼ動画なので復習などは面倒)
などがありました。
自分ような独学者かつ参考書買えない貧金な者はチュートリアルやサイトを見ることで勉強しているので、特にGUI操作に困りました…
なのでGUI操作を中心に備忘録を作りたいと思いました。
自分用の備忘録として作ったので、分かりにくかったり、コード任せな説明が多めですが、少しでも誰かの参考になれたらと思い載せました。
もちろん他の(もっと良い)方法もあると思います。
細かく書きすぎるとアップデートで名称が変わったりするので、概念的な部分を書くようにしています。
目次
何かしらの現実の物体を作りたい時
重力を変えたい
衝突判定
衝突の挙動がおかしい時
キーを押して動かしたい時
壁や地面を作りたい時
大量に湧いては消えるようなものを作る時
ブロックの監視など
選択ボタンを作って押したら何かする
個数を表示する
シーンの遷移方法
シーン間での値の受け渡し(前画面に戻る時に使える)
何かしらの現実の物体を作りたい時
左タブのHierarchyからcreate,spriteを選択し、形(circleなど)を選択(オブジェクト作成という)
Hierarchyからオブジェクトを選択し、右タブのinspectからAdd componentでRigid Body 2dを選択(Rigid bodyでも動く)
重力を変えたい
Rigid body 2D のgravity scaleから変更
衝突判定
〜colliderで、衝突判定
scriptで、衝突時の反射などを変える
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Bar"))
{
Vector2 direction = (transform.position - collision.transform.position).normalized;
Bounce(direction);
}
else if (collision.gameObject.CompareTag("Wall"))
{
Vector2 reflection = Vector2.Reflect(previousVelocity.normalized, collision.contacts[0].normal);
rb.velocity = reflection.normalized * previousVelocity.magnitude;
}
else if (collision.gameObject.CompareTag("Block"))
{
Destroy(collision.gameObject); // ブロックを削除する
BlockManager.Instance.DecreaseBlockCount(); // ブロックの残り個数を減らす
Vector2 direction = (transform.position - collision.transform.position).normalized;
Bounce(direction);
}
}
具体的なコードは以下を参照(自分のコード)
https://github.com/sakai1250/Block_KUZUSHI_unity/tree/main/tetris%2FAssets%2FScripts
衝突の挙動がおかしい時
Rigid body 2dのfrictionや、bounceを変える
(変えるには、下タブのAsset内でmaterialを作る)
キーを押して動かしたい時
private void Update()
{
float moveHorizontal = Input.GetAxis("Horizontal");
Vector2 movement = new Vector2(moveHorizontal, 0f) * moveSpeed;
rb.velocity = movement;
if (Input.GetKeyDown(KeyCode.Space))
{
ResetBar();
}
}
壁や地面を作りたい時
Hierarchyのcreate tilemapを押す
Add componentからtilemap colliderを追加
window,2d,tile palleteを選択
事前に画像をAssetに取り込み、pixel 64にしておく
その画像(sprite)をtile palleteにドラッグし、あとは上のスポイトマークでタイルを選択、絵の具マークを選択し、塗る
tilemap colliderだと衝突挙動が変なので、辺り判定のコードは以下を参照(自分のコード)
https://github.com/sakai1250/Block_KUZUSHI_unity/tree/main/tetris%2FAssets%2FScripts
大量に湧いては消えるようなものを作る時
プレファブ化すれば良い
プレファブ化するには、作ったオブジェクトをAssetにドラッグする(青くなる)
タグも付けてしまえば、大量発生して名前が(block(2))とかになっても、同じblockというタグとして衝突判定などができる
ブロックの監視など、個数がゼロになってしまうものの監視
Hierarchyからcreate emptyにより、空のオブジェクトを作成、個数監視のscriptをアタッチすることで可能
選択ボタンを作って押したら何かする
Hierarchyからcanvas,UI,buttonを選択
inspectから、onclick()の+ボタンを押し、オブジェクトをアタッチする(scriptでは無いことに注意する→オブジェクトにscriptをアタッチしておく)
no functionから自作関数を選択
個数を表示する
Hierarchyからcanvas,UI,textを選択
個数scriptをアタッチ
private void Start()
{
blockCount = GameObject.FindGameObjectsWithTag("Block").Length; // ブロックの初期個数を取得する
UpdateBlockCountText();
}
public void DecreaseBlockCount()
{
blockCount--;
UpdateBlockCountText();
if (blockCount <= 0)
ResetLevel();
}
private void UpdateBlockCountText()
{
blockCountText.text = "Blocks: " + blockCount.ToString();
}
以下を参照(自分のコード)
https://github.com/sakai1250/Block_KUZUSHI_unity/tree/main/tetris%2FAssets%2FScripts
text mesh proだと、コードの書き方が少し異なるので注意(コード参照)
シーンの遷移方法
file,new sceneを選択(saveしておく)
file,build settingsで、scene(〜.unity)をAdd scenesの場所にドラッグしておく
ボタンを押すと遷移するには、ボタンのscriptにて
scene managerを使うことで、簡単に実装可能
public void LoadStage1()
{
SceneManager.LoadScene("Stage1");
}
(コード参照)
シーン間での値の受け渡し
(前画面に戻る時に使える)
public static classを使い、現在のシーンでの値を記憶させることで可能
以下を参照(自分のコード)
https://github.com/sakai1250/Block_KUZUSHI_unity/tree/main/tetris%2FAssets%2FScripts
public static class PreviousScene
{
public static string previousScene = SceneManager.GetActiveScene().name;
}
public class GoResume : MonoBehaviour
{
private bool goResume = false;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
goResume = true;
PreviousScene.previousScene = SceneManager.GetActiveScene().name;
}
}
private void FixedUpdate()
{
if (goResume)
{
goResume = false;
SceneManager.LoadScene("Resume");
}
}
}
public class Resume : MonoBehaviour
{
public void LoadTitle()
{
SceneManager.LoadScene("Title");
}
public void LoadStage()
{
SceneManager.LoadScene(PreviousScene.previousScene);
// SceneManager.LoadScene("Stage1");
Debug.Log(PreviousScene.previousScene);
}
}
基本的操作はできるようになったので、今度はオリジナルゲームを作成したいと思っています。