質問するログイン新規登録
C#

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

Unity

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

Q&A

解決済

2回答

214閲覧

Unityで呼び出し先が変わる現象について

apa

総合スコア69

C#

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

Unity

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

0グッド

0クリップ

投稿2025/08/20 04:03

0

0

前提

C#

1 void Update() ← Controllerクラス 2 { 3... 4 RayCollisionGetTarget();

C#

1 2void Start() ← Managerクラス 3{ 4 FPSController Cont = Player.GetComponent<FPSController>(); 5 Cont.RayCollisionGetTarget(); 6 if(Cont.RayTargetGameObject != null) 7 { 8 Destroy(Cont.RayTargetGameObject); 9 }

しかしManagerクラスのCont.RayCollisionGetTarget();が呼ばれ処理を終えた後
if(Cont.RayTargetGameObject != null)にいかず(ブレークポイントが止まらない)
コントローラークラスのUpdateに呼び出し先が変わっていました。

※RayCollisionGetTarget()を抜けるまでは呼び出し先はManagerクラスになっております

使用IDE : visualstudio 2022

気になったこと

コントローラークラスのStartが呼ばれる前にManagerクラスのStartが呼ばれていたので
そこら辺もしかしたら関係があるのかなと思いましたが根本的に仕様の理解不足ですので
理解ある方いればご教授お願い致します。
(当方C++の経験しかありません)

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

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

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

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

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

YAmaGNZ

2025/08/20 04:51 編集

Managerクラスの5行目の Cont.RayCollisionGetTarget(); と6行目の if(Cont.RayTargetGameObject != null) にブレークポイントを設定して 5行目で停止した後F5で続行しても6行目で停止しないとおっしゃっていますか?
apa

2025/08/20 04:47

はいそうです
YAmaGNZ

2025/08/20 04:51

FPSController Cont = Player.GetComponent<FPSController>(); にてコンポーネントが取得できずContがnullとなっていて Cont.RayCollisionGetTarget(); が実行できずにエラーとなりStartを抜けているとか もしくはRayCollisionGetTargetで例外が発生しているとかありませんかね? 例外をcatchして確認するなりしてみてはどうでしょうか?
apa

2025/08/20 05:05

FPSController Cont = Player.GetComponent<FPSController>(); if (Cont != null) { Cont.RayCollisionGetTarget(); if (Cont.RayTargetGameObject != null) { Destroy(Cont.RayTargetGameObject); } } nullチェックを行いましたがnullではないようです。 記載したとおり関数も実行できております
YAmaGNZ

2025/08/20 05:44

Cont.RayCollisionGetTarget(); にブレークポイントを設定してステップ実行していっても if (Cont.RayTargetGameObject != null) にはたどり着かないんですかね? 念のためですが下記のように例外をcatchして確認してみてはどうでしょう? 私は呼び出し元の次の行にブレークポイントを設定したにも関わらず停止しないといった現象で思いつくのが例外時くらいしかないので・・・ void Start() { try { FPSController Cont = Player.GetComponent<FPSController>(); Cont.RayCollisionGetTarget(); if (Cont.RayTargetGameObject != null) { Destroy(Cont.RayTargetGameObject); } } catch (Exception ex) { Debug.Log(ex.Message); }
apa

2025/08/20 05:52

キャッチに入ってました 入ってる = 例外判定であってますよね? catch (Exception ex) { Debug.Log(ex.Message); } エラーメッセージから下記リンクをたどったところおそらく生成できていないことによる例外なのかなというところです https://csharpprogram.com/%e3%80%90c%e3%80%91nullreferenceexception%e3%81%ae%e5%af%be%e5%87%a6%e6%96%b9%e6%b3%95%e3%80%805%e3%81%a4%e3%81%ae%e4%ba%8b%e4%be%8b%e3%81%a8%e5%af%be%e5%87%a6%e6%96%b9%e6%b3%95%e3%82%92%e7%a2%ba/#%E3%82%B1%E3%83%BC%E3%82%B91_%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%8C%E3%81%BE%E3%81%A0%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84 これC++で遭遇したことないんですけど実行せずに抜けるなんてあるんですね 勉強不足でした。。。 catch = 例外という認識相似なければスレッド閉じたいと思います ご協力ありがとうございました
fiveHundred

2025/08/20 06:04

NullReferenceExceptionであれば、try・catchを使わずともUnityエディタ(VisualStudioではない)のConsoleに表示されるはずですが、確認はしましたか? (Unityの場合、エラーはVisualStudioに表示されず(Unityエディタに表示される)、また実行時の場合は中断もされません) > これC++で遭遇したことないんですけど実行せずに抜けるなんてあるんですね C++も例外やtry・catchはあるのでは?
apa

2025/08/20 10:23

C++も例外やtry・catchはあるのでは? ↑ありますよ ただ抜ける処理は今まで遭遇したことがありませんでした... (nullの時点で止まるので)
guest

回答2

0

ベストアンサー

例外=エラーといった認識でいいと思います。

例外が発生した場合、最寄りのcatchまで飛ばされます。
今回のように例外をcatchしていない場合はUnityシステム内の例外処理まで飛ばされます。
そしてUnityシステム内の例外処理にてエディタのログに例外内容が出力されるような処理となっています。
なので今回のように次の行のブレークポイントに引っかからずに抜ける動作となります。

もしRayCollisionGetTargetがControllerクラスのStartなどでの初期化が前提となっているのであればDefaultExecutionOrderでManagerクラスのStartよりControllerクラスのStartが早く呼ばれるようにすることも可能です。

C#

1[DefaultExecutionOrder(-1)] 2public class FPSController: MonoBehaviour 3{ 4 5}

DefaultExecutionOrderは0が標準で値が小さいほうが先に実行されます。
なので-1を設定しておけば標準よりは早く実行されます。

投稿2025/08/20 06:10

YAmaGNZ

総合スコア10688

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

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

0

言語仕様ではなく、Unityの仕様ですが、

Start():最初に一度だけ呼び出される関数
Update():毎フレーム呼び出される関数

となっています。
最初から存在しているオブジェクトはStart()→Update()の順に呼ばれ、(途中で生成されない限り)Update()の後にStart()が呼ばれることはありません。
別々のオブジェクト(クラス)の場合も、全てのStart()が終わった後に、Update()が行われます。

投稿2025/08/20 04:17

編集2025/08/20 04:19
fiveHundred

総合スコア10499

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

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

apa

2025/08/20 04:25

startが呼ばれる前に関数を呼ぼうとしているのがよろしくないという認識でしょうか? ただ呼び出した後でも呼び出し元に戻るのが一般的な挙動と考えておりますのでなぜ下記が呼ばれないのかが不思議ですね if(Cont.RayTargetGameObject != null)
fiveHundred

2025/08/20 05:19

最初にUpdate()が提示されていますが、Start()の前にUpdate()を呼び出したいと意図ではないのですか? というか、RayCollisionGetTarget()の処理が質問から読み取れませんね。 実はそちらの処理が正しくないとかも考えられますが、コードは提示できますか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問