code VR

Unity×VR(63)

スポンサーリンク

//tips

//時間経過でのアイテム配布コード修正

うまく3つ目のスロットのみが読み込まれない問題が起きたので問題を確認していく。

問題の要因は、項目削除で発生するlistと配列のindexのズレにあるのではないかと考える。まずはデバッグで各要素の動きを終えるようにする。

Debug.Log("s1:"+slots[0].name); //Slot
Debug.Log("s2:" + slots[1].name);//Slot(1)
Debug.Log("s3:"+slots[2].name);//Slot(2)
Debug.Log("i1:" + inventorytest.items[0].name); //DIY
Debug.Log("i2:" + inventorytest.items[1].name);//Melon
Debug.Log("i3:" + inventorytest.items[2].name);//Sea

を挿入した。

最初に削除されたのがDIYで

i1:Melon
i2:Sea

その次にSeaが削除され、

i1:Melon

最後はMelonが削除されている。

3つ目だけButton button = slots[index].GetComponentInChildren<Button>();とbutton.interactable = true;のコードが反映されない要因を考える。

最後にinventorytest.items.RemoveAt(index);をされた時点でindexのリストそのものが一時消滅するためこのようなことが発生してしまうのではないかと考えるたが、slotの中身とリストの中身をもう少し照らし合わせてみる。

<リスト>
1.DIY
2.Melon
3.Sea

<Slot>
基本は slots[i].AddItem(inventoryTest.items[I]);なので
slot1.DIY
slot2.Melon
slot3.Sea
となる。

inventoryTest.items[I]でのslotへのitem割り当てはスタート時点しか呼ばれないので障害にはなっていない。最初にリストからslotに割り当てられ、その後のリストの変動をslot側では受けないためリスト項目が削除されても、slotのアイテム表示が消えることはない。

Debug.Log("index:" + index);を追加。

このindexが3回0となってしまった場合は、リストのアイテムはなくなるにもかかわらず、slotの表示はslot[0]の分のみしか消えない。これは、slotのindexが初期時点のリストのindexにしか対応していないことにより起こる。

なので、 Button button = slots[index].GetComponentInChildren<Button>();
の部分を修正する必要がある。

inventorytest.items[index].name =“”で分岐させれば良いので下記のメソッドを追加した。

void SlotManage(int index)
{
if (inventorytest.items[index].name == "Diy")
{
Button button = slots[0].GetComponentInChildren<Button>();
button.interactable = true;
}

if (inventorytest.items[index].name == "Melon")
{
Button button = slots[1].GetComponentInChildren<Button>();
button.interactable = true;
}

if (inventorytest.items[index].name == "Sea")
{
Button button = slots[2].GetComponentInChildren<Button>();
button.interactable = true;
}

}

2回目のメソッド試行時にSlotManage(int index)の読み込みが行われずエラー。

ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

4秒後に実行されたitem2Sea (Item)
TimeController:Item2() (at Assets/TimeController.cs:62)

不要なデバッグの削除とSlotManage(int index)内に起動されているかのチェックのデバッグ設置。

またリストから削除した後に名前の参照を行なっているのが問題かと思い

inventorytest.items.RemoveAt(index);

も移動。

また、inventorytest.items.RemoveAt(index);をしたすぐ後にはリストの値も変更され、異なる値を返すようになってしまうため、return;を入れて、そこでSlotManage(int index)の処理を終了させる。

