Slide 1

Slide 1 text

ゲーム開発研修2022 Unityを使った開発のツボ 2022/04 ver1.0 モンスト事業本部 ゲーム運営部 クライアント2G クライアント2T 野﨑 裕也

Slide 2

Slide 2 text

自己紹介 ・野﨑 裕也 (yuya.nozaki) ・21新卒 ・モンスト事業本部 ゲーム運営部 クライアント2G クライアント2T ・アウトゲームUI担当 ・新規機能開発、既存機能改善、不具合修正etc… ・Cocos2d-x / C++ ・Unity Engine Challengeのお手伝いなどもしてたり

Slide 3

Slide 3 text

はじめに・・・ Q1 Unityの使用経験はどれくらいですか?

Slide 4

Slide 4 text

はじめに・・・ 本当はこのコーナーではガッツリとUnityのチュートリアルをやろうかなと思ったのですが・・・

Slide 5

Slide 5 text

はじめに・・・ 本当はこのコーナーではガッツリとUnityのチュートリアルをやろうかなと思ったのですが・・・ みなさん経験があるみたいなので少し発展?的なことをやります (とはいっても大したものではないですが...)

Slide 6

Slide 6 text

はじめに・・・ 本当はこのコーナーではガッツリとUnityのチュートリアルをやろうかなと思ったのですが・・・ みなさん経験があるみたいなので少し発展?的なことをやります (とはいっても大したものではないですが...) Unity未経験の方、ごめんなさい とはいいつつ、サブドキュメントを用意したりグループ分けして聞きやすい環境を 用意しているので安心してください!

Slide 7

Slide 7 text

はじめに・・・ なんだよー!Unity基礎からやってくれるんじゃないの?? という方 昨年のゲーム開発研修前半がしっかりとチュートリアルしているので 是非そちらをよろしくお願いします。 https://mixi-developers.mixi.co.jp/21-technical-training-a0bcdbf9bca0

Slide 8

Slide 8 text

事前準備 ・Slackに共有されているリポジトリからcloneはお済みでしょうか? ・UnityHubにUnityBasicsのプロジェクトを追加して、Scene_01を開いてください。 ・Sceneを開けた方は進捗確認君で挙手をお願いします。

Slide 9

Slide 9 text

Unityで学ぶ回転 クォータニオン

Slide 10

Slide 10 text

Unityで学ぶ回転 クォータニオン ・このシーンではゲーム制作をする上で欠かせない回転についてお話をします。 ・なにやら怪しげな矢印と謎の円が映し出されていますが・・・

Slide 11

Slide 11 text

Unityで学ぶ回転 クォータニオン ・このシーンではゲーム制作をする上で欠かせない回転についてお話をします。 ・なにやら怪しげな矢印と謎の円が映し出されていますが・・・ ・このシーンではゲーム制作する上で引っ掛かりがちなジンバルロックを解決する方法について  お話できればと思います。

Slide 12

Slide 12 text

Unityで学ぶ回転 クォータニオン ・ジンバルロックって・・・?

Slide 13

Slide 13 text

Unityで学ぶ回転 クォータニオン ・ジンバルロックって・・・? ・説明するよりまずは見てもらったほうが早いでしょう。 ・Xの回転を90 or -90 にして、Y or Zの回転をしてみてください。

Slide 14

Slide 14 text

Unityで学ぶ回転 クォータニオン ・ジンバルロックって・・・? ・説明するよりまずは見てもらったほうが早いでしょう。 ・Xの回転を90 or -90 にして、Y or Zの回転をしてみてください。 ・YとZどっちを動かしても同じ方向にしか回転しなくなりましたか? ・それがジンバルロックです。

Slide 15

Slide 15 text

