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

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

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

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

Unity

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

Q&A

解決済

1回答

854閲覧

Unity C# Instantiateから処理が進まない

vora_shoya

総合スコア1

C#

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

Unity

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

0グッド

0クリップ

投稿2022/06/09 17:24

編集2022/06/11 01:28

C# VisualStudio2019

1.したいこと

UnityのResources内にjpgファイルが追加されると、Unity内でその画像のスプライトを生成してコライダーを付加したいです。
Timersを使用して10秒ごとに監視フォルダーのファイル数をカウントし、増えたファイル数だけスプライトを生成する処理が実行されます。

2.問題点

Instantiateclone()で処理を勝手に抜けてしまいます。
コンソールにはエラーメッセージも出てこないです。

3.ソースコード

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Timers; using System.Threading.Tasks; public class Watcher : MonoBehaviour { //監視するフォルダーパス string folderPath = @"C:\hoge"; public GameObject spriteprefub; int num = 0; List<int> lengthList = new List<int>(); float correction = 0.01f; void Start() { Timer timer = new Timer(10000); timer.Elapsed += (sender, e) => { num++; Task.Run(() => { getFilePath(num); }); Debug.Log(num); }; timer.Start(); } void getFilePath(int count) { string[] filePathArray = System.IO.Directory.GetFiles(folderPath, "*"); lengthList.Add(filePathArray.Length); if (filePathArray.Length > lengthList[count - 2]) { Debug.Log("Upload"); //新しく追加されたファイル数 int newFilenumber = filePathArray.Length - lengthList[count - 2]; getNewFilePath(newFilenumber); } } void getNewFilePath(int number) { Debug.Log("ok"); //ファイルが作成されると.metaも同時に作成されるため、/2回実行 for (int i = 1; i < number / 2 + 1; i++) { //Resources.Loadのためにアップロードされた画像のパスを取得、編集(Removeの数値は気にしないで) string[] fileList = System.IO.Directory.GetFiles(folderPath, "*"); string ppath = fileList[fileList.Length - 2 * i].Remove(0, 75); string path = ppath.Remove(ppath.Length - 4, 4); Debug.Log(path); //ここから勝手に抜けてしまう GameObject sprite = instantiateclone(); instantiateSprite(path, sprite); //↓は出力されない Debug.Log("スプライトが生成されました"); } } //プレハブを生成 GameObject instantiateclone() { GameObject clone = Instantiate(spriteprefub); return clone; } void instantiateSprite(string path, GameObject clone) { //スプライトを生成 Sprite newsprite = Resources.Load(path, typeof(Sprite)) as Sprite; SpriteRenderer sprite = clone.GetComponent<SpriteRenderer>(); sprite.sprite = newsprite; //画像のサイズをコライダーに反映 BoxCollider size = clone.GetComponent<BoxCollider>(); Texture2D texture = Resources.Load(path, typeof(Texture2D)) as Texture2D; size.size = new Vector3(texture.width * correction, texture.height * correction, 100); } }

4.自分でしてみたこと
10秒ごとに監視する処理とspriteを生成する処理が同じスレッドで起動しているのがいけないのかと思い、Threading.Tasksを使用して非同期処理を試してみましたが、それでも動かず。
Instantiateclone()をStartメソッドで書くと正常に動くため、コードに問題がある訳ではないと思います。またDebugで確認したところ、instantiate直前までは作動しているみたいです。ただ繋げてみると勝手に処理を抜けるようになってしまいます。
個人的にはパソコン側の処理の問題かなと思っているのですが、そこからの見当が全くつかない状態です。

5.質問

抽象的な質問で申し訳ないのですが、Instantiateが実行されない理由としてどのような事が想定されますでしょうか?
初心者で未熟なコードではございますが、ご回答宜しくお願い致します。

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

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

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

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

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

bboydaisuke

2022/06/09 23:40 編集

> Instantiateclone()で処理を勝手に抜けてしまいます。 「勝手に抜ける」の「勝手に」ってどういう意味ですか? コードを見るとそのメソッドはすぐ抜けるように書かれています。 > Instantiateから処理が進まない 「処理が進まない」と「勝手に抜ける」では意味が逆なようにも思えますが、実際は何が起きていますか?
vora_shoya

2022/06/10 05:10 編集

bboydaisuke様 ご質問ありがとうございます。 分かりにくい文章で申し訳ありません。 ファイルが追加されたら(if文が反応したら) getNewFilePath() → instantiateclone(), instantiateSprite() と進みたいのですが、getNewFilePath()内のDebug.Log(Path)以降の処理を実行してくれない という意味で「勝手に抜ける(抜け落ちる)」と表現しました。 ただ上記の不具合が発生した後でも10秒ごとに監視する処理は継続しているので、すべての処理が停止する訳ではないです。
YAmaGNZ

2022/06/10 05:23

「Debug.Log(Path)以降の処理を実行してくれない」というのは それ以降にDebug.Logを書いても出力されないと確認されてのことなのでしょうか? それとも実行はされているが結果が画面上に反映されていない(実は反映されているんだけど表示されない場所にオブジェクトがあるとか?)のでしょうか?
vora_shoya

2022/06/10 05:44

YamaGNZ様 ご質問ありがとうございます。 Debug.Log(Path)は出力されますが、それから後の処理が実行されません。なので「以降」という表現は不適切でした。申し訳ありません。 またヒエラルキー上にspriteprefubは生成されていないので、そもそも実行がされていないのかと思われます。
bboydaisuke

2022/06/10 06:16

プレハブを生成する行の直後にログを出力する処理を書いたら、それは出力されるのか?ということを聞いているんだと思いますよ。
vora_shoya

2022/06/10 06:29

bboydaisuke様 ご指摘ありがとうございます。 instantiateSprite(path, sprite)以降にDebug.Logを書いても出力されません。
guest

回答1

0

ベストアンサー

Timerクラスを用いて処理を呼び出したとき
その処理はワーカースレッドで処理されます。
つまりUnityAPIをTimerクラスのイベントで呼び出すことはできません。

引用元

ということだそうです。
引用元のページには回避方法が書かれていますが、そもそもUnityでTimerクラスを使うこと自体あまりないと思います。
この程度であればコルーチンで十分ですし、高度なことをやるにしてもUniTaskなど、他に選択肢は色々あります。

また、string folderPath = @"C:\hoge";とありますが、Resources以外のディレクトリのファイルをResources.Load()で呼び出すのは想定されていないので、やめておきましょう。

投稿2022/06/10 08:41

fiveHundred

総合スコア9778

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

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

vora_shoya

2022/06/10 16:28

ご回答ありがとうございます! ご指導頂いた通りコールチンを利用して再度試してみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問