🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Unity

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

Q&A

解決済

1回答

2366閲覧

【Unity】CameraのClear Flagsを指定した間隔で切り替えたい

Mmeuniere

総合スコア9

C#

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

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Unity

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

0グッド

0クリップ

投稿2020/11/29 13:33

編集2020/11/29 13:40

UnityのCube(オブジェクト)を1ループにつきy軸で1度ずつCubeが回転するような動きを描画させています.そして10度毎にカメラ側のClear FlagsをDon't Clearの状態として深度バッファを更新させず,1度ずつの軌跡が上書きされていくような状態にしようとしています.そして10度移動すると今度はClear FlagsをSolid Colorの状態に一度切り替えて10度分の軌跡を消し,次の10度のループに入ると再び軌跡の描画が始まるようなものを想定しています.

現在,カメラ側のClear FlagsをCube側のScriptから変更する処理(BufferNotClear()やBufferClear()の呼び出し)は動作していることを個別に確認できました.
しかし,BufferNotClear()とBufferClear()をCube側のUpdate内の頭と終わりで切り替えようとしても終わり側に呼び出した関数側のClear Flagsのみが反映される状況です.例えば,以下のようにUpdate()の最後にBufferClear()を呼び出すとCubeの軌跡は残らずに表示されてしまいます.反対に,BufferNotClear()を最後に呼び出した場合は軌跡が10度ずつリフレッシュされることなく,何回転しても常に軌跡が消えない状態になります.

Debug.Log("bufferの更新中断");とDebug.Log("bufferの更新");は角度10度分がconsoleに表示される前後に表示されているので,いずれも呼び出し自体は出来ていそうなのですが,思うような描画の挙動になっていないため解決策に悩んでいます.

以下はCubeとカメラに取り付けているスクリプトです.

C#

1//オブジェクトのScript 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6 7public class TestObj : MonoBehaviour 8{ 9 10 GameObject MainCamera; //変数宣言 11 Camera cam; 12 13 void Start() 14 { 15 Application.targetFrameRate =10; //動作確認用に10fpsに固定 16 17 //ゲームオブジェクトMainCameraを見つけてMainCameraに格納 18 MainCamera = GameObject.FindGameObjectWithTag("MainCamera"); 19 cam = MainCamera.GetComponent<Camera>(); 20 } 21 22 void Update() 23 { 24  //Cambuffer.csのBufferNotClear関数を実行 25 MainCamera.GetComponent<Cambuffer>().BufferNotClear(); 26 27 for (float y = 1; y <= 10; ++y) 28 { 29 transform.Rotate(new Vector3(0, 1.0F, 0)); 30 float nowRotate = transform.localEulerAngles.y; 31 Debug.Log("今の角度は" + nowRotate); 32 } 33 34     //Cambuffer.csのBufferNotClear関数を実行 35 MainCamera.GetComponent<Cambuffer>().BufferClear(); 36 } 37 38} 39

C#

1//Main CameraのScript 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6 7public class Cambuffer : MonoBehaviour 8{ 9 10 Camera cam; 11 float color; 12 13 void Awake() 14 { 15 cam = GetComponent<Camera>(); 16 cam.clearFlags = CameraClearFlags.Nothing; 17 } 18 19 public void BufferNotClear() 20 { 21 //bufferの更新を止める 22 cam.clearFlags = CameraClearFlags.Nothing; 23 Debug.Log("bufferの更新中断"); 24 } 25 26 public void BufferClear() 27 { 28 //bufferの更新(SolidColorモードに一度戻すことで,オブジェクトの描画が更新の位置のものだけになることを期待) 29 cam.clearFlags = CameraClearFlags.SolidColor; 30 Debug.Log("bufferの更新"); 31 } 32}

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

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

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

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

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

guest

回答1

0

ベストアンサー

イベント関数の実行順序 - Unity マニュアル」をご覧いただきたいのですが、シーンのレンダリングはフローの下の方で行われています。
Update内でカメラのclearFlagsを切り替えてから即座に元に戻しても、実際にレンダリングのフェーズに到達したときにはカメラの状態は変わっていないことになりますので、うまくいかないだろうと思われます。

レンダリングに反映させるには1フレーム待機してやる必要があるでしょう。TestObjを下記のようにしてみるとどうでしょうか?

C#

1//オブジェクトのScript 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6 7public class TestObj : MonoBehaviour 8{ 9 // Startをコルーチン化する 10 IEnumerator Start() 11 { 12 Application.targetFrameRate = 10; //動作確認用に10fpsに固定 13 14 //ゲームオブジェクトMainCameraを見つけてmainCameraに格納 15 GameObject mainCamera = GameObject.FindGameObjectWithTag("MainCamera"); 16 17 // メインカメラからCambufferを取得しておき... 18 Cambuffer cambuffer = mainCamera.GetComponent<Cambuffer>(); 19 20 while (true) 21 { 22 // カメラをDon't Clear状態にして10回のループに突入する 23 cambuffer.BufferNotClear(); 24 for (int y = 1; y <= 10; ++y) 25 { 26 transform.Rotate(new Vector3(0, 1.0F, 0)); 27 float nowRotate = transform.localEulerAngles.y; 28 Debug.Log("今の角度は" + nowRotate); 29 30 // オブジェクトを回転後、1フレーム待機する 31 // ただし10回目に限りカメラをSolid Color状態に切り替えてから待機する 32 if (y == 10) 33 { 34 cambuffer.BufferClear(); 35 } 36 37 yield return null; 38 } 39 } 40 } 41}

投稿2020/11/29 15:36

Bongo

総合スコア10811

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

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

Mmeuniere

2020/11/30 04:40

>>実際にレンダリングのフェーズに到達したときにはカメラの状態は変わっていないことになりますので~ この内容については自分でもぼんやりと予想していたのですが,1フレーム待機するような記述の方法が見いだせずにいました. 実際にオブジェクト側へ提案していただいたスクリプトをアタッチしたところ,想定していた挙動となりました.ありがとうございます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問