【UE】テレポート（壁は通り抜けるが、マップからは出ない）の作り方

:::note info
この記事はUE Blueprint初心者が書いたものです。コードは冗長である可能性が高いです。
より簡潔に作ることができそうであれば教えていただけると、とても嬉しいです。
適当Englishも優しい目で見逃してもらえると嬉しいです。
:::
2023/4/1 Macro : PutKey_to_vectorが複数回発動してしまっていた問題を修正
# テレポートの仕様と完成品
テレポートキー（`IA_Teleport`）を押すと`EnhancedInput IA_Teleport_Direction`で設定されたAxis3D (Vector)で得た方向にテレポートをします。もし`IA_Teleport_Direction`で設定したキーが押されていなかった場合、前方にテレポートします。
また、ここでいう前方はカメラの向いている方向なので上をむいて前方向テレポートをした場合、地面から高いところへテレポートします。
## 完成品は以下のblueprint共有サイトから
本体

https://blueprintue.com/blueprint/9dms6bsy/

途中ででてくる`Macro : PutKey_to_vector`の内容

https://blueprintue.com/blueprint/8623my4v/

### 出てくる変数（その他、Tagの名前など）
| 変数名|種類 | 内容 |
|:-:|:-:|:-:|
| default_Teleport_Range  |変数|  壁と当たらないときのテレポート距離|
| Teleport_Range  |変数|  実際にテレポートする距離 |
| Tag_Playground  |タグ   |通り抜けてほしくないアクターにつけるTag
| PutKey_to_vector|マクロ|折りたたむ機能を知らなかった|
| 0,0,0 Counter  |  変数 |何も押していないときにテレポートキーを押すと前方向テレポートをするためnにすべてが0かカウントする変数。冗長になっている原因。
|(X/Y/Z) Vector|変数|３種類とも各々の頭文字での処理で使う。左/後ろ/下 方向はマイナスをかけないといけないためその処理をするために設定|

# 解説
## Macro : PutKey to vectorの解説
`IA_Teleport_direction`からもらったベクトルを分解しX,Y,Zを別々に処理しています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/23de3cf8-b86b-2975-593e-861e257246ec.png)

上画像はXの処理のみを表示したもの
switch文で-1,0,1の３種類に更に分ける
`Get Control Rotation`（カメラの向いている方向）から`Get Forward Vector`でRotationからベクトルに変換。Xでは前後方向なのでForwardだが、Yでの処理では`Get Right Vector`（角度から右方向ベクトルを取得）、Zでの処理は上下方向なので`Get Up Vector`（角度から上方向ベクトルを取得）を使う。
### -1のとき
これは後ろ方向キーを押している状態であるため、Forward Vectorを反転させる。
その反転したものをSETする
### 0のとき
押されていない状態なのでForward Vectorは使わない。一応、`X_Vector`を(0,0,0)にSETする。
そして、全てが0か確認するために`0,0,0 Conter`を+1する。

### 1のとき
前方向キーをおしている状態なので、Forward VectorをそのままSETする。

**上記３パターンの処理を同様にY,Zでも行う（詳しくはBPをみてね）**

### X,Y,Zの処理で得たものをまとめる & 0,0,0 Counterの処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/f5293fbb-b013-da96-3a3b-03d4c988ff29.png)
X,Y,Zで得たベクトルを全て足して、長さを１にして`Go vector`に値をいれている
長さを１にしないと斜め方向にてレポートした時に通常より長い距離テレポートしてしまうため
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/3b543e56-4d27-30f7-ebcc-1a387eb983c4.png)
`0,0,0 Counter`が３のとき前方向のベクトルをセットしている。

### 複数回、実行ピンに出力されるのを回避する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/9ea013b6-8b77-ca5a-1458-bdd1e8f6eae9.png)
Enterには`X/Y_vector`からの実行ノードと`Z_Vector`をSETしたあとに行われている`0,0,0 Counter`の数字によるSwitch on Intからの実行ノードがつながっている
ResetにはInputsノードの次にあるSequenceノードの１とつながっている
これにより、３種類すべてのノードが実行されてから**一度だけ** Outputsに実行が出力される
また、毎回このマクロに実行が送られると最初に`Do Nノード`をリセットするようになっている
## Raycastの解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237205/5b860043-38ab-ad64-763d-6fc98cb38bee.png)

プレイヤーの位置（`GetActorLocation`）から`Default_Teleport_Range`の距離Raycastを飛ばしている
そして、Raycastがあたっているものの情報が`Out Hits`から出てくるので`is not empty`で空（=あたっていない）か判断している。
### あたっている場合
`ForEachLoop`を利用して当たった複数のアクターを手前から順番に`Tag_Playground`を持っているか確認している
#### Tagを持っていた場合
そのアクターまでの距離を-52したものを`Teleport_Range`にSETして`Add Actor World Offset`に処理を流してテレポートするようにしている
なぜ-52するかというと、そのままの距離をテレポートすると半分壁にめりこんでしまうため
#### Tagを持っていなかった場合
`Default_Teleport_Range`を`Teleport_Range`にSETして`Add Actor World Offset`に処理を流してテレポートするようにしている

### あたっていない場合
Tagを持っていなかった場合と同様の処理をしている
`Default_Teleport_Range`を`Teleport_Range`にSETして`Add Actor World Offset`に処理を流してテレポートするようにしている

# あとがき
数々のQiitaの記事、ブログ、解説動画などを見てつくりました
先人の方々ありがとうございます
テレポートなどを多用した高機動なFPSゲームを作っているのでまた記事を書くかもしれません
読んでいただきありがとうございました

2023/4/1 Macro : PutKey_to_vectorが複数回発動してしまっていた問題を修正