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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

2回答

1965閲覧

あるキーを押した後ドアが開きそのまま画面をフェードアウトさせたい(あるキーを押した瞬間の時間を取得したい)

toricotori

総合スコア14

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2017/12/14 16:54

タイトル通り、あるトリガー内で一定のキーを押すとドアが自動的に開き、画面がフェードアウトするというスクリプトを書いています。
http://tsubakit1.hateblo.jp/entry/2015/02/20/235021
こちらのページを参考に、ドアが開くアニメーションのスクリプトを作成したのですが、
ページによるとドア移動の開始時間(startTime)や経過時間(diff)に、シーン読み込み時からの時間(Time.timeSinceLevelLoad)を取得しており、シーン読み込み直後からのアニメーションに最適となっているようです。
この状態で一連の流れをプレビューすると、シーン読み込みした瞬間から見た移動指定時間(time)が経過した状態でトリガーの中に入り、一定のキーを押すと、すでに移動し終わった状態にパッと切り替わるようになってしまいます。移動指定時間内に間に合うと、初期位置から、パッと再生途中の移動アニメーションに切り替わります。
一定のキーが押された瞬間の時間を開始時間とすることができれば、キーを押す→ドアのアニメーションが再生される→フェードアウトが始まる、と理想の流れになると考えているのですが、なかなか思うように行きません(deltaTimeを使うのかと考えているのですが……)。
書き方が違うのか、考え方がそもそも違うのかなど、お力添えいただけますと幸いです。

一連の流れに使っているスクリプトは以下の通りです。

C#

1//ドアの移動アニメーション 2public class doorWork : MonoBehaviour 3{ 4 5 [SerializeField, Range(0, 10)] 6 float time = 1; 7 8 [SerializeField] 9 Vector3 endPosition; 10 11 [SerializeField] 12 AnimationCurve curve; 13 14 private float startTime; 15 private Vector3 startPosition; 16 17 void OnEnable () 18 { 19 if (time <= 0) 20 { 21 transform.localPosition = endPosition; 22 enabled = false; 23 return; 24 } 25 26 startTime = Time.timeSinceLevelLoad; 27 startPosition = transform.localPosition; 28 } 29 30 void Update () 31 { 32 if (toNextScene.openFlag == true) 33 { 34 var diff = Time.timeSinceLevelLoad - startTime; 35 if (diff > time) 36 { 37 transform.localPosition = endPosition; 38 enabled = false; 39 toNextScene.FOflag = true; //ドアが開ききったらフェードアウト(別スクリプト) 40 } 41 42 var rate = diff / time; 43 var pos = curve.Evaluate(rate); 44 45 transform.localPosition = Vector3.Lerp (startPosition, endPosition, pos); 46 } 47 } 48} 49

C#

1//一定範囲に入ってエンターキーを押すとドアが開いてフェードアウトする 2public class toNextScene : MonoBehaviour { 3 4 private Image panel; 5 float palpha; 6 float palphaSpeed = 0.02f; 7 8 public string nextScene; 9 10 public static bool FOflag; 11 public static bool openFlag; 12 13 void Start () 14 { 15 panel = GameObject.Find ("Panel_FO").GetComponent<Image> (); 16 palpha = 0.0f; 17 panel.color = new Color (0, 0, 0, palpha); 18 panel.enabled = false; 19 20 FOflag = false; 21 openFlag = false; 22 } 23 24 25 void Update () 26 { 27 if (FOflag == true) //ドアが開ききったらフェードアウト 28 { 29 panel.enabled = true; 30 palpha += palphaSpeed; 31 if (palpha > 1) 32 { 33 palpha = 1; 34 SceneManager.LoadScene (nextScene); 35 } 36 panel.color = new Color (0, 0, 0, palpha); 37 } 38 } 39 40 void OnTriggerStay(Collider col) //トリガー内でエンターキーを押すとドアが開き始める 41 { 42 if (col.gameObject.tag == "chara") 43 { 44 if (Input.GetKeyDown (KeyCode.Return)) 45 { 46 openFlag = true; 47 } 48 } 49 } 50}

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

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

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

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

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

guest

回答2

0

自己解決

startTimeの取得を、toNextSceneの、エンターキーを押した瞬間に行うようにしたところ、
押した後0からアニメーションの再生ができるようになりました。

投稿2017/12/15 05:42

toricotori

総合スコア14

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

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

0

startTimeは「アニメが開始する時間」を指します。
OnEnableは「このスクリプトがアクティブになった時」に呼ばれます。
元ソースはシーン読み込み直後にアニメ開始なのでこれでも問題無いです。

ではどうすればいいかというと、
つまりtoNextSceneのOnTriggerStay内openFlag = true;が呼ばれたタイミングで
現在OnEnable内にあるコードを実行をすればよいです。

ただしそうした場合、トリガー内でエンターキーを押す度にリスタート出来てしまう(=毎回startTimeが初期化される)ことになるので適宜条件分岐を挟んでください。

投稿2017/12/15 01:24

sakura_hana

総合スコア11427

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

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

toricotori

2017/12/15 05:21

ご回答ありがとうございます。 void OnEnable () {   startPosition = transform.localPosition;   if (toNextScene.openFlag == true)   {   if (time <= 0)   {   transform.localPosition = endPosition;   enabled = false;   return;   }   startTime = Time.timeSinceLevelLoad;   } } と書き換えたのですが、挙動が変わりませんでした。 (startPositionはopenFlagのいかんにかかわらず指定しておかないと動きが変になったのでif文の外に出しました。) たとえば移動にかける時間(time)を2にして、シーン開始から5秒経ってトリガー内でエンターキーを押すと、初期位置から、すでにアニメが2秒経った状態の位置(終点)に切り替わります。 また、移動にかける時間(time)を10にして、シーン開始から5秒経ってトリガー内でエンターキーを押すと、初期位置から、アニメ開始後5秒経った時点でいるはずの位置に切り替わり、そこから最後までアニメーションをします。
sakura_hana

2017/12/15 05:50

回答内にも書きましたが、OnEnableは「このスクリプトがアクティブになった時」に自動的に呼ばれる特別なメソッドです。 このメソッド内でstartTimeを設定している以上、挙動は変わりません。 (本当はOnEnableのタイミングでtoNextScene.openFlagがtrueなのはおかしいのでは?という気もしますが……) 根本的な修正としては、OnEnableを別の名前にして、openFlag = true;の「前」に呼び出してやれば動くと思います。 (回答では同じタイミングでと書きましたが、正確にはopenFlagがtrueになる前にstartTimeをセットしておかないと最初の1フレームが狂うかと思います)
sakura_hana

2017/12/15 05:51

コメント書いてる間に自己解決されていましたね。被りすみません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問