Unityで学ぶ回転 クォータニオン ・オイラー角で表現された回転を行うときに、2つの回転軸が同じ方向を向いてしまう現象を  ジンバルロックといいます。  (ちょっとしたゲーム制作なら陥らないけど、ちょっと凝った3Dゲーム作ろうとすると   起こることが多い) ・謎の矢印の周りにある色の付いた円はそれぞれ  X Y Z の回転軸を表しています。 ・Xを90度傾けたときにYとZの円が重なってしまっていますね。  動画としてはこれがわかりやすい (https://youtu.be/zc8b2Jo7mno?t=55)

Slide 16

Slide 16 text

Unityで学ぶ回転 クォータニオン ・オイラー角はみなさんが慣れ親しんでいるXYZで回転を表現する形式 ・UnityではY→X→Zの順番で回転の計算が行われるためにジンバルロックが起こってしまう。  (ワールド座標からみたらZ→X→Y) ・X 90 Y 90 Z0 と X90 Y0 Z90 の場合それぞれ見てみましょう。

Slide 17

Slide 17 text

Unityで学ぶ回転 クォータニオン ・回転の順番で影響が出るなら、自分で制御すれば思い通りの回転ができるのでは?

Slide 18

Slide 18 text

Unityで学ぶ回転 クォータニオン ・回転の順番で影響が出るなら、自分で制御すれば思い通りの回転ができるのでは?  → 複数軸回転するオブジェクトそれぞれにスクリプト書く?  → 回転させる順番で結果が全然違ってくるのでは?  → そもそも回転のイメージし辛い

Slide 19

Slide 19 text

Unityで学ぶ回転 クォータニオン ・回転の順番で影響が出るなら、自分で制御すれば思い通りの回転ができるのでは?  → 複数軸回転するオブジェクトそれぞれにスクリプト書く?  → 回転させる順番で結果が全然違ってくるのでは?  → そもそも回転のイメージし辛い ・じゃあどうすればいいの?

Slide 20

Slide 20 text

Unityで学ぶ回転 クォータニオン ・回転の順番で影響が出るなら、自分で制御すれば思い通りの回転ができるのでは?  → 複数軸回転するオブジェクトそれぞれにスクリプト書く?  → 回転させる順番で結果が全然違ってくるのでは?  → そもそも回転のイメージし辛い ・じゃあどうすればいいの?   →クォータニオン

Slide 21

Slide 21 text

Unityで学ぶ回転 クォータニオン ・クォータニオンって何?

Slide 22

Slide 22 text

Unityで学ぶ回転 クォータニオン ・クォータニオンって何?  →クォータニオン(quaternion)は四元数(しげんすう)と呼ばれ,2次元平面の回転を表現する「複素数の拡張」として,3次元の 回転を表現することができます.なお,ただのクォータニオンはそれだけでは回転を表現しません.大きさが1という拘束のある単位 クォータニオン(オイラーパラメータ)によって回転を表現します.
 (https://www.sports-sensing.com/brands/labss/motionmeasurement/motion_biomechanics/quaternion04.html )


Slide 23

Slide 23 text

Unityで学ぶ回転 クォータニオン ・クォータニオンって何?  →クォータニオン(quaternion)は四元数(しげんすう)と呼ばれ,2次元平面の回転を表現する「複素数の拡張」として,3次元の 回転を表現することができます.なお,ただのクォータニオンはそれだけでは回転を表現しません.大きさが1という拘束のある単位 クォータニオン(オイラーパラメータ)によって回転を表現します.
 (https://www.sports-sensing.com/brands/labss/motionmeasurement/motion_biomechanics/quaternion04.html )
 
 ・???????

Slide 24

Slide 24 text

Unityで学ぶ回転 クォータニオン ・クォータニオンって何?  →クォータニオン(quaternion)は四元数(しげんすう)と呼ばれ,2次元平面の回転を表現する「複素数の拡張」として,3次元の 回転を表現することができます.なお,ただのクォータニオンはそれだけでは回転を表現しません.大きさが1という拘束のある単位 クォータニオン(オイラーパラメータ)によって回転を表現します.
 (https://www.sports-sensing.com/brands/labss/motionmeasurement/motion_biomechanics/quaternion04.html )
 
 ・??????? ・正直何言ってるかわからんし調べても理解できる自信ない・・・って方いるかと思いますが  Unityなら大丈夫  簡単にクォータニオンが使える関数群が用意されています。

Slide 25

Slide 25 text

Unityで学ぶ回転 クォータニオン ・まずは今の実装を見ていきましょう。 ・Projectウィンドウから、Scripts -> Scene_01 -> Cursor.cs を開く ・input には キー入力の結果が格納されている。 ・transform.rotationからオイラー角として値を取り出して入力と合成し、  クォータニオンとしてrotationに代入している。 // 現在の回転に入力を加算 Vector3 newAngle = transform.rotation.eulerAngles + (input); // rotationに代入 transform.rotation = Quaternion.Euler(newAngle);

Slide 26

Slide 26 text

Unityで学ぶ回転 クォータニオン ・ここで問題なのは  transform.rotationにはQuaternionで値が入っているのにわざわざオイラー角で取り出して  計算を行っていること。 ・Quaternionのまま計算してあげればちゃんと回転するんじゃない?

Slide 27

Slide 27 text

Unityで学ぶ回転 クォータニオン ・UnityでQuaternionの回転を表現する主な関数は4つ // オイラー角からクォータニオンを作成する Quaternion.Euler // 任意の回転軸からクォータニオンを作成する Quaternion.AngleAxis // ある方向からある方向へ向かせるクォータニオンを作成する Quaternion.FromToRotation // 向きたい方向に向かせるクォータニオンを作成する Quaternion.LookRotation

Slide 28

Slide 28 text

Unityで学ぶ回転 クォータニオン ・UnityでQuaternionの回転を表現する主な関数は4つ ・今回使うのは Quaternion.AngleAxis // オイラー角からクォータニオンを作成する Quaternion.Euler // 任意の回転軸からクォータニオンを作成する Quaternion.AngleAxis // ある方向からある方向へ向かせるクォータニオンを作成する Quaternion.FromToRotation // 向きたい方向に向かせるクォータニオンを作成する Quaternion.LookRotation

Slide 29

Slide 29 text

Unityで学ぶ回転 クォータニオン ・まずは各回転軸のクォータニオンを作りましょう。 // 各軸のクォータニオンを作成 var rotX = Quaternion.AngleAxis(input.x, Vector3.right); var rotY = Quaternion.AngleAxis(input.y, Vector3.up); var rotZ = Quaternion.AngleAxis(input.z, Vector3.forward);

Slide 30

Slide 30 text

Unityで学ぶ回転 クォータニオン ・まずは各回転軸のクォータニオンを作りましょう。 ・次にこのクォータニオンたちを合成するのですが、さっき言った  Unityでの回転軸の合成順番、覚えてますか? // 各軸のクォータニオンを作成 var rotX = Quaternion.AngleAxis(input.x, Vector3.right); var rotY = Quaternion.AngleAxis(input.y, Vector3.up); var rotZ = Quaternion.AngleAxis(input.z, Vector3.forward);

Slide 31

Slide 31 text

Unityで学ぶ回転 クォータニオン ・まずは各回転軸のクォータニオンを作りましょう。 ・次にこのクォータニオンたちを合成するのですが、さっき言った  Unityでの回転軸の合成順番、覚えてますか?  →「Y→X→Z」の順番で合成します。 // 各軸のクォータニオンを作成 var rotX = Quaternion.AngleAxis(input.x, Vector3.right); var rotY = Quaternion.AngleAxis(input.y, Vector3.up); var rotZ = Quaternion.AngleAxis(input.z, Vector3.forward);

Slide 32

Slide 32 text

Unityで学ぶ回転 クォータニオン ・まずは各回転軸のクォータニオンを作りましょう。 ・次にこのクォータニオンたちを合成するのですが、さっき言った  Unityでの回転軸の合成順番、覚えてますか?  →「Y→X→Z」の順番で合成します。 // 各軸のクォータニオンを作成 var rotX = Quaternion.AngleAxis(input.x, Vector3.right); var rotY = Quaternion.AngleAxis(input.y, Vector3.up); var rotZ = Quaternion.AngleAxis(input.z, Vector3.forward); // Y→X→Zの順に乗算 transform.rotation *= rotZ * rotX * rotY;

Slide 33

Slide 33 text

Unityで学ぶ回転 クォータニオン ・これでジンバルロックが解消したか確認してみましょう。

Slide 34

Slide 34 text

Unityで学ぶ回転 クォータニオン ・これでジンバルロックが解消したか確認してみましょう。 ・ちゃんと解消されてますね!やったー! ・ちなみに矢印の周りの円はオイラー角表現でジンバルロック見るために無理やり作ったやつなので  クォータニオンだとちゃんと動きません。 ・回転軸見たい人はSceneビューで  オブジェクト回転モードにして見てみてください。

Slide 35

Slide 35 text

Unityで学ぶ回転 クォータニオン ・ではここまでできた人は進捗確認君で挙手してください。 ・終わっちゃって暇な人はScene_01Exを開いて、矢印の周りを周回する玉を追従する矢印を  作ってください。  (transform.LookAtで終わらそうとすると逆向きになるのでQuaternionで180度回してね)

Slide 36

Slide 36 text

Unityで学ぶ回転 クォータニオン ・向きたいオブジェクトの位置と自分の位置から向きたいベクトルを出して  Quaternion.LookRotationでクォータニオンを作成  その後180度回してます。 var vec = target.transform.position - this.transform.position; var rot = Quaternion.LookRotation(vec); transform.rotation = rot * Quaternion.Euler(0, 180, 0);

Slide 37

Slide 37 text

Unityで学ぶ回転 クォータニオン ・向きたいオブジェクトの位置と自分の位置から向きたいベクトルを出して  Quaternion.LookRotationでクォータニオンを作成  その後180度回してます。  (本当はモデルの出力ミスっただけだけどそれっぽい問題になったのでそのままにしました) var vec = target.transform.position - this.transform.position; var rot = Quaternion.LookRotation(vec); transform.rotation = rot * Quaternion.Euler(0, 180, 0);

Slide 38

Slide 38 text

SphereCastで作る予測線

Slide 39

Slide 39 text

SphereCastで作る予測線 ・Projectウィンドウ -> Scenes -> Scene_02を開いてください。

Slide 40

Slide 40 text

SphereCastで作る予測線 ・Projectウィンドウ -> Scenes -> Scene_02を開いてください。 ・真ん中の砲台が回転して弾を撃つだけのシーンです。 ・A,Dで回転、Spaceで射撃です。  移動はできません。

Slide 41

Slide 41 text

SphereCastで作る予測線 ・特に敵が出てきたりとかは作ってないのでありませんが、  射撃の予測線を作ってもらおうかと思います。

Slide 42

Slide 42 text

SphereCastで作る予測線 ・まずはSphereCastの説明から

Slide 43

Slide 43 text

SphereCastで作る予測線 ・まずはSphereCastの説明から ・Unityに実装されているRayCastの中の一つ  ・点を飛ばすRayCast  ・球を飛ばすSphereCast  ・箱を飛ばすBoxCast  ・カプセルを飛ばすCapsuleCast ・どれも何かを飛ばして当たり判定を取得する、という関数です。

Slide 44

Slide 44 text

SphereCastで作る予測線 ・origin … 球を飛ばす原点 ・radius … 球の半径 ・direction … 飛ばす方向 ・hitInfo … あたった場合の情報が入った構造体 ・maxDistance … 最大飛距離 ・他にも引数はあるが基本的なのはこんな感じ。 bool SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance)

Slide 45

Slide 45 text

SphereCastで作る予測線 ・とりあえず飛ばしてみる if(Physics.SphereCast(shotPoint.transform.position, Bullet.transform.localScale.x * 0.5f, turret.transform.forward, out hit, 30)) { Debug.Log(hit.point) }

Slide 46

Slide 46 text

SphereCastで作る予測線 ・とりあえず飛ばしてみる ・コンソールにそれっぽい座標返ってきてたらOK ・次は線を書く if(Physics.SphereCast(shotPoint.transform.position, Bullet.transform.localScale.x * 0.5f, turret.transform.forward, out hit, 30)) { Debug.Log(hit.point) }

Slide 47

Slide 47 text

SphereCastで作る予測線 ・Unityのヒエラルキー上で右クリック -> Create Empty  名前は予測線なので「Pred Line」とか適当につけておく。  ”cannon”の子供にして、Line Rendererをアタッチする。

Slide 48

Slide 48 text

SphereCastで作る予測線 ・Unityのヒエラルキー上で右クリック -> Create Empty  名前は予測線なので「Pred Line」とか適当につけておく。  ”cannon”の子供にして、Line Rendererをアタッチする。 ・次はマテリアルを作る  Projectウィンドウ -> Materials -> Scene_02 の中で  右クリック -> Material を選択  Rendering ModeをTransparentにし、それっぽい緑にしておく  アルファ値を設定するのを忘れずに。

Slide 49

Slide 49 text

SphereCastで作る予測線 ・今作ったマテリアルをヒエラルキーのPredLineにドラッグ&ドロップ  これでマテリアルが設定される。  初期設定のままだと極太の線が出てくるのでWidthを0.1にする

Slide 50

Slide 50 text

SphereCastで作る予測線 ・次はスクリプトを書いていく。  Projectウィンドウ -> Scripts -> Scene_02 -> cannon.cs を開く ・一番上にシリアライズフィールドを追加する。   [SerializeField] LineRenderer predLine;

Slide 51

Slide 51 text

SphereCastで作る予測線 ・次はスクリプトを書いていく。  Projectウィンドウ -> Scripts -> Scene_02 -> cannon.cs を開く ・一番上にシリアライズフィールドを追加する。 ・シリアライズフィールドを追加したら忘れずにcannonのインスペクタからpredLineを設定しておく。   [SerializeField] LineRenderer predLine;

Slide 52

Slide 52 text

SphereCastで作る予測線 ・スクリプトに戻る ・LineRendererに予測線の始点と終点を教えてあげたい。  始点は射撃の部分で使っているshotPoint.transform.position でいけそう  終点は shotPoint.transform.position + (turret.transform.forward * hit.distance) とする。  hit.pointという接触地点が格納される変数もあるが、球が接触した場所なので  球の軌道上じゃない場合がある。  

Slide 53

Slide 53 text

SphereCastで作る予測線 ・コードにするとこうなる   predLine.SetPosition(0, shotPoint.transform.position); predLine.SetPosition(1, shotPoint.transform.position + (turret.transform.forward * hit.distance));

Slide 54

Slide 54 text

SphereCastで作る予測線 ・コードにするとこうなる ・SphereCastを飛ばした先に何もないときに線が出続けてしまうと困るので  あたっていないときはLineRendererを出ないようにする   predLine.SetPosition(0, shotPoint.transform.position); predLine.SetPosition(1, shotPoint.transform.position + (turret.transform.forward * hit.distance));

Slide 55

Slide 55 text

SphereCastで作る予測線 ・SphereCastを飛ばした先に何もないときに線が出続けてしまうと困るので  あたっていないときはLineRendererを出ないようにする   if(Physics.SphereCast(shotPoint.transform.position, Bullet.transform.localScale.x * 0.5f, turret.transform.forward, out hit, 30)) { predLine.SetPosition(0, shotPoint.transform.position); predLine.SetPosition(1, shotPoint.transform.position + (turret.transform.forward * hit.distance)); predLine.gameObject.SetActive(true); } else { predLine.gameObject.SetActive(false); }

Slide 56

Slide 56 text

SphereCastで作る予測線 ・こんな感じになったらOK!! ・ここまでできたらこのパートでやりたかったことはおしまいです。  ここまでできた方は進捗確認君で挙手をお願いします。 ・暇な人は右下の図みたいに予測線の先に球とかも出してみましょう  (画像では分かりやすくするために球を大きくしています)  

Slide 57

Slide 57 text

最後に ・お疲れ様でした。 ・ここからがUnity研修の本番です。  頑張りましょう。 (質問は気軽にしてね!)

Slide 58

Slide 58 text

No content