【Unity】ドラッグしたオブジェクトの複製

更新が遅くなりました。
オブジェクトの合成処理を作っていて、バグある事に気付いたのですが、
修正案がなかなか出なくて悩んでおりました(;-_-;) ウーム
余り参考にならないかもですが、順を追って説明していきます。

今回は、オブジェクト合成の前段階、オブジェクトの複製について
まとめたいと思います。

前回、マス目にハメる動作まで無事作る事ができました。

こうなるとタワーディフェンスなんかでもある、
オブジェクトの合成を作ってみたくなります。

同じオブジェクトを重ねてドロップするとレベルアップするやつです。

今は、大砲が各種一枚しか生成されてないので、
フィールドに出してしまうと予備が無い状態になります。

なので、大砲をドラッグして移動させた時に複製を作る処理を考えてみます。

単純にドラッグしたら複製するようにすれば良いのですが、
そうするとドラッグする度に複製されていく事になるので、
非常にまずい処理になります。

そこで、初期位置にセンサーを用意して、
大砲が離れたら感知できるようにしてみます。

まずセンサー替わりのオブジェクトを用意します。
ドロップ処理⑨.jpg
画像では分かりにくいのですが、
各種大砲の下にCellと言うオブジェクトを用意しました。

Cellは空のオブジェクトにBoxCollider2Dを載せます。
ドロップ処理⑱.jpg
Cellはセンサーなので、コラインダーのトリガーにチェックを入れます。
コラインダーのサイズは50×50くらいでいいかと。

続いて、大砲がセンサーにキャッチして貰えるように
ドロップ処理⑳.jpg
Rigidbody2DとBoxCollider2Dをアタッチします。

Rigidbodyはお馴染み、物理処理がいらないので、キネマティック使用に設定します。
コラインダーは、マス目ピッチの半分50×50に設定します。

これで大砲が感知できるので、
Cellのスクリプトを作成して、大砲が移動した時に複製を作るようにします。
CellScript

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

public class CellScript : MonoBehaviour
{
public GameObject cannonParent; //大砲Parent

//CellのColliderから大砲オブジェクトが出たら
private void OnTriggerExit2D(Collider2D collision)
{
//Cellの座標に大砲を複製する
GameObject Cannon = (GameObject)Instantiate(collision.gameObject);
Cannon.transform.SetParent(cannonParent.transform, false);
Cannon.transform.localPosition = this.transform.localPosition;
}
}

処理としては、センサーから外れたら複製するので、OnTriggerExit2Dを使います。
大砲の複製には、プレハブを使うのが常識なのですが、
大砲には、大砲Parentや設置フィールドのオブジェクトを取り込んでいるので、
プレハブ化した際、リンクが切れてしまいます。

生成時に再度、Findしなければいけない為、リソースを使うのでは?
と思いまして、直接大砲を複製する事にしました。

Unityの作法上は、複製はプレハブからが望ましいとあるので、
あまり行儀の良くない方法かもしれません。ヽ(´~`;)ウーン

複製の生成時に大砲Parentの子に指定して、
Cellの座標に複製すればOKでっす。

大砲とCellの座標を揃えてないと、違う位置に生成されるので注意です。

このスクリプトをCellにアタッチして、大砲Parentを変数にアタッチします。
ドロップ処理⑬.jpg
準備ができたのでPLAYしてみます。

おお~!?
えらい事になりました。

大砲をドラッグしてCellを通過すると複製されていきます。
種類もお構いなしでっす(T^T) ヒック

これは不味いので、ドラッグした大砲が通過しても複製ができないように
処理する必要があります。

センサーに種類を判別させるには、
オブジェクトNameやpublicな印があれば処理できますが、
簡単に処理が作れるタグで行きます。
ドロップ処理⑭.jpg
タグネームを追加します。

Cellに付ける○○base5種と、大砲に付ける○○Can5種を追加します。
分かり易い名前ならなんでもOKでっす。

まず、Cellのタグに各色別の○○baseを選択します。
続いて、大砲タグにも同じように○○baseのタグを付けます。
ドロップ処理⑮.jpg
白を例にすると、こんな感じになります。
各色のタグネームを付けていきます。

続いて、スクリプトを修正します。
CellScript

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

public class CellScript : MonoBehaviour
{
public GameObject cannonParent; //大砲Parent
public string tagname; //大砲のタグ名

//CellのColliderから大砲オブジェクトが出たら
private void OnTriggerExit2D(Collider2D collision)
{
//大砲とCellのタグが同じなら
if (collision.gameObject.tag == this.gameObject.tag)
{
//Cellの座標に大砲を複製する
GameObject Cannon = (GameObject)Instantiate(collision.gameObject);
Cannon.transform.SetParent(cannonParent.transform, false);
Cannon.transform.localPosition = this.transform.localPosition;

//外れた大砲のタグを書き換える
collision.gameObject.tag = tagname;
}
}
}

まず、Cellと大砲のタグネームが同じなら複製を作るようにします。
ドラッグした大砲が同じタグネームのままだと、上を通過しただけで複製されるので、
センサーから外れた所でタグネームを書き換えます。

public string tagnameにドラッグ後のタグネームを格納しておき、
センサーから外れた時に大砲のタグに代入してやれば、書き換えられます。

タグネームは、インスペクターで追加しないとスクリプトから書き換えが出来ません。
先に追加しておけば、忘れる事がないかと思います。
綴りや大文字・小文字が違っても書き換えが行われないので注意でっす。

あとは、CellScriptコンポーネントのtagname変数に
対応したNameを書き込んでおけば、ドラッグ時にタグを書き換えてくれます。
ドロップ処理㉑.jpg
Cell青ならBlueCan
Cell赤ならRedCan
残りも同じく…

準備ができたので、テストPLAYでっす。

ドラッグした大砲がCellを通過しても複製される事がなくなりました。

これで各種、初期大砲を準備できるので、フィールドに出しまくれます。(^.^; オホホホ

アイテムを変えれば、いろいろと使えそうですね~
複製については、以上となります。

次回は、問題の合成についてまとめてみます。
うまく説明できるといいのですが…

それでは、このへんで(o・・o)/~マタネェ

この記事へのコメント