最終的にスクリプトは下記かたちになった。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TimeController : MonoBehaviour
{
InventoryTest inventorytest;
Slot[] slots;
public Transform slotsParent;

void Start()
{
inventorytest = GetComponent<InventoryTest>();
slots = slotsParent.GetComponentsInChildren<Slot>();

Invoke("Item1", 3);
Invoke("Item2", 4);
Invoke("Item3", 5);
}

void Item1()
{
int index = Random.Range(0, inventorytest.items.Count); //int型なので最大値を含まない
Item item1 = inventorytest.items[index];
Debug.Log("index:" + index);

Debug.Log(inventorytest.items.Count);
Debug.Log("3秒後に実行されたitem1" + item1);
//inventorytest.items.RemoveAt(index);
//inventorytest.Remove(item1);

SlotManage(index);

//Button button = slots[index].GetComponentInChildren<Button>();
//button.interactable = true;

}

void Item2()
{
int index = Random.Range(0, inventorytest.items.Count);
Item item2 = inventorytest.items[index];
Debug.Log("index:" + index);

Debug.Log("4秒後に実行されたitem2" + item2);
//inventorytest.items.RemoveAt(index);
//inventorytest.Remove(item2);

SlotManage(index);

//Button button = slots[index].GetComponent<Button>();
//Button button = slots[index].GetComponentInChildren<Button>();
//button.interactable = true;

}

void Item3()
{
//int index = Random.Range(0, inventorytest.items.Count);
int index = 0;
Item item3 = inventorytest.items[index];
Debug.Log("index:" + index);

Debug.Log("5秒後に実行されたitem3" + item3);
//inventorytest.items.RemoveAt(index);
//inventorytest.Remove(item3);

SlotManage(index);

//Button button = slots[index].GetComponent<Button>();
//Button button = slots[index].GetComponentInChildren<Button>();
//Button button = slots[index].GetComponentInChildren<Button>();
//button.interactable = true;

/*
Debug.Log("i1:" + inventorytest.items[0].name);
Debug.Log("i2:" + inventorytest.items[1].name);
Debug.Log("i3:" + inventorytest.items[2].name);
Debug.Log("index:" + index);
*/

}

void SlotManage(int index)
{
Debug.Log("SlotManage");
Debug.Log(inventorytest.items[index].name);

if (inventorytest.items[index].name == "DIY")
{
Button button = slots[0].GetComponentInChildren<Button>();
button.interactable = true;

inventorytest.items.RemoveAt(index);
return;
}

if (inventorytest.items[index].name == "Melon")
{
Button button = slots[1].GetComponentInChildren<Button>();
button.interactable = true;

inventorytest.items.RemoveAt(index);
return;
}

if (inventorytest.items[index].name == "Sea")
{
Button button = slots[2].GetComponentInChildren<Button>();
button.interactable = true;

inventorytest.items.RemoveAt(index);
return;
}

}

ボタンのbutton.interactableを変化させる際にアイコンの表示色も明示的にしたい。

InventoryオブジェクトにアタッチしているTimeControllerスクリプト内に書くと孫オブジェクトの取得が非常に面倒になるので、slotに新たなスクリプトをアタッチし、そこでiconの色の表示変更を加えられるようにする。

一旦下記のスクリプトを作成し、slotオブジェクトにアタッチ。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ChangeColoricon : MonoBehaviour
{
[SerializeField]
GameObject icon;

Image image;
Color basecolor;

void Start()
{
Image image = icon.GetComponent<Image>();
basecolor = new Color(255.0f, 255.0f, 255.0f, 255.0f);

}

public void ChangeColor()
{
image.color = Color.red;
}

public void BackColor()
{
image.color = basecolor;
}
}

これを実行するとエラーが発生。

NullReferenceException: Object reference not set to an instance of an object
ChangeColoricon.ChangeColor () (at Assets/ChangeColoricon.cs:24)
image.color = Color.red;

TimeController.SlotManage (System.Int32 index) (at Assets/TimeController.cs:98)
changeColoricon.ChangeColor();

TimeController.Item2 () (at Assets/TimeController.cs:51)

Nullになっていないかデバッグで確認。
Debug.Log("changeColoricon"+changeColoricon);

public void ChangeColor()のimageが案の定nullになっていたので確認したら、Start()内のimageの前にImageがついており、image変数が二つあったのが問題になっていた。

人気の記事

1

コロナによる需要変化 コロナパンデミックの影響で、人々は外に出られなくなり、自宅で過ごす時間が増えました。 この自粛ムードの中、下記のようなビジネスの需要変化が引き起こされています。 【利用者減少】 ...

2

米国レストランの決済時に毎日お世話になっていた「Square」のビジネスモデルについて本日はふれていきたいと思います。 「Square」とは、ネットにつながったモバイル端末と専用のカードリーダーを用意 ...

3

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

4

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

5

ナイキのSNKRSが、なぜこれほどまでに人気なのか?調べてみました。 きっかけは米国での友達との会話。彼は自分のシューズをみせて、「これ20万円もしたんだぜ。」と語ってくれました。 あまり靴に興味がな ...

-code, VR
-,

Copyright© BUSINESS HACKER , 2021 All Rights Reserved Powered by AFFINGER5.