『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter05 敵をロックオンする」 学習記録

Unity5ゲーム開発レシピ ハマるゲーム制作のノウハウ

Unity5ゲーム開発レシピ ハマるゲーム制作のノウハウ

序文

『Unity5ゲーム開発レシピ』7日目。

そっか、まだ実質1週間か。
1週間の割には割とそれっぽいものができている気がする。
ありがとうUnity。ありがとうAzalea。(サンプルゲームのロボットの名前らしい)

GitHub

github.com

進捗

  • Part01 基本編
    • Chapter04 敵キャラクターを登場させる
    • Chapter05 敵をロックオンする(途中)

(学習時間:2.5時間)

コード実装部分

\Chapter1\Assets\Scripts\LockOn.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LockOn : MonoBehaviour
{
  GameObject target = null;

  void Start()
  {

  }

  void Update()
  {
    if (Input.GetButtonDown("Lock"))
    {
      // ロックを解除する
      if (target != null)
        target = null;
      else
        // 一番近いターゲットを取得する
        target = FindClosestEnemy();
        // ターゲットを取得する
        //target = GameObject.FindWithTag("Enemy");
    }

    if (target != null)
    {
      // ターゲットの方向を向く
      // transform.LookAt(target.transform);

      // スムーズにターゲットの方向を向く
      Quaternion targetRotation = Quaternion.LookRotation(target.transform.position - transform.position);
      transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 10);
      // ただしX軸とZ軸は回転させない
      transform.rotation = new Quaternion(0, transform.rotation.y, 0, transform.rotation.w);

      // カメラをターゲットに向ける
      Transform cameraParent = Camera.main.transform.parent;
      // カメラをどう回転させるかを取得
      Quaternion targetRotation2 = Quaternion.LookRotation(target.transform.position - cameraParent.position);
      // 速度を指定してカメラを回転させる
      cameraParent.localRotation = Quaternion.Slerp(cameraParent.localRotation, targetRotation2, Time.deltaTime * 10);
      // ただしY軸とZ軸は回転させない
      cameraParent.localRotation = new Quaternion(cameraParent.localRotation.x, 0, 0, cameraParent.localRotation.w);
    }
  }

  // 一番近い敵を探して取得する
  private GameObject FindClosestEnemy()
  {
    GameObject[] gos;
    gos = GameObject.FindGameObjectsWithTag("Enemy");
    GameObject closest = null;
    float distance = Mathf.Infinity;
    Vector3 position = transform.position;

    foreach(GameObject go in gos)
    {
      Vector3 diff = go.transform.position - position;
      float curDistance = diff.sqrMagnitude;

      if(curDistance < distance)
      {
        closest = go;
        distance = curDistance;
      }
    }

    return closest;
  }
}
  • その他実装部分

github.com

実行結果

www.youtube.com プレイヤーと敵の位置関係や敵の数によって、ロックオンの対象が変わるんだぞーということを表現しようとしています(一番近くにいる敵を狙う)

感想

やったこと。

  • 敵にHPを設定して何発か当てないと敵が倒れないようにする
  • 着弾時のダメージにある程度幅をもたせて、さらに敵との距離によってダメージが減少するように設定
  • ロックオン機能の実装
  • 一番近い敵を探してロックオンするように設定

上のソースコードにも登場しているけれどQuaternionというクラスが登場した。
日本語訳すると四元数というそうな。(-_-;;)

私は数学は好きなんだけど苦手というタチが悪いタイプで、ずっと文系を選択してきたので、まったく専門的な理解はできていないが、とりあえずUnityにおいては「回転」をあらわす(時に使う)クラスというふうに理解した。
Quaternionオブジェクトは4つの値(x,y,z,w)から定義されていて、前3つの値(x,y,z)で「回転の軸」をあらわす3次元ベクトルを表し、最後の引数wでそれをどれぐらい回転させるかという値を表していると理解した。
確かにInspectorのRotationに表示されている3値だけでは回転を定義できない(気がする)。

正確かどうかはしらない。ここらへん参照してください。

spi8823.hatenablog.com

カロリーメイトください。

BGM

YEN TOWN BAND feat. Kj(Dragon Ash) / my town

www.youtube.com