確かにUnityCsReference/Ray.cs at master · Unity-Technologies/UnityCsReference · GitHub によるとm_Direction
は入力値を正規化してからセットしているようですので、ご質問者さんがお示しのリファレンスの文章はその通りかと思います。
あとはScreenPointToRay
の方ですが、あいにくこちらは実際の処理はネイティブコードになっているようで詳細は分かりませんでした。処理内容によってはもしかすると正規化されないのかも...と思いまして、下記のようなスクリプトでカメラをガチャガチャ動かしてはScreenPointToRay
を行い、direction
の長さを調べてみたところ...
lang
1 using System;
2 using UnityEngine;
3 using Random = UnityEngine.Random;
4
5 public 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
を入れたのかもしれません。