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

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

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

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

Unity

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

Q&A

解決済

1回答

1165閲覧

Rigidbodyによる移動の制御について

sanshi5

総合スコア18

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/06/08 02:40

編集2020/06/08 06:08

前提・実現したいこと

Rigidbodyで目的ポイントまで、上下に永続的に動く床(上と下で2秒停止付)

(コルーチンで制御する方法を一個前の質問で教えていただきました。その流れでの質問です。)

発生している問題・エラーメッセージ

上下にPingPongするものや、目的のポイントまで動くのまでは機能しましたが 床を一定時間止めて、また逆方向に動いたりをどう 書けばいいかというところで詰まってます。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class coltin : MonoBehaviour 6{ 7 8 private Rigidbody rb; 9 public float speed = 1.0f; 10 public Vector3 direction = new Vector3(0f, 5f, 0f); 11 12 void Start() 13 { 14 rb = GetComponent<Rigidbody>(); 15 // コルーチン開始 16 StartCoroutine("ChangePsition"); 17 } 18 19 20 // ポジション変更 21 IEnumerator ChangePsition() 22 { 23 yield return new WaitForSeconds(2); 24 Debug.Log("2秒"); 25 26 while (true) 27 { 28 float step = speed * Time.deltaTime; 29 rb.MovePosition(Vector3.MoveTowards(transform.position, direction, step)); 30 yield return null; 31 //1フレーム待つ 32 } 33 } 34}

現状だと上にあがったままなので、元の位置にもどり
上と下それぞれ2秒停止しエレベータのように
動かせないかコードを考えています。

試したこと

C#

1using UnityEngine; 2using System.Collections; 3 4public class rigiido : MonoBehaviour 5{ 6 7 private Rigidbody rigid; 8 private Vector3 defaultPos; 9 10 void Start() 11 { 12 rigid = GetComponent<Rigidbody>(); 13 defaultPos = transform.position; 14 } 15 16 void FixedUpdate() 17 { 18 rigid.MovePosition(new Vector3(defaultPos.x, defaultPos.y + Mathf.PingPong(Time.time,5), defaultPos.z)); 19 } 20}

これだと上下し続けてくれますが、任意の場所で
任意の秒数を止めたりができない感じです。

###自己進展があったので追記します。

using System.Collections; using System.Collections.Generic; using UnityEngine; public class coltin : MonoBehaviour { private Rigidbody rb; public float speed = 1.0f; public Vector3 direction = new Vector3(0f, 5f, 0f); void Start() { rb = GetComponent<Rigidbody>(); // コルーチン開始 StartCoroutine("ChangePsition"); } // ポジション変更 IEnumerator ChangePsition() { yield return new WaitForSeconds(2); Debug.Log("2秒"); while (transform.position.y < 5) { float step = speed * Time.deltaTime; rb.MovePosition(Vector3.MoveTowards(transform.position, direction, step)); yield return null; //1フレーム待つ } //もう一つのコルーチンを実行する StartCoroutine("ChangePsition2"); } IEnumerator ChangePsition2() { yield return new WaitForSeconds(2); Debug.Log("2秒"); while (transform.position.y > 0.5) { float step = speed * Time.deltaTime; rb.MovePosition(Vector3.MoveTowards(transform.position, -direction, step)); yield return null; } //もう一つのコルーチンを実行する StartCoroutine("ChangePsition"); } }

これでとりあえず目的の動きがしてる感じがしますが、動作をランニングテストしてます。
while 条件の数値を手入力してるので、public Vector3 direction = new Vector3(0f, 5f, 0f);を自動で入るようにしたほうがいいのか検討中。
もっといい方法や何かアドバイスあればよろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

Unity2019.2.9f1

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

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

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

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

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

guest

回答1

0

ベストアンサー

2点間を移動して端に来たら一定時間停止するということですね。
スクリプトを変更せずに後から移動前,移動先,移動時間,停止時間,移動対象を変更できるよう実装しました。
(このスクリプトをアタッチした上で他のオブジェクトを用意したりインスペクタから設定する必要があります。)

Vector3.Lerpなどは2点間の補完にも使えて便利なので覚えておくとよいかと思います。
https://docs.unity3d.com/ja/current/ScriptReference/Vector3.Lerp.html

C#

1using UnityEngine; 2 3public class Escalator : MonoBehaviour 4{ 5 [SerializeField] private Transform from; // 移動前のロケータ(空のGameObjectなどを配置) 6 [SerializeField] private Transform to; // 移動後のロケータ(空のGameObjectなどを配置) 7 [SerializeField] private float duration; // from,to間の移動にかかる時間 (≠速度) 8 [SerializeField] private float wait; // 端に到達した後停止する時間 9 [SerializeField] private Rigidbody target; // 動かす対象のRigidBody 10 11 enum Direction 12 { 13 FORWARD, 14 BACKWORD, 15 WAIT 16 } 17 private Direction direction; 18 private Direction pastDirection; 19 private float time; 20 21 private void Awake() 22 { 23 direction = Direction.FORWARD; 24 time = 0; 25 } 26 27 private void Update() 28 { 29 time += Time.deltaTime; 30 31 if (direction == Direction.WAIT) 32 { 33 if (wait <= time) 34 { 35 time = 0f; 36 direction = pastDirection == Direction.FORWARD ? 37 Direction.BACKWORD : 38 Direction.FORWARD; 39 } 40 return; 41 } 42 43 if (direction == Direction.FORWARD) 44 { 45 target.MovePosition(Vector3.Lerp(from.position, to.position, time / duration)); 46 } 47 else 48 { 49 target.MovePosition(Vector3.Lerp(to.position, from.position, time / duration)); 50 } 51 52 if (duration <= time) 53 { 54 time = 0f; 55 pastDirection = direction; 56 direction = Direction.WAIT; 57 } 58 } 59}

投稿2020/06/08 06:24

編集2020/06/08 06:54
uskey512

総合スコア144

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

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

sanshi5

2020/06/08 06:52

ありがとうございます。試してみました。 インスペクターで必要な要素を調節ができてとても便利です。 このようなアプローチの仕方もあるんですね。 Vector3.Lerp色々調べてみます。 大変参考になりました。 ありがとうございました。
sanshi5

2020/06/08 06:59

修正箇所確認いたしました。
sanshi5

2020/06/08 20:45

ありがとうございます。itween使ったことあります。 空にUFOを飛ばすようなパスアニメーションにちょうど使ってました。 今回はキャラクターを載せて上下するエレベータを作りたくてRigidbodyで動かすのが必要でした。 animationで動かすと制御は簡単ですがキャラが乗ったときガタガタするので、itweenでもできそうか試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問