Slide 1

Slide 1 text

ゲーム開発研修2023 Unityを使った開発のツボ 2023/05 ver1.1 デジタルエンターテインメント事業本部 モンストゲーム運営部 クライアント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

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

Slide 4

Slide 4 text

簡単な移動操作

Slide 5

Slide 5 text

簡単な移動操作 ・このチャプターでは簡単な移動操作を作っていただきます。 ・ゲームを作る上では欠かせない移動操作です。  肩肘張らずにリラックスしていきましょう。 ・Projectウィンドウから Scenes -> Scene_1を開いてください。

Slide 6

Slide 6 text

簡単な移動操作 ・このチャプターでは簡単な移動操作を作っていただきます。 ・ゲームを作る上では欠かせない移動操作です。  肩肘張らずにリラックスしていきましょう。 ・Projectウィンドウから Scenes -> Scene_1を開いてください。 ・ここではラジコン操作の移動を作っていただきます。 ・W - 前進 ・S - 後退 ・A - 左回転 ・D - 右回転

Slide 7

Slide 7 text

簡単な移動操作 ・Projectウィンドウから、Scripts -> Scene_1 で右クリック  Create -> C#Scripts でスクリプトを作成する(Cannon.cs として進めていきます) ・先にスクリプトをアタッチする  HierarchyからCannonを選択→InspectorのAddComponentから作成したファイル名を検索して設定。

Slide 8

Slide 8 text

簡単な移動操作 ・Projectウィンドウから、Scripts -> Scene_1 で右クリック  Create -> C#Scripts でスクリプトを作成する(Cannon.cs として進めていきます) ・先にスクリプトをアタッチする  HierarchyからCannonを選択→InspectorのAddComponentから作成したファイル名を検索して設定。 ・デフォルトで用意されている関数について   // オブジェクトが生まれたタイミングでUpdateより前に呼ばれる void Start() // 毎フレーム呼ばれる void Update()

Slide 9

Slide 9 text

簡単な移動操作 ・Unityでの移動はtransformを使用して行う。 ・transformって何よ?  → 移動・回転・拡大縮小・親子関係を司る機能。  → GameObjectは必ずtransformを持っている。

Slide 10

Slide 10 text

簡単な移動操作 ・Unityでの移動はtransformを使用して行う。 ・transformって何よ?  → 移動・回転・拡大縮小・親子関係を司る機能。  → GameObjectは必ずtransformを持っている。 ・Unityでtransformを使用した移動を行うには以下のどちらかを操作する // 絶対座標での指定 transform.position // 親オブジェクトからの相対位置指定 transform.localPosition

Slide 11

Slide 11 text

簡単な移動操作 ・移動は毎フレーム処理したいのでUpdate()の中に書いていきます。 ・まずはキー入力の取得から ・これでWキーの押下が取得できます。簡単ですね。 // 前 if (Input.GetKey(KeyCode.W))

Slide 12

Slide 12 text

簡単な移動操作 ・まずは前後の移動から作っていきましょう。 // 移動 if (Input.GetKey(KeyCode.W)) {// 前 } if (Input.GetKey(KeyCode.S)) {// 後 }

Slide 13

Slide 13 text

簡単な移動操作 ・まずは前後の移動から作っていきましょう。 ・前移動から作っていきます。 // 移動 if (Input.GetKey(KeyCode.W)) {// 前 } if (Input.GetKey(KeyCode.S)) {// 後 } // 移動 if (Input.GetKey(KeyCode.W)) {// 前 transform.position += transform.foward * 10.0f * Time.deltaTime; }

Slide 14

Slide 14 text

簡単な移動操作 ・コードの解説 ・オブジェクトが向いてる方向に移動したいので、前ベクトルを取得する必要があります。  Unityではtransform.foward でオブジェクトの前方向ベクトルが取得できます。  10.0f はそのままだと移動量が少ないので速度として乗算しています。  Time.deltaTime は前回Update()が呼ばれたフレームから今回のUpdate()が呼ばれたフレームの  間の時間になります。 // 移動 if (Input.GetKey(KeyCode.W)) {// 前 transform.position += transform.foward * 10.0f * Time.deltaTime; }

