ゲーム開発における三角形のお話

こんにちは！
株式会社OGIXのエンジニア T.Rです！
（弊社については最後に紹介があるのでぜひ見てください）

突然ですがみなさんは数学が好きですか？
嫌いですよね。わたしも嫌いです。

こんなもん勉強して一体何の役に立つんだ、というのは数学を学んでいるときに出てくる定番のセリフですが、ゲーム制作（特に2Dゲーム）においてはびっくりするほど役に立っていたりします。

どういうところで役に立っているのかを知ってみると、仕組みや成り立ちがわかるようになり、嫌いだったものでもおもしろさを感じられるようになるかもしれません。

ということで、今回はゲームの制作において欠かせない、三角形についてのお話をしようと思います。

## 三角形なんて見つけて何の役に立つんだ

まずは、ゲーム画面の中のどういったところに三角形がひそんでいるのかをみつけてみましょう。たとえば、下記のようにプレイヤーキャラクターと敵のキャラクターが並んでいる場面を考えてみます。

![img1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/91d596df-8a23-4e60-cdf2-d4d575d30d90.jpeg)

そうしたら、プレイヤーキャラクターから敵キャラクターの方向に向かってx軸の水平の直線を伸ばしていきます。同時に、敵キャラクターからも、プレイヤーキャラクターの方向に向かってy軸の垂直の直線を伸ばしていきます。するとそれぞれを伸ばしていった先に、この二つの直線が交差する点ができますね。最後に、プレイヤーキャラクターと敵キャラクターを直接結ぶ線を引くと、ここに三角形が浮かんできます。（視覚的なわかりやすさのため画像にグリッドをかけています）

![img2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/794fa0b8-8120-ad71-57fd-98a56bb171c5.jpeg)

ここで大事なことは、できあがった交点がx軸とy軸二つの直線でつくられた**直角**であり、浮かんできた三角形が**直角三角形である**ということです。これが直角三角形だと何がうれしいのかというと、この空間にまつわる様々な情報を、**三角関数**によって調べることが容易になるからなのです。

では、三角関数とは何なのでしょうか。

> 三角関数とは、平面三角法における、角の大きさと線分の長さの関係を記述する関数の族、およびそれらを拡張して得られる関数の総称である。鋭角を扱う場合、三角関数の値は対応する直角三角形の二辺の長さの比（三角比）である。三角法に由来する三角関数という呼び名のほかに、単位円を用いた定義に由来する円関数という呼び名がある。(Wikipediaより)

はい。
とのことです。

それでは、三角関数からわかる情報で何ができるのか、具体例をみていきたいと思います。

## プレイヤーから敵に向かってまっすぐ伸びる線の角度が知りたい

さきほどの画像で示したようにプレイヤーと敵のキャラクターが並んでいると、プレイヤーから敵に向かってまっすぐ飛んでいく弾を撃ちたくなるときがあります。その際にどういった情報が必要になるかというと、まずはどの方向に対して弾を飛ばせば、それが敵に向かってまっすぐ飛んでいく弾になるのかという、**角度**の情報です。

単に三角関数と呼ばれるものの場合、これは角度を入力として辺の比率を出力として得るものですので、角度がわからない今回の場合使うことができないと思うかもしれません。ですが、数学の関数には**逆関数**という考え方があり、これはある関数の逆操作をすることで、出力の情報を使ってもともとの入力を求めることができるというものです。

![スライド3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/a32d40d8-e0c4-59c9-e8c8-eafd03479ab0.jpeg)

つまり、角度を入力して辺の比率を出力する三角関数の逆関数は、**辺の比率を入力して角度を出力する**関数として使うことができます。
（逆関数の名前は、元の関数名の頭にアーク(arc)という接頭辞をつけてあらわされることが多く、三角関数のサイン・コサイン・タンジェントに対応する逆関数は、それぞれアークサイン・アークコサイン・アークタンジェントとなります。）

今回は、プレイヤーと敵のキャラクターの間にあるx軸とy軸の距離がすでにわかっているため、その情報から二辺の比率を出すことができます。

![スライド4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3565804/8ec943c0-2e28-406f-e83f-fc96b21c9296.jpeg)

そして、それを三角関数の逆関数の入力として使用することで、角度の情報を得ることができるようになります。

これをUnity/C#で実装する場合をみてみます。数学に関する実装はMathfクラスに定義されていますので、三角関数の逆関数もこの中に含まれています。比率から角度を取得しますので、アークタンジェントを使いますが、ここではAtan2として定義されているものを使用します。これは、x軸とy軸の距離を与えるだけで角度を出力してくれるすぐれものです。

```
Math.Atan2(y, x); // yが先であることに注意
```

はい、これにより、x軸とy軸の値から、プレイヤーから敵キャラクターにまっすぐ伸びる線の角度がいくつなのか、という情報を得ることができました。Atan2から得られる角度の値は、ラジアンと呼ばれる単位となっていますが、これは度数単位に変換することができます。

この角度をそのまま使えば、プレイヤーから敵に向かってまっすぐに飛んでいく方向を知ることができますし、この角度に対して数値の揺らぎを加えてあげると、目的の方向からわずかにそれた値となり、いわゆるn-Way弾をつくることにも活用できるようになりますね。

（方向が知りたいなら最初から二つの点をベクトルとして引き算してから正規化すればよい？　やかましい）

## まとめ

いかがでしたでしょうか。

非常に初歩的な内容ではありますが、初歩的とはいえ仕組みや原理をイチから知ろうとするとなかなかの回り道が必要になるのがこのテの話のやっかいなところ。一方で、原理を無視して結果だけ得ようとすると、本当にそれを使っていいのか判断ができないというときもあるかと思います。

わたしもゲーム制作について学びはじめたころ、角度が知りたいだけなのにどうしていきなりアークのタンジェントの2が出てくるのかと非常に困惑した記憶があります。

最終的にもっとも大事なことは、その原理を使って何を実現するかというところにあると思います。ゲーム制作に限らず何かをつくろうとするとき、原理を知ること自体は目的ではないことが多いですが、知っておくことでより発展的・応用的なアプローチをひらめくきっかけとなるかもしれません。

これから学習や制作を進めていく方の一助となればうれしく思います。

## 一緒に働く仲間を募集しています！

株式会社OGIXでは一緒に働いてくれる仲間を募集しています！
エンタメ制作集団としてゲームのみならず、未来を見据えたエンタメコンテンツの開発を行っています。

事業拡大に伴い、エンジニアさんを大募集しています。
興味のある方は下記リンクから弊社のことをぜひ知っていただき応募してもらえると嬉しいです。
▼会社について
https://www.wantedly.com/companies/company_6473754/about
▼代表インタビュー
https://www.wantedly.com/companies/company_6473754/post_articles/443064
▼東京オフィスの応募はこちら
https://www.wantedly.com/projects/1468324
▼新潟オフィスの応募はこちら
https://www.wantedly.com/projects/1468155