Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゲーム開発研修(Unity基礎編)【ミクシィ22新卒技術研修】

 ゲーム開発研修(Unity基礎編)【ミクシィ22新卒技術研修】

B16717ef4b7aab0b253d933c3934f280?s=128

mixi_engineers
PRO

April 25, 2022
Tweet

More Decks by mixi_engineers

Other Decks in Programming

Transcript

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

  2. 自己紹介 ・野﨑 裕也 (yuya.nozaki) ・21新卒 ・モンスト事業本部 ゲーム運営部 クライアント2G クライアント2T ・アウトゲームUI担当

    ・新規機能開発、既存機能改善、不具合修正etc… ・Cocos2d-x / C++ ・Unity Engine Challengeのお手伝いなどもしてたり
  3. はじめに・・・ Q1 Unityの使用経験はどれくらいですか?

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

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

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

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

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

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

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

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

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

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

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

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

    ・Xを90度傾けたときにYとZの円が重なってしまっていますね。  動画としてはこれがわかりやすい (https://youtu.be/zc8b2Jo7mno?t=55)
  16. Unityで学ぶ回転 クォータニオン ・オイラー角はみなさんが慣れ親しんでいるXYZで回転を表現する形式 ・UnityではY→X→Zの順番で回転の計算が行われるためにジンバルロックが起こってしまう。  (ワールド座標からみたらZ→X→Y) ・X 90 Y 90 Z0 と X90 Y0

    Z90 の場合それぞれ見てみましょう。
  17. Unityで学ぶ回転 クォータニオン ・回転の順番で影響が出るなら、自分で制御すれば思い通りの回転ができるのでは?

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

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

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

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

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


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

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

     Unityなら大丈夫  簡単にクォータニオンが使える関数群が用意されています。
  25. Unityで学ぶ回転 クォータニオン ・まずは今の実装を見ていきましょう。 ・Projectウィンドウから、Scripts -> Scene_01 -> Cursor.cs を開く ・input には

    キー入力の結果が格納されている。 ・transform.rotationからオイラー角として値を取り出して入力と合成し、  クォータニオンとしてrotationに代入している。 // 現在の回転に入力を加算 Vector3 newAngle = transform.rotation.eulerAngles + (input); // rotationに代入 transform.rotation = Quaternion.Euler(newAngle);
  26. Unityで学ぶ回転 クォータニオン ・ここで問題なのは  transform.rotationにはQuaternionで値が入っているのにわざわざオイラー角で取り出して  計算を行っていること。 ・Quaternionのまま計算してあげればちゃんと回転するんじゃない?

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

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

    // ある方向からある方向へ向かせるクォータニオンを作成する Quaternion.FromToRotation // 向きたい方向に向かせるクォータニオンを作成する Quaternion.LookRotation
  29. 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);
  30. 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);
  31. 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);
  32. 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;
  33. Unityで学ぶ回転 クォータニオン ・これでジンバルロックが解消したか確認してみましょう。

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

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

  36. 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);
  37. 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);
  38. SphereCastで作る予測線

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

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

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

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

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

  44. SphereCastで作る予測線 ・origin … 球を飛ばす原点 ・radius … 球の半径 ・direction … 飛ばす方向

    ・hitInfo … あたった場合の情報が入った構造体 ・maxDistance … 最大飛距離 ・他にも引数はあるが基本的なのはこんな感じ。 bool SphereCast(Vector3 origin, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance)
  45. SphereCastで作る予測線 ・とりあえず飛ばしてみる if(Physics.SphereCast(shotPoint.transform.position, Bullet.transform.localScale.x * 0.5f, turret.transform.forward, out hit, 30))

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

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

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

     Projectウィンドウ -> Materials -> Scene_02 の中で  右クリック -> Material を選択  Rendering ModeをTransparentにし、それっぽい緑にしておく  アルファ値を設定するのを忘れずに。
  49. SphereCastで作る予測線 ・今作ったマテリアルをヒエラルキーのPredLineにドラッグ&ドロップ  これでマテリアルが設定される。  初期設定のままだと極太の線が出てくるのでWidthを0.1にする

  50. SphereCastで作る予測線 ・次はスクリプトを書いていく。  Projectウィンドウ -> Scripts -> Scene_02 -> cannon.cs を開く

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

    ・一番上にシリアライズフィールドを追加する。 ・シリアライズフィールドを追加したら忘れずにcannonのインスペクタからpredLineを設定しておく。   [SerializeField] LineRenderer predLine;
  52. SphereCastで作る予測線 ・スクリプトに戻る ・LineRendererに予測線の始点と終点を教えてあげたい。  始点は射撃の部分で使っているshotPoint.transform.position でいけそう  終点は shotPoint.transform.position + (turret.transform.forward *

    hit.distance) とする。  hit.pointという接触地点が格納される変数もあるが、球が接触した場所なので  球の軌道上じゃない場合がある。  
  53. SphereCastで作る予測線 ・コードにするとこうなる   predLine.SetPosition(0, shotPoint.transform.position); predLine.SetPosition(1, shotPoint.transform.position + (turret.transform.forward *

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

    (turret.transform.forward * hit.distance));
  55. 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); }
  56. SphereCastで作る予測線 ・こんな感じになったらOK!! ・ここまでできたらこのパートでやりたかったことはおしまいです。  ここまでできた方は進捗確認君で挙手をお願いします。 ・暇な人は右下の図みたいに予測線の先に球とかも出してみましょう  (画像では分かりやすくするために球を大きくしています)  

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

  58. None