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

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

詳細はこちら
C#

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

Unity3D

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

Unity

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

Q&A

解決済

1回答

2885閲覧

【Unity】オブジェクトをfloat*Time.deltaTimeで反復動作させると徐々にズレをなくしたい

Y0241-N

総合スコア1066

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2019/09/20 05:06

現状・改善したいこと

タイトル通り、オブジェクトをfloat*Time.deltaTimeで反復動作で左右に動かしているのですが、
恐らく、floatの仕様のせいで若干の誤差が発生し、その分が徐々に積み重なってズレが生じています。

このズレをなくしたいのですが、入力値にMathf.Clampで制限をかけたり、
ネットで調べて出てきたfloatをMathf.Roundで*100した値を切り捨てたのち、/100する
という方法も試してみたのですが、うまくいきませんでした。

他にも、反復のタイミングをずらしてみたり、色々試しましたが、思うようにいかなかった為
質問させていただきました。

制限の方法や、もしくは別の方法で動かすなどでも構いません、回答お待ちしております。

現状の様子

分かりやすくするために、掛け率を0.01から0.1にしています
イメージ説明

該当のソースコード

cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class MoveCursors : MonoBehaviour 6{ 7 private Vector3 Pos; 8 float x; 9 float y; 10 void Start() 11 { 12 Pos = transform.position; 13 x = 0; 14 y = 0; 15 } 16 17 void Update() 18 { 19 this.transform.rotation = Quaternion.Euler(0, 0, 0); 20 21 if(y == 0) 22 { 23 x += 0.1f *Time.deltaTime; 24 Pos.x += x; 25 transform.position = Pos; 26 Debug.Log("+ : " + x); 27 28 if(x >= 0.01) 29 { 30 y = 1; 31 } 32 } 33 34 if(y == 1) 35 { 36 x -= 0.1f *Time.deltaTime; 37 Pos.x -= x; 38 transform.position = Pos; 39 Debug.Log("- : " + x); 40 41 if(x <= -0.01) 42 { 43 y = 0; 44 } 45 } 46 } 47} 48

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

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

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

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

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

guest

回答1

0

ベストアンサー

これはfloatの誤差によるずれではありません

y=1 にしたあとすぐにif(y==1)の部分を通るのに対し、
y=0 にしたあとは、if(y==0)の部分を通らないのが原因です

とはいえ、floatの誤差が起きうるのは事実ですので、
中心を保存しておき、それを左右に動かす方式にするのがいいと思います

Vector3 origin; void Start(){ origin = transform.position; } void Update(){ // gapを左右に動かす transform.position = origin + new Vector3(gap, 0f, 0f); }

投稿2019/09/20 05:27

izmktr

総合スコア2856

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

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

Y0241-N

2019/09/20 07:45

y=1 にしたあとすぐにif(y==1)の部分を通るのに対し、 y=0 にしたあとは、if(y==0)の部分を通らないのが原因です とのことですが、コンソールを見ていただければわかるのですが、Debug.Log("+ : " + x);の内容が表示されているので、if(y==0)の部分はきちんと循環処理されていると思います。 あと中心を基準に左右に動かすというアイデアはよいなと思ったのですが、 試しに以下のように動かしてみましたが、結局ズレてしまいました... transform.position = Origin + new Vector3(x,0,0); if(transform.position == Origin) { x += 0.1f *Time.deltaTime; } if(transform.position.x == Origin.x + 0.01f) { x -= 0.1f *Time.deltaTime; } if(transform.position.x == Origin.x - 0.01f) { x += 0.1f *Time.deltaTime; }
izmktr

2019/09/20 08:20

if (y ==1) を else に書き換えてみましょう 浮動小数点においては、原則的に==を使ってはいけません そういう意味ですでに間違っています もう面倒だから、これで良くないですか? x += Time.deltaTime; transform.position = Origin + new Vector3(Math.Sin(x), 0, 0);
Y0241-N

2019/09/20 09:04

こちらの勉強不足でお手数をおかけして申し訳ありません、勉強になりました。 ありがとうございます。 最後にもう一点伺いたいのですが、Mathf.Sin(x)で制限して-1~1の値で返ってきた数値を -0.5~0.5などに制限することはできるのでしょうか? Mathf.Clampで制限してみたところ、効果がなかったので、他の方法があればと思い、お伺いさせていただきます。
izmktr

2019/09/20 09:07

掛け算しましょう
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問