Physics.Raycastにつまった件が解決しました

UnityのPhysics.Raycastにつまった件。昨日の夕方以降ずっと悩んでおりましたが解決しました。
結論としては座標とベクトルの違いをちゃんと抑えておこうってことでした。

# UnityのPhysics.Raycast とは？
特定のベクトル方向に対して物体が存在するかを検証する機能です。
例えばOculusGoのコントローラに対して設定することでコントローラの指し示した先のオブジェクトの特定や
距離の測定などが可能となり、かなり利用率が高い機能だと思われます。


# 何が起こったか？

先ずは以下のコードをご覧ください

```RayCastSample.cs
    [SerializeField] private LineRenderer Laser;
    [SerializeField] private GameObject FoucusPoint;

	// Update is called once per frame
	void Update()
    {
        RaycastHit hit;
        var t = GetComponent<Transform>();
        var ray = new Ray(t.position, t.TransformDirection(Vector3.forward));
        if (Physics.Raycast(ray, out hit))
        {
            var target = ray.direction * hit.distance;

            // Debug 
            Debug.DrawRay(t.position, target, Color.red);

            Laser.SetPositions(new Vector3[] { t.position, target });
            FoucusPoint.SetActive(true);
            FoucusPoint.transform.position = target;

            Debug.Log("ray = " + ray);
            Debug.Log("start = " + t.position);
            Debug.Log("target = " + target);

            Debug.Log("Did Hit");
        }
    }

```

イメージとしてはレーザーを照射して当たった部分に突起ができるような状況を作ろうとしています。

ポイントはここです。

```
var target = ray.direction * hit.distance;
```
rayの方向ベクトルにhit迄の距離をかけ合わせてレーザーの接触点の座標をつくろうとしています。


上記の出力結果です。

<img width="836" alt="Unity_2018_1_0f2_Personal__64bit__-_SampleScene_unity_-_raycast_simple_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/fcb72d4b-e049-8563-af83-00e7c5ec90ec.png">

赤いボールがレーザーの発射口です。DrawRayは上手く描画できていますが、レーザーの照射方向に間違いがあります。
ログを確認してみます。
<img width="391" alt="Unity_2018_1_0f2_Personal__64bit__-_SampleScene_unity_-_raycast_simple_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/62f5180f-9050-b090-b88f-a966b222da45.png">

targetの想定座標が異なりました。Y軸の値が違います。
Debug.DrawRayは想定通りの挙動なのに、、、、、
そこでDebug.DrawRayの仕様を調べてみました。

<img width="1020" alt="Debug_DrawRay_-_Unity_スクリプトリファレンス.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/b555d769-7f43-5cb2-8189-d998740aa785.png">

やっちまいました。 Debug.DrawRay の第2引数は **座標ではなく方向ベクトルだった**のです。

先程の

```
var target = ray.direction * hit.distance;
```
**rayの方向ベクトルにhit迄の距離をかけ合わせてレーザーの接触点の座標をつくろうとしています。**
というのは

**間違いですね**

正解はこうです

```
var target = ray.orgin + ray.direction * hit.distance;
```
rayの方向ベクトルにhit迄の距離をかけ合わせても方向ベクトルができるだけで
**発射地点の座標**を足して初めてターゲットの座標が算出できます。

ちゃんと動くコードを書きます。

```RayCastSample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RaycastSample : MonoBehaviour
{

    [SerializeField] private LineRenderer Laser;
    [SerializeField] private GameObject FoucusPoint;

	
	// Update is called once per frame
	void Update()
    {
        RaycastHit hit;
        var t = GetComponent<Transform>();
        var ray = new Ray(t.position, t.TransformDirection(Vector3.forward));
        if (Physics.Raycast(ray, out hit))
        {
            var dir = ray.direction * hit.distance;
            var target = ray.origin + dir;
            // Debug 
            Debug.DrawRay(t.position, dir, Color.red);

            Laser.SetPositions(new Vector3[] { t.position, target });
            FoucusPoint.SetActive(true);
            FoucusPoint.transform.position = target;
            Debug.Log("Did Hit");
        }

    }
}

```

レンダリング結果

<img width="729" alt="Unity_2018_1_0f2_Personal__64bit__-_SampleScene_unity_-_raycast_simple_-_PC__Mac___Linux_Standalone__Personal___Metal_.png" src="https://qiita-image-store.s3.amazonaws.com/0/3844/fa07bb5a-1efe-66ac-eba6-3d7bf8f52192.png">


うまくいきました。

# 結論

座標なのかベクトルなのかちゃんと意識しよう。後マニュアルちゃんと読むべし