はじめに
現在Unityの2Dゲームのチュートリアルを色々触っている段階の初心者です。今回は初心者ながらコードをいじることができたのでそれを紹介します。
とはいっても中のコードだけ変えたので最終的な処理自体は変えて無いのですが...()
では早速いきます
今回いじらせていただいたコードはこちらから: https://unity.moon-bear.com/category/puzzle-game/
注意点
まだ初心者かつ目的を達成することに意識を向けたせいでめちゃくちゃ冗長になっていたりツッコミどころ満載のコード and 解説になっていると思いますがご了承ください。
(まあこれを見に来る人はほぼゼロだと思うのでね...())
今回やったこと
「プレハブ(LightButton)につけていた処理をLights(Grid Layout Group)に移行」です。
これを思いついたのはLightButton.csのコードではlightObjects[i, j]のインデックスはi, jそれぞれそのまま取得していましたが1次元配列のindexとして取得して戻す方法を試してみたかっただけです。
え?やる意味だろって?
...学習のためなので許して(あとこの処理は競プロでやったことあったからというのもある)
なお以下のファイルはLightPanelManager.csとしていますがこれはチュートリアル記事でいうところのLights(Gird Layout GroupコンポーネントをアタッチしたCanvas内のオブジェクト)に該当します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LightPanelManager : MonoBehaviour
{
[SerializeField] UniLightsMain main;
//イベントハンドラーを登録
public void AssignButtonClickHandlers(GameObject parent)
{
foreach (Transform child in parent.transform)
{
Button button = child.GetComponent<Button>();
if (button != null)
{
button.onClick.AddListener(() => OnButtonClick(child.gameObject));
}
}
Debug.Log("イベントハンドラー登録完了");
}
private void OnButtonClick(GameObject buttonObject)
{
//Debug.Log($"Clicked Button: {buttonObject.name}");
// ここでボタンオブジェクトを使用可能
GameObject child = buttonObject; // 対象の要素
int index = child.transform.GetSiblingIndex();
Debug.Log($"Index: {index}");
Debug.Log("index / main.nowMapSize(equals to row): " + index / main.nowMapSize);
Debug.Log("index % main.nowMapSize(equals to col): " + index % main.nowMapSize);
//main.SwitchLights(row, col, CreateMode);
main.SwitchLights(index / main.nowMapSize, index % main.nowMapSize, false);
}
}
nowMapSizeという変数を追加しています。これは元々のファイルの下記のように修正しているためです。
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
public class UniLightsMain : MonoBehaviour
{
[SerializeField] int minSize = 3;
[SerializeField] int maxSize = 9;
public int nowMapSize; //変数を追加
[SerializeField] int randomCount = 5;
[SerializeField] GameObject lightPrefab;
[SerializeField] Transform lightParent;
[SerializeField] GameObject lightPanelManager; //冗長にはなるが追加
[SerializeField] GridLayoutGroup grid;
[SerializeField] Color onButtonColor;
[SerializeField] Color onButtonHighlightedColor;
[SerializeField] Color offButtonColor;
[SerializeField] Color offButtonHighlightedColor;
[SerializeField] Text clearText;
//以下チュートリアル同様の処理が続きます
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SizeDropdown : MonoBehaviour
{
[SerializeField] UniLightsMain main; //UniLightsMain.csで管理するために追加
Dropdown dropdown;
private int mapSize; //新たに追加
void Start()
{
dropdown = GetComponent<Dropdown>();
OnValueChanged();
}
public void OnValueChanged()
{
mapSize = dropdown.value + 4; //マジックナンバーなのは4x4スタートのため
main.ClearLights();
main.CreateLights(mapSize);
main.nowMapSize = mapSize;
}
}
1次元配列から縦横の長さが等しい2次元配列においては1次元配列の要素番号をiとしたときに変換するとi ÷ (長さの商), i ÷ (長さの余り)...⓵になることを利用しています。
indexに関してはそれぞれのLightPanelは子要素に該当するのでchild.transform.GetSiblingIndex()で取得できこれを⓵にあてはめています。
なお、UniLightsMain.csでのlightPanelManagerの宣言は上記でTransformを取得しているので明らかに冗長です。参考にしたい人は頑張って直してください。