FC2ブログ
    10 «1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.» 12

    ハルシオンシステムの気ままBlog

    株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

     

    【ハルシオンブログ】Prefabから複数Instantiateしてできたオブジェクトに●●したい時のやり方。とりあえず2パターンかいてみたけど、他にもいい方法ありますか? 

    こんにちは。坂内っす。

    Prefabを使ってInstantiateしたオブジェクトの管理について。

    1つのPrefabを使って複数のオブジェクトを作った際に、指定番号(生成した順)のオブジェクトに対してアクション(消したり、処理を行ったり)をする場合のやり方。

    デジゲーでお会いした杉田さんがこんなことをつぶやいていたので、ちょっと説明。


    もう解決はしているようだけども。

    いくつかやり方があると思うのですが、僕のやりかたを2つほど紹介。

    まずは、ただ単にImageのプレハブを5個Instantiateして並べるだけのプログラム。



    [Script20181126.cs]
    using UnityEngine;

    public class Script20181126 : MonoBehaviour {

    [SerializeField, HeaderAttribute("アイテムをおくところ")]
    private Transform itemsPlace;
    [SerializeField, HeaderAttribute("アイテムプレハブ")]
    private GameObject itemPref;

    float[] itemPosiX = {-300f,-150f,0f,150f,300f };

    private void Start() {
    for(int i = 0; i < itemPosiX.Length; i++) {
    GameObject item = Instantiate(itemPref, itemsPlace, false);
    item.transform.localPosition = new Vector2(itemPosiX[i], 0f);
    }
    }
    }


    これをベースにボタンを押したら、「1番目のオブジェクトを消す」「5番目のオブジェクトの色を変える」をやってみましょう。


    【オブジェクト名での管理】
    オブジェクトに名前(番号付き)を付けて大元から色々いじったりする。

    using UnityEngine;
    using UnityEngine.UI;

    public class Script20181126 : MonoBehaviour {

    [SerializeField, HeaderAttribute("アイテムをおくところ")]
    private Transform itemsPlace;
    [SerializeField, HeaderAttribute("アイテムプレハブ")]
    private GameObject itemPref;

    float[] itemPosiX = {-300f,-150f,0f,150f,300f };

    private void Start() {
    for(int i = 0; i < itemPosiX.Length; i++) {
    GameObject item = Instantiate(itemPref, itemsPlace, false);
    item.name = "item_" + i;
    item.transform.localPosition = new Vector2(itemPosiX[i], 0f);
    }
    }

    public void OnClickButton() {
    foreach(Transform itemTran in itemsPlace) {
    if(itemTran.gameObject.name == "item_0") {
    Destroy(itemTran.gameObject);
    }
    if(itemTran.gameObject.name == "item_4") {
    itemTran.gameObject.GetComponent<Image>().color = new Color(1f,1f,0f,1f);
    }

    }
    }
    }


    あ、もちろん次にやるようにオブジェクトの方で処理とかもできますが、なんか名前等の「Stringでの判定」ってあんまりやりたくないですよね。


    【オブジェクトにもスクリプトを用意する方法】
    番号で判定させるなら、文字列よりintとかで判断したい。(大文字小文字とかで合わなかったりをなくすため)
    そして、オブジェクトがあるならそれ用のスクリプトで処理とかしたい。
    そんなあなたへ。

    Item側を触るスクリプトを1つ追加します。


    [ScriptItem.cs]
    using UnityEngine;
    using UnityEngine.UI;

    public class ScriptItem : MonoBehaviour {
    private int itemNo;
    public int ItemNo
    {
    get{ return itemNo; }
    set{ itemNo = value; }
    }

    public void InitItem(int itemNo,float posiX) {
    this.itemNo = itemNo;
    transform.localPosition = new Vector2(posiX,0f);
    }

    public void DestroyItem() {
    Destroy(gameObject);
    }

    public void ChangeColor() {
    GetComponent<Image>().color = new Color(1f,1f,0f,1f);
    }
    }


    [Script20181126.cs]
    using UnityEngine;
    using UnityEngine.UI;

    public class Script20181126 : MonoBehaviour {

    [SerializeField, HeaderAttribute("アイテムをおくところ")]
    private Transform itemsPlace;
    [SerializeField, HeaderAttribute("アイテムプレハブ")]
    private GameObject itemPref;

    float[] itemPosiX = {-300f,-150f,0f,150f,300f };

    private void Start() {
    for(int i = 0; i < itemPosiX.Length; i++) {
    GameObject itemObject = Instantiate(itemPref, itemsPlace, false);
    ScriptItem item = itemObject.GetComponent<ScriptItem>();
    item.InitItem(i, itemPosiX[i]);

    }
    }

    public void OnClickButton() {
    foreach(Transform itemTran in itemsPlace) {
    ScriptItem item = itemTran.gameObject.GetComponent<ScriptItem>();
    if(item.ItemNo == 0) {
    item.DestroyItem();
    }
    if(item.ItemNo == 4) {
    item.ChangeColor();
    }

    }
    }
    }

    こっちの方がスッキリしますよね?

    ってことで、作ったオブジェクトへのアクションについてでした。あでゅ~ノシ

    ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
    2018/11/28 追記 コメントにより、最適解?

    [Script20181126.cs]
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class Script20181126 : MonoBehaviour {

    [SerializeField, HeaderAttribute("アイテムをおくところ")]
    private Transform itemsPlace;
    [SerializeField, HeaderAttribute("アイテムプレハブ")]
    private GameObject itemPref;

    private List<ScriptItem> itemList = new List<ScriptItem>();

    float[] itemPosiX = {-300f,-150f,0f,150f,300f };

    private void Start() {
    for(int i = 0; i < itemPosiX.Length; i++) {
    GameObject itemObject = Instantiate(itemPref, itemsPlace, false);
    ScriptItem item = itemObject.GetComponent<ScriptItem>();
    item.InitItem(i, itemPosiX[i]);
    itemList.Add(item);
    }
    }

    public void OnClickButton() {
    itemList[0].DestroyItem();
    itemList[4].ChangeColor();

    }
    }


    あ。たしかにいつもこうやってるわ。

    Category: 開発日記(Unity)

    tb 0 : cm 2