質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

3100閲覧

[Unity]プレハブをインスタンス化したの際の、レイヤーを常に手前に配置したい

skycamo

総合スコア13

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2019/09/03 03:51

前提・実現したいこと

・Unityの2Dにて、画面をタップしたらタップした場所にプレハブを作成するアプリのようなものを作っています(イメージは画面をタップした場所にシールを張っていく感じです)
・プレハブは5種類ほどあり、想定通りタップするごとにプレハブが作成されています。
・しかし、シール貼りのように、新しく作成したプレハブが一番手前のレイヤーにならず、前に作成したプレハブの下に隠れたりしてしまいます(シールを貼る際のように、一番最新に貼ったものを一番手前のレイヤーに表示したいです)
・スクリプト側からレイヤーを常に最新になるように制御できないでしょうか。

発生している問題・エラーメッセージ

・プレハブを作成できてはいるものの、レイヤーが順番通りになっておらず、最新に作成したプレハブが過去に作成したプレハブの下に潜ってしまっている。

該当のソースコード

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

public class ItemGeneratorScript : MonoBehaviour{

public GameObject AnpanmanPrefab; public GameObject CheesePrefab; public GameObject BaikinmanPrefab; public GameObject ShokupanmanPrefab; public GameObject CurrypanPrefab; public GameObject DokinchanPrefab; private Vector3 clickPosition; private int counter; [SerializeField] SortingGroup sortingGroup; void Start() { } void Update() { if (Input.GetMouseButtonDown(0)) { if (counter < 50) { counter++; } else { SceneManager.LoadScene("GameScene"); } clickPosition = Input.mousePosition; var number = UnityEngine.Random.Range(1,7); if (number == 1) { Instantiate(AnpanmanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), AnpanmanPrefab.transform.rotation); } else if(number == 2) { Instantiate(CheesePrefab, Camera.main.ScreenToWorldPoint(clickPosition), CheesePrefab.transform.rotation); } else if(number == 3) { Instantiate(BaikinmanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), BaikinmanPrefab.transform.rotation); } else if(number == 4) { Instantiate(ShokupanmanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), ShokupanmanPrefab.transform.rotation); //Debug.Log("53行目"); } else if(number==5) { Instantiate(CurrypanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), CurrypanPrefab.transform.rotation); } else if(number==6) { Instantiate(DokinchanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), DokinchanPrefab.transform.rotation); } } }

}

試したこと

・[SerializeField] SortingGroup sortingGroup;

private void Update () { // 何かキーを押す if ( Input.anyKeyDown ) { sortingGroup.sortingOrder = 10;

上記のようなことをしてみてもダメでした。

・また、

Instantiate(AnpanmanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), AnpanmanPrefab.transform.rotation);
AnpanmanPrefab.GetComponent<SpriteRenderer>().sortingLayerName = SortingLayerName;
AnpanmanPrefab.GetComponent<SpriteRenderer>().sortingOrder = SortingOrder;

ということをしてもダメでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

GetComponent<SpriteRenderer>()sortingOrderで解決できそうです。

また、Prefab ではなく、実際にインスタンス化したほうのオブジェクトに変更を加えてあげる必要があります。GameObject型の変数でインスタンス化したオブジェクトを一旦受け取って、それを変更してあげると良いでしょう。(もちろんvarで受け取ってもOKです)

cs

1 2// インスタンス化したオブジェクトへの参照が obj に入る 3var obj = Instantiate(AnpanmanPrefab, Camera.main.ScreenToWorldPoint(clickPosition), AnpanmanPrefab.transform.rotation); 4// インスタンス化したオブジェクトのSortingOrderをカウンターの値にする(新しいものが数値が大きい) 5obj.GetComponent<SpriteRenderer>().sortingOrder = counter; 6

ソースを見る感じだと画像を作るメソッドをわけて、配列からランダムにPrefabを選ぶというアプローチでも良さそうです。

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5 6public class Test : MonoBehaviour { 7 8 [SerializeField] GameObject[] imagePrefabs; 9 private int counter; 10 11 void Update() { 12 if (Input.GetMouseButtonDown(0)) { 13 var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition); 14 pos.z = 0; // カメラ位置調整用 15 CreateImage(pos); 16 } 17 } 18 19 private void CreateImage(Vector3 pos) { 20 var _prefab = imagePrefabs[Random.Range(0,imagePrefabs.Length)]; 21 var newObj = Instantiate(_prefab,pos, _prefab.transform.rotation); 22 newObj.GetComponent<SpriteRenderer>().sortingOrder = counter; 23 counter++; 24 } 25 26} 27

投稿2019/09/03 04:04

編集2019/09/03 04:17
hogefugapiyo

総合スコア3302

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

skycamo

2019/09/03 04:18

回答ありがとうございます! 早速試してみたところ、想定通りにできました!! 本当にありがとうございます!! もしよろしければ教えていただきたいのですが、変更前のInstantiate~…ではなく、オブジェクトを一度受け取る(var obj=Instantiate~…)必要があったのはなぜでしょうか。 想定通り動いていますので、ご教授いただいたスクリプトで問題ないのですが、私の勉強不足で難しく…
hogefugapiyo

2019/09/03 04:55

いじりたいのはインスタンス化して作られた「後」のオブジェクトなので、そいつを特定したいです。 なので、作成する段階で作ったオブジェクトがわかるように変数で参照を確保してことでその後の作業をスムーズに進めるという感じです。 参照さえ取れてれば基本的に何でもできるので、たとえばこの例だと貼ったときにサイズもランダムに変わるとかも簡単につくれます。(newObj のスケールをいじってあげればOKです)
skycamo

2019/09/03 05:19

ご丁寧にありがとうございます。 確かに、質問をする前に試行錯誤していたところ、GameObject型とint型で型違い、などのエラーが出ておりました。 こういったことを避けるために一度オブジェクトを受け取る必要があるのですね。 サイズの変更もできるのは面白そうです!試してみます!
hogefugapiyo

2019/09/03 05:26

var型はローカル変数などで使われることが多いのですが、型推論と呼ばれて自動的に適切な型を判断してくれます。今回の場合は、インスタンス化したあとのオブジェクトって結局GameObject型なのでvarとは書いていますが、GameObjectとして受け取っています。 var obj = Instantiate ~ ↓ varくん(右辺はGameObject型っぽいから、GameObject型で受け取りましょうか) GameObject obj = Instantiate ~ コードがスッキリして個人的にはよく使うのでお好みにあわせて調べてご利用いただければと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問