前提・実現したいこと
実際にやりたい事としては、まず初めにParticleのすべての値を保持し、TimelineでClip再生中にParticleに変更を加え、Clipの再生が終了したタイミングで最初に保持した値に戻す。(例:再生前 startLifeTime = 1. 再生中 10, 再生後 1)
ということが実現したい事となります。
startLifeTimeだけ保持するのでなく、まるっとコンポーネントの値を保持したい理由はClipごとにどのような変化を行うは想定していないためです。
要はEditor上でCopy Componentすることをスクリプト上でやりたいのですが、Copy ComponentはEitorに依存しているので、仮にスクリプト上でCopy Componentが出来ても、出力後では使えなくなると思います。
なので、とりあえず最初にデフォルト値として保持しておきたいParticle Systemコンポーネントを別変数で複製し、そのあとにコピー元のParticle Systemの値を変更し、コピーした物を再度受け渡せば出来るんじゃないか。と思ったのですが、コピー元を変更するとコピーした方も値が変更されてしまっていてダメでした。
なにかコピー元に変更を加えてもコピー先も値が変更しないように保持する方法はありますでしょうか?
該当のソースコード
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; // A behaviour that is attached to a playable public class ControllParticleBehaviour : PlayableBehaviour { public GameObject particleObject{get; set;} public ParticleSystem particle; public ParticleSystem copyPV; public Transform playPos; public bool isPlayOfPlayback; public PostPlaybackEnum PostPlayback; public enum PostPlaybackEnum { Active, //クリップを抜けた後もアクティブにする NonActive, //クリップを抜けた後は非アクティブにする Delete, //クリップを抜けた後は対称を破棄する Revert //クリップを抜けた後は元の値に戻す } // クリップに入った時に走らせる処理 public override void OnBehaviourPlay(Playable playable, FrameData info) { if(particle != null) { copyPV = particle; Debug.Log(copyPV.main.startLifetime.constant); //particle の startLifetime が 「1」 だとして、ここでは copyPV の startLifetime はまだ 1 if(playPos != null) { particleObject.transform.position = playPos.position; } Debug.Log("Start"); particleObject.SetActive(true); ParticleSystem.MainModule par = particle.main; par.startLifetime = 10; Debug.Log(copyPV.main.startLifetime.constant + " / 2"); // ここですでに copyPV の startLifetime は 10 になっている particle.Play(); } } // クリップを抜ける際に走らせる処理 public override void OnBehaviourPause(Playable playable, FrameData info) { if(particle.isPlaying && PostPlayback == PostPlaybackEnum.Revert && copyPV != null) { Debug.Log("!"); particle = copyPV; //ここで particle の値を再生前の値に戻したい Debug.Log(copyPV.main.startLifetime.constant + " / 3"); } if(particle.isPlaying && PostPlayback == PostPlaybackEnum.NonActive) { Debug.Log("Stop"); particle.Clear(); particleObject.SetActive(false); } } }
#追記 2021/6/8 10:40
sakura_hana様のアドバイスに従ってInstantiateでparticleObjectを複製し、別物としてParticle Systemを保持し、これを後に変更した複製元に適用する。という方法を試したのですが、参照先に変更が適用されず、変数上で保持しているparticleには変更が適用されているという状態になってしまいます。
particleはparticleObjectにアタッチされているParticle Systemを参照しているのですが、なぜ変更が適用されないのか分からず困っています。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; public class ControllParticleBehaviour : PlayableBehaviour { public GameObject particleObject; public GameObject copyOB; public ParticleSystem particle; public ParticleSystem copyPV; public Transform playPos; public bool isPlayOfPlayback; public PostPlaybackEnum PostPlayback; public enum PostPlaybackEnum { Active, //クリップを抜けた後もアクティブにする NonActive, //クリップを抜けた後は非アクティブにする Delete, //クリップを抜けた後は対称を破棄する Revert //クリップを抜けた後は元の値に戻す } // クリップに入った時に走らせる処理 public override void OnBehaviourPlay(Playable playable, FrameData info) { if(particle != null) { Debug.Log("Start"); switch(PostPlayback) { case PostPlaybackEnum.Active: break; case PostPlaybackEnum.NonActive: break; case PostPlaybackEnum.Revert: copyOB = Object.Instantiate(particleObject); //別オブジェクトとして複製 copyPV = copyOB.GetComponent<ParticleSystem>(); //再生前の Particle System として保持 copyOB.SetActive(false); break; case PostPlaybackEnum.Delete: break; default: break; } if(playPos != null) { particleObject.transform.position = playPos.position; } particleObject.SetActive(true); ParticleSystem.MainModule par = particle.main; par.startLifetime = 10; Debug.Log(copyPV.main.startLifetime.constant + " / 2"); // copyPV の startLifetime は再生前の値(例として値は「1」とする)を保っている particle.Play(); } } // クリップを抜ける際に走らせる処理 public override void OnBehaviourPause(Playable playable, FrameData info) { if(particle.isPlaying && PostPlayback == PostPlaybackEnum.Revert && copyPV != null) { Debug.Log("!"); particle = copyPV; //ここで particleObject にアタッチされている Particle System の値を再生前の値に戻したい Debug.Log(copyPV.main.startLifetime.constant + " / Copy"); // 1 Debug.Log(particle.main.startLifetime.constant + " / Default"); // 1 Debug.Log(particleObject.GetComponent<ParticleSystem>().main.startLifetime.constant); // 10 ← particleObject の Particle System は paritcle とイコールなはずなのに、変更が適用されていない Object.Destroy(copyOB); } if(particle.isPlaying && PostPlayback == PostPlaybackEnum.NonActive) { Debug.Log("Stop"); particle.Clear(); particleObject.SetActive(false); } } }
回答1件
あなたの回答
tips
プレビュー