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

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

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

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

Unity3D

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

Q&A

解決済

2回答

839閲覧

UnityでLerpを使ってオブジェクトを往復させたい

BEGINER

総合スコア2

C#

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

Unity3D

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

0グッド

0クリップ

投稿2023/04/20 08:42

自動ドアに応用したくてLerpを用いたプログラミングをしました。
座標AからBまで進み、Bとの距離が十分小さくなったらAに向かって進む、を繰り返すスクリプトを書いたつもりでしたが、Bで止まってしまって困っています。
原因を教えていただければ自分で考えて直してみます。

以下はその動画とスクリプトです。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class AutoDoorOpen : MonoBehaviour 6{ 7 8 public Transform startLocation;//開始位置のTransform 9 public Transform endLocation;//終了位置のTransform 10 public float moveSpeed = 50.0f;//開くときの移動速度 11 public float reverseMoveSpeed = -50.0f;//閉まるときの移動速度 12 public float purposeDistance = 1.0f;//ドアと目的地の距離 13 14 private float startTime;//開始時間 15 private float journeyLength;//移動距離 16 17 18 // Start is called before the first frame update 19 void Start() 20 { 21 //移動に必要な距離を計算 22 journeyLength = Vector3.Distance(startLocation.position, endLocation.position); 23 24 } 25 26 // Update is called once per frame 27 void Update() 28 { 29 //ドアの位置を取得 30 Vector3 currentPosition = transform.position; 31 32 //ドアの位置がstartLocation付近にあるなら(Mathf.Absで絶対値に直す) 33 if (Mathf.Abs(Vector3.Distance(currentPosition, startLocation.position)) < purposeDistance) 34 { 35 //移動した距離を計算 36 float distCovered = (Time.time - startTime) * moveSpeed; 37 38 //現在の位置をLerpで求める 39 float fracJourney = distCovered / journeyLength; 40 transform.position = Vector3.Lerp(startLocation.position, endLocation.position, fracJourney); 41 42 //開始時間を更新 43 startTime = Time.time; 44 } 45 46 //ドアの位置がendLocation付近にあるなら 47 else if (Mathf.Abs(Vector3.Distance(currentPosition, endLocation.position)) < purposeDistance) 48 { 49 //移動した距離を計算 50 float distCovered = (Time.time - startTime) * reverseMoveSpeed; 51 52 //現在の位置をLerpで求める 53 float fracJourney = distCovered / journeyLength; 54 transform.position = Vector3.Lerp(startLocation.position, endLocation.position, fracJourney); 55 56 //開始時間を更新 57 startTime = Time.time; 58 } 59 60 } 61}

https://youtu.be/uABdwOfPF20

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

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

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

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

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

guest

回答2

0

ベストアンサー

コードを見る限りそのような動作はしないと思っていたのですが、もしかすると startLocation はこの AutoDoorOpenTransform と同じなのではないですか?

よく考えてみてください。
startLocationendLocation の間を行き来するプログラムですが、その startLocationendLocation にだんだん近づいていくのです。
そりゃ、最終的に startLocationendLocation がほぼ同じ位置になって、動かなくなるでしょう。

他にも、色々と気になる点はあります。

Update の中の条件式は「startLocation付近だったら」「endLocation付近だったら」
となっていますが、「それ以外」は?

endLocation 付近の場合、Vector3.Lerp の第3引数である fracJourney は負の値になりそうですが、Vector3.Lerp の中で0から1にクランプされるので、常に0を渡していることと同様になります。
そもそも、lerpの動作を考えると、負であること自体間違いでは?という気がします。

とりあえず、このプログラムがどのような動作になるか、しっかり見直してみてください。

投稿2023/04/21 00:19

編集2023/04/21 01:03
katsuko

総合スコア3471

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

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

0

AIにも手伝ってもらって解決まで至りました。
「startLocation が endLocation にだんだん近づいてしまっている」という指摘からstartLocationとendLocationにはこのスクリプトがアタッチされるオブジェクト以外のオブジェクトを2つ割り当てることで解決しました。
「それ以外」にも対応できるように、if (fracJourney >= 1.0f)に条件を変更しました。
また、boolを用いて、startLocationとendLocationの区別がつくように変更しました。
回答ありがとうございました。
以下は解決後のコードです。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class AutoDoorOpen : MonoBehaviour 6{ 7 public Transform startLocation; 8 public Transform endLocation; 9 public float speed = 1.0f; 10 11 private float startTime; 12 private float journeyLength; 13 private bool isMovingToEnd = true; 14 15 private void Start() 16 { 17 startTime = Time.time; 18 journeyLength = Vector3.Distance(startLocation.position, endLocation.position); 19 } 20 21 private void Update() 22 { 23 float distCovered = (Time.time - startTime) * speed; 24 float fracJourney = distCovered / journeyLength; 25 26 if (isMovingToEnd) 27 { 28 transform.position = Vector3.Lerp(startLocation.position, endLocation.position, fracJourney); 29 if (fracJourney >= 1.0f) 30 { 31 isMovingToEnd = false; 32 startTime = Time.time; 33 } 34 } 35 else 36 { 37 transform.position = Vector3.Lerp(endLocation.position, startLocation.position, fracJourney); 38 if (fracJourney >= 1.0f) 39 { 40 isMovingToEnd = true; 41 startTime = Time.time; 42 } 43 } 44 } 45} 46

投稿2023/04/21 03:11

BEGINER

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問