質問するログイン新規登録
Unity

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

Q&A

解決済

1回答

2092閲覧

UnityのRay.directionとRay.direction.normalizedの違いについて知りたい

unity_begin

総合スコア1

Unity

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

0グッド

0クリップ

投稿2021/08/09 08:43

0

0

前提・実現したいこと

UnityのRay.directionとRay.direction.normalizedの違いについて知りたい

Unityの教科書2018を参考にしてイガグリを的に当てるゲームを作成しています。

文中に 「directionベクトルの持つnormalized変数を使って長さ「1」のベクトルした後に、2000の力をかける」
という部分があるのですが、Ray.directionのリファレンスを見ると
Direction is always a normalized vector. If you assign a vector of non unit length, it will be normalized.
と記載があり、ray.directionをnormalizedしている意味が分かりません。

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

下記のソースコードでは、printで全く同じ値が出力されます。 この結果とUnityのリファレンスから ray.directionはもともと正規化されており、ray.direction.normalizedする必要は ないのでは?と思ってしまいます。

該当のソースコード

C#

1GameObject igaguri = Instantiate(igaguriPrefab) as GameObject; 2 3Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 4Vector3 worldDir = ray.direction; 5 6print("worldDir " + worldDir ); 7print("normalized " + worldDir.normalized ); 8 9igaguri.GetComponent<IgaguriController>().Shoot(worldDir.normalized * 2000);

試したこと

画面サイズを変えたり、カメラの位置を変えてみましたが、どのパターンも同じ結果でした。
またHPの正誤表も確認しましたが、特に記載はありませんでした。

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

Unity 2020 3.9f1

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

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

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

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

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

fiveHundred

2021/08/10 02:01 編集

念のためnormalizedを使っているだけだと思いますが、あくまで予想ですので、正確に知りたければ書いた本人に聞いてください。
unity_begin

2021/09/09 04:56

コメントありがとうございます。 なるほど、著者の方にもコンタクトを試みてみます!
guest

回答1

0

ベストアンサー

確かにUnityCsReference/Ray.cs at master · Unity-Technologies/UnityCsReference · GitHubによるとm_Directionは入力値を正規化してからセットしているようですので、ご質問者さんがお示しのリファレンスの文章はその通りかと思います。

あとはScreenPointToRayの方ですが、あいにくこちらは実際の処理はネイティブコードになっているようで詳細は分かりませんでした。処理内容によってはもしかすると正規化されないのかも...と思いまして、下記のようなスクリプトでカメラをガチャガチャ動かしてはScreenPointToRayを行い、directionの長さを調べてみたところ...

lang

1using System; 2using UnityEngine; 3using Random = UnityEngine.Random; 4 5public class ScreenPointToRayTest : MonoBehaviour 6{ 7 [SerializeField] private int testsPerFrame = 1024; 8 9 private Camera mainCamera; 10 private Transform mainCameraTransform; 11 private float width; 12 private float height; 13 private int n; 14 private double sqrDeltaSum1; 15 private double sqrDeltaSum2; 16 private double deltaMax1 = double.NegativeInfinity; 17 private double deltaMax2 = double.NegativeInfinity; 18 private double deltaMin1 = double.PositiveInfinity; 19 private double deltaMin2 = double.PositiveInfinity; 20 21 private void Start() 22 { 23 this.mainCamera = Camera.main; 24 this.mainCameraTransform = this.mainCamera.transform; 25 this.width = Screen.width; 26 this.height = Screen.height; 27 } 28 29 private void Update() 30 { 31 for (var i = 0; i < this.testsPerFrame; i++) 32 { 33 this.mainCamera.aspect = Random.Range(0.5f, 2.0f); 34 this.mainCamera.fieldOfView = Random.Range(30.0f, 60.0f); 35 this.mainCameraTransform.SetPositionAndRotation(Random.insideUnitSphere * 100.0f, Random.rotation); 36 var ray = this.mainCamera.ScreenPointToRay(new Vector3(Random.value * this.width, Random.value * this.height, 0.0f)); 37 var direction1 = ray.direction; 38 var delta1 = 1.0 - direction1.magnitude; 39 var direction2 = direction1.normalized; 40 var delta2 = 1.0 - direction2.magnitude; 41 this.sqrDeltaSum1 += delta1 * delta1; 42 this.sqrDeltaSum2 += delta2 * delta2; 43 this.deltaMax1 = Math.Max(delta1, this.deltaMax1); 44 this.deltaMax2 = Math.Max(delta2, this.deltaMax2); 45 this.deltaMin1 = Math.Min(delta1, this.deltaMin1); 46 this.deltaMin2 = Math.Min(delta2, this.deltaMin2); 47 } 48 this.n += this.testsPerFrame; 49 50 if (Input.GetKeyDown(KeyCode.Space)) 51 { 52 var sd1 = Math.Sqrt(this.sqrDeltaSum1 / (this.n - 1)); 53 var sd2 = Math.Sqrt(this.sqrDeltaSum2 / (this.n - 1)); 54 Debug.Log($"Test count: {this.n}"); 55 Debug.Log($"Max 1: {this.deltaMax1}, Min 1: {this.deltaMin1}"); 56 Debug.Log($"Max 2: {this.deltaMax2}, Min 2: {this.deltaMin2}"); 57 Debug.Log($"SD 1: {sd1}, SD 2: {sd2}"); 58 } 59 } 60}

下図のように、normalizedを行った方がごくわずかに長さが1に近づくようでした。

図

とはいえ、normalizedなしだと1より長くなる傾向がありそうだったものの、せいぜい10^-7の水準のズレしか観察されませんでした。Vector3型の各成分はfloat型ですが、floatにおいてはこの程度のズレは誤差の範疇として十分許容できるレベルかと思います。normalizedがなくても、おそらく問題ないんじゃないでしょうか。
どうしても気になるようでしたら、fiveHundredさんのおっしゃるように著者の方にお問い合わせいただくのがいいかと思います。もしかすると大きなズレが発生するようなケースをご存じで、それを回避するためにnormalizedを入れたのかもしれません。

投稿2021/08/10 21:31

Bongo

総合スコア10816

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

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

unity_begin

2021/09/09 04:55

初歩的な質問にも関わらず詳細な解説ありがとうございます。 とてもためになりました。 今後の参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問