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

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

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

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

Unity

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

Q&A

2回答

4169閲覧

C#: シンボルの定義に付いて

t_s

総合スコア50

C#

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

Unity

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

0グッド

0クリップ

投稿2017/07/31 17:02

編集2022/01/12 10:55

Unityを使用しており、シンボルの定義についてわからないことがあるので質問です。

まず、やりたいことはUnityで定義されているシンボルを#ifで判定し、定義されていたら追加で独自のシンボルを定義することです。

C#

1#if UNITY_EDITOR 2#define MY_DEFINE 3#endif 4 5using UnityEngine; 6using System.Diagnostics; 7 8class Foo : MonoBehaviour 9{ 10 private void Start() 11 { 12 FooOutput(); 13 } 14 15 [Conditional("MY_DEFINE")] 16 private void FooOutput() 17 { 18 UnityEngine.Debug.Log("Foo"); 19 } 20}

以上でFooが出力されてくれれば良いのですが、コンソールには出力されません。

そこで、他のファイルに冒頭の三行を書き、二箇所で判定を行ったところ、Fooがコンソールに出力されるようになりました。

以下が再現を行えるファイルになります。

Foo.cs

C#

1#if UNITY_EDITOR 2#define MY_DEFINE 3#endif 4 5using UnityEngine; 6using System.Diagnostics; 7 8class Foo : MonoBehaviour 9{ 10 private void Start() 11 { 12 FooOutput(); 13 } 14 15 [Conditional("MY_DEFINE")] 16 private void FooOutput() 17 { 18 UnityEngine.Debug.Log("Foo"); 19 } 20}

Hoge.cs

C#

1#if UNITY_EDITOR 2#define MY_DEFINE 3#endif 4 5using UnityEngine; 6 7class Hoge : MonoBehaviour 8{ 9 private void Start() 10 { 11 12 } 13}

以上の二つのファイルを、シーンに配置されている空のゲームオブジェクトに両方共アタッチし、実行するとなぜかコンソールにFooが出力されます。

これが特に理解不能で、この時一箇所での判定だけではFooが出力されず、二箇所でなら出力される理由を御存知の方は回答いただけると助かります。

なお、Conditionalではなく、#if-endifでメソッドの呼び出しを区切った場合、打って変わってコンソールにFooが出力されます。
以下が#if-elseで区切ったケースになります。

C#

1#if UNITY_EDITOR 2#define MY_DEFINE 3#endif 4 5using UnityEngine; 6 7class Foo : MonoBehaviour 8{ 9 private void Start() 10 { 11 #if MY_DEGINE 12 FooOutput(); 13 #endif 14 } 15 16 private void FooOutput() 17 { 18 Debug.Log("Foo"); 19 } 20}

以上、ご存知の方いましたら、何卒よろしくお願いします。

●実行環境
Windows10
Unity 5.6.2f1
VisualStudio2017

####2017/08/01:質問文の不備に関して修正、追記
●実行環境を追記しました
●コードの記述ミスを修正
●二箇所で判定を行う件について、検証したファイルを記述していなかったので追記
●Conditionalではなく#if-endifで検証したコードを追記

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

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

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

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

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

guest

回答2

0

私のUnityは5.6.2f1なのですが、ご質問者さんのコードでFooと表示されました(おそらく打ち間違いかと思いますが、MonoBihaviourMonoBehaviourに、public Start()public void Start()に、また曖昧さの解決のためDebug.Log("Foo");UnityEngine.Debug.Log("Foo");に修正して実行しました。それ以外は同じです)。
Unity 5.5でご質問者さんと同様の現象に言及している方がいらっしゃるようですが(Conditional attribute ignores #defines in 5.5 | Unity Community)、もしUnityのバージョンが古い場合は、アップデートすると改善されますでしょうか?

投稿2017/08/01 13:23

編集2017/08/01 13:29
Bongo

総合スコア10807

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

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

t_s

2017/08/01 13:50

粗雑な質問文で申し訳ないです。実際のコードをコピペしたわけではなく、直で書いたもので、かなり抜けている部分がありました。後ほど修正しておきます。 本題ですが、質問するまでの間色々と検証しており、文中のようなコンパイルの通らないコードで試したわけではないので、コードの記述ミスでは無いと思っています。 また、Unityのバージョンは5.6.2f1を使用しており、VisualStudio2017を使用しています。 先程改めて実行してみましたが、依然として状況に変化はありませんでした。 このあと質問文の修正とともに、現在問題の発生しているコードを追記しますので、もし都合が良ければ引き続きよろしくお願いします。
Bongo

2017/08/02 22:09

Unity 5.6.2f1・Windows 10 Home(バージョン1703)・Visual Studio Community 2017(バージョン15.2)の場合と、Unity 5.6.2f1・macOS Sierra(バージョン10.12.6)・MonoDevelop(バージョン5.9.6、Mono JIT compilerバージョン2.6.5)の場合で試しましたが、いずれでも再現させられませんでした(新規にプロジェクトを作って、追記いただいたスクリプトのうち最初のConditionalを使うFoo.csだけを空のゲームオブジェクトに単独でアタッチし実行しても、コンソールにFooが表示されてしまいます)。 いまいち発生条件がつかめずやっかいですね... 古い内容ですが、https://gist.github.com/kimsama/4123043のソースコードコメント中にも、カスタム定義のシンボルがConditionalで正しく動かないようなことが書かれておりました。これに対する2016年のコメントで、「[Conditional("CUSTOM_CONDITION"), Conditional("UNITY_EDITOR")]」とすると動いたとの報告がありますが、これもなぜそういう挙動になるのか理解しがたいです... この際、#defineで定義したシンボルについてはConditionalを使うのは諦めて、#if〜#endif方式に書き換えてしまうべきかもしれません。
t_s

2017/08/03 14:37

こうなってくると、C#やUnityではなく自分の作業環境に何か問題があるかもしれませんね。 かといってこのようなややこしい自体を招くような構築の仕方はしていないので皆目検討もつきません・・・
guest

0

#define (C# リファレンス) | Microsoft Docs
に以下のことが書いてあります。

define で定義されたシンボルのスコープは、そのシンボルが定義されたファイル内だけです。

したがって載せていただいたコード上にUNITY_EDITORが定義されていないので、#define MY_DEFINEの行は通ってなさそうです。

以下の話をもっと詳しく説明できますか?

他のファイルに冒頭の三行を書き、二箇所で判定を行ったところ、Fooがコンソールに出力されるようになりました。

投稿2017/08/01 12:44

K_S_

総合スコア419

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

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

t_s

2017/08/01 13:56

自分もdefineのスコープの範囲についてはリファレンスを読み知っていたつもりではあったのですが、今回質問した経緯のひとつに「Conditionalだと実行されないが#if-endifで区切る分には実行される」という現象が発生しており、結局理解が及ばず質問した次第です。 また、この件について質問文に記載しておらず、すみませんでした。 投稿時大分混乱していまして、質問内容に多々不備がありお恥ずかしい限りです。 後ほど、質問文の修正と一緒に「冒頭の三行を~~」の詳細を追記しますので、都合がよろしければ引き続きよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問