Slide 15

Slide 15 text

簡単な移動操作 ・同じように後ろも作れる。 if (Input.GetKey(KeyCode.S)) {// 後 transform.position -= transform.foward * 10.0f * Time.deltaTime; }

Slide 16

Slide 16 text

簡単な移動操作 ・コード整理するとこんな感じ // 移動 float moveSpeed = 10.0f; Vector3 vec = Vector3.zero; if (Input.GetKey(KeyCode.W)) {// 前 vec += transform.forward; } if (Input.GetKey(KeyCode.S)) {// 後 vec -= transform.forward; } if(vec != Vector3.zero) { transform.position += vec * moveSpeed * Time.deltaTime; }

Slide 17

Slide 17 text

簡単な移動操作 ・回転のキー入力も作りましょう。 「 ・Unityで簡単な回転を行うには以下の関数を使用する // 回転 if (Input.GetKey(KeyCode.A)) {// 左 } if (Input.GetKey(KeyCode.D)) {// 右 } // 現在の回転角に引数の回転角を加算する(オイラー角) transform.Rotate(Vector3 euler)

Slide 18

Slide 18 text

簡単な移動操作 ・左回転から作っていきます。 ・先程の移動と似たようなコードになるかと思います。 // 移動 if (Input.GetKey(KeyCode.A)) {// 左 transform.Rotate(new Vector3(0, -1, 0) * 100.0f* Time.deltaTime); }

Slide 19

Slide 19 text

簡単な移動操作 ・左回転から作っていきます。 ・先程の移動と似たようなコードになるかと思います。 ・同じように右回転も作る。 // 移動 if (Input.GetKey(KeyCode.A)) {// 左 transform.Rotate(new Vector3(0, -1, 0) * 100.0f* Time.deltaTime); } // 移動 if (Input.GetKey(KeyCode.A)) {// 右 transform.Rotate(new Vector3(0, 1, 0) * 100.0f* Time.deltaTime); }

Slide 20

Slide 20 text

簡単な移動操作 ・コード整理するとこんな感じ // 回転 float rotateSpeed = 100.0f; Vector3 rot = Vector3.zero; if (Input.GetKey(KeyCode.A)) {// 左 rot += new Vector3(0, -1, 0); } if (Input.GetKey(KeyCode.D)) {// 右 rot += new Vector3(0, 1, 0); } if(rot != Vector3.zero) { transform.Rotate(rot * rotateSpeed * Time.deltaTime); }

Slide 21

Slide 21 text

簡単な移動操作 ・戦車の前後移動と回転が行えるようになった人は進捗確認くんお願いします。 ・終わっちゃって暇な人は  ・平行移動 とかも作ってみよう!

Slide 22

Slide 22 text

Unityで学ぶ回転

Slide 23

Slide 23 text

Unityで学ぶ回転 クォータニオン ・このシーンではゲーム制作をする上で欠かせない回転についてお話をします。 ・今までのシーンは一旦保存をして、  Projectウィンドウから Scenes -> Scene_2を開いてください。

Slide 24

Slide 24 text

Unityで学ぶ回転 クォータニオン ・このシーンではゲーム制作をする上で欠かせない回転についてお話をします。 ・今までのシーンは一旦保存をして、  Projectウィンドウから Scenes -> Scene_2を開いてください。 ・なにやら怪しげな矢印と謎の円が映し出されていますが・・・

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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


Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 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 44

Slide 44 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 45

Slide 45 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 46

Slide 46 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 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Unityで学ぶ回転 クォータニオン ・Scene_1に戻ってください。

Slide 52

Slide 52 text

Unityで学ぶ回転 クォータニオン ・Scene_1に戻ってください。 ・それでは先程の知識を使って砲塔部分の回転を作ってみましょう。 ・まず砲塔部分のオブジェクトを取得したいので以下のコードを書きます public class Cannon : MonoBehaviour { [SerializeField] GameObject turret; …

Slide 53

Slide 53 text

Unityで学ぶ回転 クォータニオン ・Scene_1に戻ってください。 ・それでは先程の知識を使って砲塔部分の回転を作ってみましょう。 ・まず砲塔部分のオブジェクトを取得したいので以下のコードを書きます ・シリアライズフィールドってなんぞや!?と思うかもしれませんが、  ここではUnity上から変数にアクセスするためのおまじないくらいに思っておいてください。 public class Cannon : MonoBehaviour { [SerializeField] GameObject turret; …

Slide 54

Slide 54 text

Unityで学ぶ回転 クォータニオン ・次はUnity上から砲塔オブジェクトを先程の変数に設定します。 ・HierarchyからCannonを選択、InspectorのCannonコンポーネントのturretにTurretのオブジェクトを  設定する。

Slide 55

Slide 55 text

Unityで学ぶ回転 クォータニオン ・次はUnity上から砲塔オブジェクトを先程の変数に設定します。 ・HierarchyからCannonを選択、InspectorのCannonコンポーネントのturretにTurretのオブジェクトを  設定する。 ・砲塔のオブジェクトのtransformには以下のようにアクセスできます。 turret.transform

Slide 56

Slide 56 text

Unityで学ぶ回転 クォータニオン ・それでは最初に作った回転と同じように砲塔の回転も作りましょう。 // 砲塔の回転 if (Input.GetKey(KeyCode.Q)) { turret.transform.localRotation *= Quaternion.Euler(0.0f, -1.0f, 0.0f); } if(Input.GetKey(KeyCode.E)) { turret.transform.localRotation *= Quaternion.Euler(0.0f, 1.0f, 0.0f); }

Slide 57

Slide 57 text

Unityで学ぶ回転 クォータニオン ・それでは最初に作った回転と同じように砲塔の回転も作りましょう。 ・ここまでできたら進捗確認くんの方お願いします。  できちゃってて暇だったら本体の回転もクォータニオンでチャレンジしてみよう! // 砲塔の回転 if (Input.GetKey(KeyCode.Q)) { turret.transform.localRotation *= Quaternion.Euler(0.0f, -1.0f, 0.0f); } if(Input.GetKey(KeyCode.E)) { turret.transform.localRotation *= Quaternion.Euler(0.0f, 1.0f, 0.0f); }

Slide 58

Slide 58 text

弾を撃つ

Slide 59

Slide 59 text

弾を撃つ ・このチャプターでは弾を発射できるようにしていただきます。 ・Spaceキーを押したときに砲塔の先から弾が出るようにします。

Slide 60

Slide 60 text

弾を撃つ ・このチャプターでは弾を発射できるようにしていただきます。 ・Spaceキーを押したときに砲塔の先から弾が出るようにします。 ・まずは弾のオブジェクトを作成します。 ・Hierarchy上で 右クリック -> 3D Object -> Sphere で球を作成。  名前はBulletにしておきます。 ・RigidBodyをアタッチしてUse Gravityをオフにしてください。 ・Bulletという名前のスクリプトを作ってアタッチしてください。 ・アタッチが出来たら、Hierarchy上のBulletをProjectウィンドウのPrefab -> Scene1の中に  ドラッグ&ドロップでPrefabを作成してください。 ・Prefabが出来たらHierarchyのBulletは削除してください。

Slide 61

Slide 61 text

弾を撃つ ・突然出てきたけどPrefabって何よ?

Slide 62

Slide 62 text

弾を撃つ ・突然出てきたけどPrefabって何よ? ・いろいろな設定をしたGameObjectをアセットとして扱い、複製できるようにしたもの。 ・ここでは、たくさん出したいオブジェクトを作るときにPrefabにしてあると楽なんだな!  くらいの認識でいいかも

Slide 63

Slide 63 text

弾を撃つ ・突然出てきたけどPrefabって何よ? ・いろいろな設定をしたGameObjectをアセットとして扱い、複製できるようにしたもの。 ・ここでは、たくさん出したいオブジェクトを作るときにPrefabにしてあると楽なんだな!  くらいの認識でいいかも ・Prefabに変更を加えると既にHierarchy上に置いてあるオブジェクトにも設定が反映されるので、  シーンを跨いで使う共通オブジェクトとかに使うと楽ができる。

Slide 64

Slide 64 text

弾を撃つ ・本筋に戻って・・・ ・戦車から弾を撃てるように設定します。

Slide 65

Slide 65 text

弾を撃つ ・本筋に戻って・・・ ・戦車から弾を撃てるように設定します。 ・まずは弾を発射する場所の設定から。 ・Hierarchy上で右クリック CreateEmpty で空オブジェクト作成。  名前はShotPointとしておきます。 ・ShotPointを戦車の子要素のCannonの子に入れて、いい感じに砲塔の先端に来るように座標を調整しま す。

Slide 66

Slide 66 text

弾を撃つ ・Cannon.cs に以下のコードを追加します。 [SerializeField] GameObject shotPoint; [SerializeField] GameObject Bullet;

Slide 67

Slide 67 text

弾を撃つ ・Cannon.cs に以下のコードを追加します。 ・先ほどと同様Inspectorからそれぞれのオブジェクトを設定します。 [SerializeField] GameObject shotPoint; [SerializeField] GameObject Bullet;

Slide 68

Slide 68 text

弾を撃つ ・Spaceを押したときに弾が発射されるようにしたいので、Spaceのキー入力を取得します // 射撃 if(Input.GetKeyDown(KeyCode.Space)) {}

Slide 69

Slide 69 text

弾を撃つ ・Spaceを押したときに弾が発射されるようにしたいので、Spaceのキー入力を取得します ・以下の関数でGameObjectの動的な生成を行うことが出来ます。 ・Instantiateの戻り値は生成したゲームオブジェクトになります。 // 射撃 if(Input.GetKeyDown(KeyCode.Space)) {} // ゲームオブジェクト生成 Instantiate(GameObject original, Vector3 position, Quaternion rotation)

Slide 70

Slide 70 text

弾を撃つ ・以上の説明を踏まえて、弾を発射するコードは以下のようになります。 ・コードが書けたら早速発射してみてください!! // 射撃 if(Input.GetKeyDown(KeyCode.Space)) { Instantiate(Bullet, shotPoint.transform.position, Quaternion.identity); }

Slide 71

Slide 71 text

弾を撃つ ・以上の説明を踏まえて、弾を発射するコードは以下のようになります。 ・コードが書けたら早速発射してみてください!! ・... あれ? 発射した弾、ちゃんと飛びませんね  それもそのはず、弾の移動処理を作っていないので作りましょう。 // 射撃 if(Input.GetKeyDown(KeyCode.Space)) { Instantiate(Bullet, shotPoint.transform.position, Quaternion.identity); }

Slide 72

Slide 72 text

弾を撃つ ・Bullet.csを開いて、一番上に以下のコードを書きます。 ・そして、関数を一つ宣言します。 private Vector3 _direction; private Vector3 _direction; private Vector3 _direction; public void SetDirection(Vector3 vec) { _direction = vec; }

Slide 73

Slide 73 text

弾を撃つ ・Bullet.csを開いて、一番上に以下のコードを書きます。 ・そして、関数を一つ宣言します。 private Vector3 _direction; private Vector3 _direction; ・Update()の中に以下のコードを書きます。 private Vector3 _direction; public void SetDirection(Vector3 vec) { _direction = vec; } transform.position += _direction * Speed * Time.deltaTime;

Slide 74

Slide 74 text

弾を撃つ ・Cannon.cs側から先程宣言したSetDirection()を呼びたいので、弾発射時のコードを以下のように修正し ます。 ・GetComponentを利用することによってBulletのスクリプトに宣言された関数にアクセスしています。 ・ここまで出来たら弾を発射してみてください!  今度こそまっすぐ飛んでいくはずです。 ・ここまで出来たら進捗確認くんをお願いします。 GameObject obj; obj = Instantiate(Bullet, shotPoint.transform.position, Quaternion.identity); obj.GetComponent().SetDirection(turret.transform.forward);

Slide 75

Slide 75 text

敵を撃破する

Slide 76

Slide 76 text

敵を撃破する ・このチャプターでは当たり判定を取得して敵を撃破できるようにします。 ・実装に入る前にUnityの当たり判定のお話を少しだけします。

Slide 77

Slide 77 text

敵を撃破する ・このチャプターでは当たり判定を取得して敵を撃破できるようにします。 ・実装に入る前にUnityの当たり判定のお話を少しだけします。 ・Unityの当たり判定には衝突する判定とすり抜ける判定の2種類があります。 ・試しにCannonにアタッチされているBoxColliderを見てみてください。 ・isTriggerという項目にチェックを入れるとすり抜ける判定になります。

Slide 78

Slide 78 text

敵を撃破する ・このチャプターでは当たり判定を取得して敵を撃破できるようにします。 ・実装に入る前にUnityの当たり判定のお話を少しだけします。 ・Unityの当たり判定には衝突する判定とすり抜ける判定の2種類があります。 ・試しにCannonにアタッチされているBoxColliderを見てみてください。 ・isTriggerという項目にチェックを入れるとすり抜ける判定になります。 ・ゴール地点の判定とかはisTriggerで作ったりすることが多いかも

Slide 79

Slide 79 text

敵を撃破する ・衝突する判定、すり抜ける判定それぞれに関数が用意してあります。 // 衝突する判定 OnCollisionEnter (衝突した瞬間) OnCollisionStay (衝突して触れ続けている間) OnCollisionExit (離れる瞬間) // すり抜ける判定 OnTriggerEnter (すり抜ける瞬間) OnTriggerStay (すり抜けている間) OnTriggerExit (離れる瞬間)

Slide 80

Slide 80 text

敵を撃破する ・衝突する判定、すり抜ける判定それぞれに関数が用意してあります。 ・今回は弾が敵に当たったとき、になるので  OnCollisionEnter を使います。 // 衝突する判定 OnCollisionEnter (衝突した瞬間) OnCollisionStay (衝突して触れ続けている間) OnCollisionExit (離れる瞬間) // すり抜ける判定 OnTriggerEnter (すり抜ける瞬間) OnTriggerStay (すり抜けている間) OnTriggerExit (離れる瞬間)

Slide 81

Slide 81 text

敵を撃破する ・Enemy.csに以下の関数を宣言します private void OnCollisionEnter(Collision collision) { }

Slide 82

Slide 82 text

敵を撃破する ・Enemy.csに以下の関数を宣言します ・弾が当たったときに自身を削除します。 ・自身を削除するには以下のように書きます。 private void OnCollisionEnter(Collision collision) { } private void OnCollisionEnter(Collision collision) { Destroy(this.gameObject); }

Slide 83

Slide 83 text

敵を撃破する ・これでも一応は良いのですが、弾以外のオブジェクトに触れても死んでしまうので  弾に触れたときのみ消されるように修正します。

Slide 84

Slide 84 text

敵を撃破する ・これでも一応は良いのですが、弾以外のオブジェクトに触れても死んでしまうので  弾に触れたときのみ消されるように修正します。 ・Unityのタグの仕組みを使います。 ・先程作ったBulletのPrefabを選択して、Inspector上部のTagを選択してAdd Tagを選択します。 ・「+」を押してBulletと入力してSaveを押します。

Slide 85

Slide 85 text

敵を撃破する ・TagがBulletに設定されていることを確認したら、先程のEnemy.csを修正します。 if (collision.transform.CompareTag("Bullet")) { Destroy(this.gameObject); }

Slide 86

Slide 86 text

敵を撃破する ・TagがBulletに設定されていることを確認したら、先程のEnemy.csを修正します。 ・これで弾以外のオブジェクトに当たったときは消えなくなっているはずです  試しに体当たりして消えないか確認してみましょう。 if (collision.transform.CompareTag("Bullet")) { Destroy(this.gameObject); }

Slide 87

Slide 87 text

敵を撃破する ・ここまで出来たら進捗確認くんをお願いします。 ・できちゃってて暇だったら  ・弾も消えるようにする(地形にはStageのタグが設定してあります。)  もやってみてください。

Slide 88

Slide 88 text

SphereCastで作る予測線

Slide 89

Slide 89 text

SphereCastで作る予測線 ・ここでは射撃の予測線を作ってもらおうかと思います。

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 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 94

Slide 94 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 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 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 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

No content