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

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

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

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

Unity

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

Q&A

解決済

4回答

488閲覧

【Unity C#】if (isA != newIsA) をどこに入れるべきか分かりません。

catdoglion

総合スコア1

C#

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

Unity

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

0グッド

0クリップ

投稿2021/06/24 02:55

例えばこんなようなメソッドがあったとします。
「引数 newIsAisA を比較、異なる場合は代入し、その値に応じて処理をする」という感じのものです。

C#

1void ToggleIsA(bool newIsA) { 2  if (isA != newIsA) { 3    isA = newIsA; 4   5    if (isA) { 6      Debug.Log("Aになりました!"); 7    } else { 8      Debug.Log("Aではなくなりました!"); 9    } 10  } 11   12}

そしてこのメソッドを毎フレーム実行するとします。
例えば、レイが当たっている間は ToggleIsA(true); 、当たっていない間は ToggleIsA(false); を実行するとします。

これで期待する動作はするのですが、
レイが当たっている間、ずーっと ToggleIsA(true); が実行されているのが気持ち悪いので、
メソッドを呼ぶ部分にこのようなif分を追加します。

「レイが当たっているのに isA == false なら ToggleIsA(true); 、当たっていないのに isA == true なら ToggleIsA(false); 」という感じです。

C#

1//レイが当たっている間 2if (isA == false) { 3  ToggleIsA(true); 4} 5 6//レイが当たっていない間 7if (isA == true) { 8  ToggleIsA(false); 9}

でもそうすると、 ToggleIsAメソッド の、この部分が必要なくなります。

C#

1void ToggleIsA(bool newIsA) { 2  if (isA != newIsA) { //←◆◆◆ココ◆◆◆ 3    isA = newIsA; 4   5    if (isA) { 6      Debug.Log("Aになりました!"); 7    } else { 8      Debug.Log("Aではなくなりました!"); 9    } 10  } 11   12}

というような感じで、
要はif (isA != newIsA)をどこに入れるべきなのかを悩んでおります。

選択肢としては、
0. メソッドを呼ぶ部分メソッド内の両方に入れる

  1. メソッドを呼ぶ部分のみに入れる
  2. メソッド内のみに入れる
  3. そのほかのやり方?

私の今の感覚としては、先ほども書いた通り、3の場合は毎フレームToggleIsA(bool newIsA)が実行されるのが気持ち悪く、また処理速度的な観点からも重くならないのかな?と思っているのですが、かと言ってメソッドを呼ぶ部分に必要、となると、「そのメソッドを使うときの決まり事」が増えて残念とも思います。

ご教授いただければ幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

こんにちは。

感覚に関する質問ということで、個人的な感覚で回答しますが、
これは単に ToggleIsA という名前が良くない気がします。
結局やっていることは「引数に渡した値で IsA を上書きする (ただし既に同じ値のときはなにもしない)」なので、
例えばこれを SetIsA(bool newValue) などとすれば、呼び出し側で毎フレーム実行しても違和感はなくなるものと思います。
こうすることで、呼び出し側では毎フレーム新しい値をセットする、呼ばれた側では値が変化した場合のみ何かをする、とそれぞれの担当範囲が分かれるので、この場合では質問の選択肢「3」が適当になります。

なお、質問のコード例では名前付けが意味を持っていないのでこのような回答になりますが、メソッドの名前によっては「呼ぶ側が呼ぶかどうか考えなければならない」ことにもなるので、全ては名前付け次第です。
「書いて読んで違和感がない」ことはとても重要なプログラミングの要素なのです。

投稿2021/06/24 03:15

tamoto

総合スコア4252

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

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

catdoglion

2021/06/24 03:32

ご回答いただきありがとうございます。 なるほど! もろもろ、すごくなるほど!となりました。 ひとつお聞きしたいのですが、 この 「SetIsAメソッドが毎フレーム呼び出される」という点について、 処理速度的に重くなったりということはないでしょうか? 毎フレーム呼び出された結果実行されるのが「if文での値比較のみ」ならば気にすることはないでしょうか? また、メソッドが別のスクリプトにある場合、それの参照に負荷がかかるとか、そんなようなこともいかがでしょうか。 もちろんケースバイケースで、具体的にすみずみまで確認しないと明言はできないと思いますので、「可能性はある」というような曖昧な表現でも大丈夫です。 これも肌感覚といいますか、印象でお答えいただけると嬉しいです。 よろしくお願いいたします。
tamoto

2021/06/24 03:46 編集

メソッド呼び出し一つ程度なら誤差未満なので気にしなくて良いです。 特に、質問のコードは入った直後引数をチェックして条件を満たさなければ即終了するので、この場合メソッド呼び出し分のコストはゼロと想定しても問題ないでしょう。
guest

0

ベストアンサー

「IsAをプロパティとして実装すること」と「IsAプロパティ変更をイベントとして抽出すること」が出来ると良さそうですね。

private bool _isA; public bool IsA { // IsAプロパティのgetter get => _isA; // IsAプロパティのsetter set { // 値が異なる場合だけ if (_isA != value) { // 値の変更を適応し _isA = value; // 変更時の処理を呼び出す IsAPropertyChanged(_isA); } } } // IsAが変更された時だけ呼び出される処理 private void IsAPropertyChanged(bool isA) { if (isA) { Debug.Log("Aになりました!"); } else { Debug.Log("Aではなくなりました!"); } }

ここで if (isA != newIsA) に該当するのは setter内の if (_isA != value) です。

プロパティのsetterが定義されている場合、代入演算子(=)によってプロパティのsetterが呼び出されて、変数の書き換え処理をカスタマイズできます。詳しくは以下のリンクを確認してみてください。

プロパティ(C#プログラミング入門) - 未確認飛行 C

実利用時としても

IsA = true; or IsA = false;

とするだけでIsAプロパティのsetterが呼ばれて 値が異なる場合だけ変更を受け付け、変更があった時だけIsAPropertyChanged(_isA);が呼ばれます。

投稿2021/06/24 03:36

tor4kichi

総合スコア769

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

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

catdoglion

2021/06/24 22:18

丁寧にご回答いただきありがとうございます。 まったく知らなかったやり方で、先ほど試したところとても綺麗にできました。 リンクも貼っていただきありがとうございます。リンク先ページの説明もすごく分かりやすかったです。 ありがとうございます m( _ _ )m ご回答をくださった他の皆様も本当にありがとうございます。 特に命名の部分はあまり考えずしていた節があり、ご回答によって気づくことができました。 ありがとうございました m( _ _ )m
guest

0

個人的にToggleIsA(bool newIsA)のメソッド名と引数がすごく気になります。

Toggleって名前だと、スイッチを切り替えるように、値の変化は担保された上で切り替わるようなイメージがあります。
引数で明示的に値をセットするなら、Set~~みたいな名前かなと思いましたが。どうでしょうか。

選択肢に関しては3が良いかと思います
呼び出し側で色々やるより、メソッド側で処理させるのが良いでしょう。折角メソッドで分離しているのに呼び出す側で色々制約をかけなきゃいけないのは、非常にめんどくさいです。

もちろん明確な理由があるなら呼び出し側で弾くのもありです。

投稿2021/06/24 03:32

hogefugapiyo

総合スコア3302

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

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

0

そういうのはあなた自身が、それぞれいろいろやってみて、あなた自身が都合がいい方にすればいいです。

あなたのいう「気持ち悪い」のは各人それぞれ違いますんで、他の誰かのいうことを聞いたところで解決はしないかと。

投稿2021/06/24 03:13

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問