『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter06 ユーザーインターフェースを作成する」 学習記録3

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

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

序文

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

国民健康保険料を支払ってきました。31万円でした。(言っちゃう)
高いよー。

GitHub

github.com

進捗

(学習時間:2時間)

コード実装部分

\Chapter1\Assets\Scripts\LockOn.cs

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

public class LockOn : MonoBehaviour
{
  GameObject target = null;

  bool isSearch;

  public Image lockOnImage;

  public GameObject enemyAp;

  public Image gaugeImage;

  public Text textDistance;

  void Start()
  {
    isSearch = false;

    lockOnImage.enabled = false;

    enemyAp.SetActive(false);
  }

  void Update()
  {
    if (Input.GetButtonDown("Lock"))
    {
      // ロックオンモードに切り替え
      isSearch = !isSearch;

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

    // ロックオンモードで敵がいれば敵の方を向く
    if (isSearch)
    {
      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);
      }
      else
      {
        // ロックオンモードでロックしていなければ敵を探す
        target = FindClosestEnemy();
      }
    }

    if (target != null)
    {
      // 距離が離れたらロックを解除する
      if(Vector3.Distance(target.transform.position, transform.position) > 100)
      {
        target = null;
      }
    }

    // ターゲットがいたらロックオンカーソルを表示する
    bool isLocked = false;

    if (target != null)
    {
      isLocked = true;

      lockOnImage.transform.rotation = Quaternion.identity;

      // ターゲットの表示位置にロックオンカーソルを合わせる
      lockOnImage.transform.position = Camera.main.WorldToScreenPoint(target.transform.position);

      // 敵の体力をゲージに反映させる
      Enemy targetScript = target.GetComponent<Enemy>();
      gaugeImage.transform.localScale = new Vector3((float)targetScript.armorPoint / targetScript.armorPointMax, 1, 1);

      // 敵との距離を表示する
      textDistance.text = Vector3.Distance(target.transform.position, transform.position).ToString();
    }
    else
    {
      // ロックオンモード時はカーソルを回転する
      lockOnImage.transform.Rotate(0, 0, Time.deltaTime * 200);
    }

    lockOnImage.enabled = isSearch;

    // 敵の体力ゲージの表示を切替可能にする
    enemyAp.SetActive(isLocked);
  }

// (以下略)
  • その他実装部分

github.com

実行結果

www.youtube.com

感想

やったこと。

  • プレイヤーの残り体力によって体力ゲージの色を変える
  • ロックオンカーソルの表示
  • 索敵中にロックオンカーソルを回転させる
  • ロックオンした敵の体力ゲージと距離を表示する

ここらへんの内容はプログラミングの技術というより、ゲームを魅力的に演出するTips的な部分が大きくて、なかなか実践的で感心しながらすすめている。

ゲームを作るにあたって、こういう内容は本当に大事だと思うなぁ。
同じ内容のツイートでも漫画にしないと誰も読んでくれないもんね。(笑)

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

BGM

10 Balls + 2 / RHYMESTER feat. KICK THE CAN CREW

www.youtube.com

unityroomにユニティちゃんのライフゲームを投稿しました

うにのライフゲーム~たまにユニティちゃん~ | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう

f:id:yjkym:20180617184220p:plain

うにのライフゲーム~たまにユニティちゃん~

今日の学習分のデータが消えてしまって、投稿するネタがなくなってしまったので、unityroomに昔作ったライフゲームを投稿してみました。

ライフゲームってどれくらい認知されてるんですかね。
ほとんど知られてないのかな。

ライフゲーム - Wikipedia

個人的にはほぼ初めて自分でアルゴリズムを考えてイチから作ったのがC言語ライフゲームのプログラムだったので結構思い入れがあったりします。

よろしくお願いします。

『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter06 ユーザーインターフェースを作成する」 学習記録2

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

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

序文

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

徹夜明けで少しぼーっとしています。あ、寝たからだ。

GitHub

github.com

進捗

(学習時間:2時間)

コード実装部分

\Chapter1\Assets\Scripts\Marker.cs

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

public class Marker : MonoBehaviour
{
  Image marker;
  public Image markerImage;
  GameObject compass;

  GameObject target;

  void Start()
  {
    // PlayerTargetはプレイヤーの中心
    target = GameObject.Find("PlayerTarget");
    // マーカーをレーダー(コンパス)上に表示する
    compass = GameObject.Find("CompassMask");
    // マーカーイメージを取得して
    marker = Instantiate(markerImage, compass.transform.position, Quaternion.identity) as Image;
    // コンパスのマスクの子要素にする(各エネミーごとに実行される)
    marker.transform.SetParent(compass.transform, false);
  }

  void Update()
  {
    // マーカーをプレイヤーの相対位置に配置する
    Vector3 position = transform.position - target.transform.position;
    marker.transform.localPosition = new Vector3(position.x, position.z, 0);
    /*
    // レーダーの範囲外に出たら表示しない
    if (Vector3.Distance(target.transform.position, transform.position) <= 150)
      marker.enabled = true;
    else
      marker.enabled = false;
    */
  }

  // 敵が消滅したら敵のマーカーも消滅させる
  void OnDestroy()
  {
    Destroy(marker);  
  }
}
  • その他実装部分

github.com

実行結果

www.youtube.com 無駄に長い

感想

やったこと。

  • レーダー上に敵を表示する(離れたり、やっつけたらレーダー上から消える)
  • プレイヤーの体力を表示する

離れた敵を表すマーカーをレーダー上から消すのに

  • 敵とプレイヤーの距離を測って一定距離以上離れたら非表示にする
  • Maskコンポーネント使用してマスクの範囲外に出たら表示させないようにする

という2とおりの実装方法が説明されていた。

前者のほうが直感的であるけれど、後者のやり方で実装できることがプログラミングの実力なのだと思っている。

そのためにはいろんなソースコードに触れるようにするのが一番だ。
勉強勉強。

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

BGM

天然関係 / Sir Oriental Orchestra

www.youtube.com

『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter06 ユーザーインターフェースを作成する」 学習記録

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

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

序文

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

都民税のお知らせが来ました。128,000でした。(言っちゃう)

GitHub

github.com

進捗

(学習時間:2.5時間)

コード実装部分

\Chapter1\Assets\Scripts\Compass.cs

using UnityEngine;
using UnityEngine.UI;

public class Compass : MonoBehaviour
{
  public Image compassImage;

  void Start()
  {

  }

  void Update()
  {
    // 方角の回転
    // プレイヤーのY軸に対する回転をコンパスのZ軸回転に対応させる
    // transform.rotationはQuaternion角で表されているので
    // Euler角をQuaternion角に変換している
    compassImage.transform.rotation = Quaternion.Euler(compassImage.transform.rotation.x, compassImage.transform.rotation.y, transform.eulerAngles.y);
  }
}
  • その他実装部分

github.com

実行結果

www.youtube.com プレイヤーの向きとコンパスのUIが連動していることと、カメラの高さ(Z軸回転)を初期位置にリセットできるということを表現しようとしています

感想

やったこと。

  • 自動ロックオン機能の実装
  • カメラ角のリセット機能を実装
  • レーダーのUIを表示して、プレイヤーの向きと連動して回転させるように設定

回転を表すのにQuaternionに続いてオイラー(Euler)角というVector3で回転を表現しているらしい概念が登場した。

一応ちょっと調べてみたけど、当然ぱっと理解できるはずもなく。
まぁ…3Dはそんなに手出さないだろうから必要になった時に勉強しよう…。

参考書でもまったく説明なく使うだけ使っているので「こんなスペースで説明できるかい!」ということなのだろう。

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

BGM

POSH BOY / THE LOST CLUB
www.youtube.com

『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

『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter04 敵キャラクターを登場させる」 学習記録

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

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

序文

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

最近クリエイティブな作業をしていないのでモチベーション下がり気味。

GitHub

github.com

進捗

  • Part01 基本編
    • Chapter04 敵キャラクターを登場させる(途中)

(学習時間:2時間)

コード実装部分

\Chapter1\Assets\Scripts\Enemy.cs

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

public class Enemy : MonoBehaviour
{
  GameObject target;

  public GameObject shot;

  float shotInterval = 0;
  float shotIntervalMax = 1.0f;

  public GameObject explosion;

  void Start()
  {
    // ターゲットを取得
    target = GameObject.Find("PlayerTarget");
  }

  void Update()
  {
    // プレイヤーとの距離が近づくと攻撃してくる
    if (Vector3.Distance(target.transform.position, transform.position) <= 30)
    {
      // スムーズにターゲットの方向を向く
      // エネミーの向くべき方向を算出する
      Quaternion targetRotation = Quaternion.LookRotation(target.transform.position - transform.position);
      // スムーズに方向を変える。第三引数はスピード
      transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 10);

      shotInterval += Time.deltaTime;

      if (shotInterval > shotIntervalMax)
      {
        Instantiate(shot, transform.position, transform.rotation);
        shotInterval = 0;
      }
    }
  }

  private void OnCollisionEnter(Collision collider)
  {
    // プレイヤーの弾と衝突したら消滅する
    if(collider.gameObject.tag == "Shot")
    {
      Destroy(gameObject);
      Instantiate(explosion, transform.position, transform.rotation);
    }
  }
}
  • その他実装部分

github.com

実行結果

www.youtube.com カメラの操作が覚えられない人の図

感想

やったこと。

  • 敵が一定距離まで近づくと攻撃してくるように実装
  • 敵に弾が当たるように実装

Unityの操作ってオブジェクト指向プログラミングをGUIでやっているような感覚だと思った。

それぞれのオブジェクトやスクリプトが明確に分離されていて、それらを組み合わせてゲームを作っていく感覚が心地よい。

なるほどC#とは相性が良さそうだ。

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

BGM

初恋とはなんぞや / パブリック娘。

www.youtube.com ネタがなくなった

『Unity5ゲーム開発レシピ』「Part01 基本編 Chapter03 弾を撃つ」 学習記録

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

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

序文

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

ちょっと楽しくなってきました。

GitHub

github.com

進捗

  • Part01 基本編
    • Chapter03 弾を撃つ

(学習時間:3時間)

コード実装部分

\chapter1\assets\scripts\playershoot.cs

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

public class PlayerShoot : MonoBehaviour
{
  void Start()
  {

  }

  public GameObject shot;
  public GameObject muzzle;
  public GameObject muzzleFlash;

  float shotInterval = 0;
  float shotIntervalMax = 0.25f;

  void Update()
  {
    // 発射間隔を設定する
    shotInterval += Time.deltaTime;

    // 弾を発射する
    if (Input.GetButton("Fire1"))
    {
      // 間隔を開ける
      if (shotInterval > shotIntervalMax)
      {
        Instantiate(shot, muzzle.transform.position, Camera.main.transform.rotation);

        shotInterval = 0;

        // マズルフラッシュを表示する
        Instantiate(muzzleFlash, muzzle.transform.position, transform.rotation);
      }
    }
  }
}
  • その他実装部分

github.com

実行結果

www.youtube.com もう操作が俺の動作性IQで扱えなくなっている

感想

やったこと。

  • プレイヤーが弾にひっかからないように修正
  • 玉野発射位置の調整
  • 弾の消滅と各種エフェクト実装
  • 敵キャラクターの表示、つねにプレイヤーの方向を見るように設定

おー、割とそれっぽくなってきた。

パーティクルのエフェクト終了時にオブジェクトを破棄する処理

ParticleSystem particleSystem = GetComponent <ParticleSystem>();
Destroy(gameObject, particleSystem.duration);

が非推奨の古い書き方です。みたいなこと言われたのでどうしたらいいのかなーと思って調べてみたら、著者の方がしっかりブログで触れていらっしゃった。

cycling.hateblo.jp

ありがたいです。

「マズルフラッシュを作成するには」が果たしてTipsになりうるのか!?とかツッコミどころはありながらも割と楽しんでいる。

はやくオリジナルのアプリ制作に取り掛かりたい。

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

BGM

初恋とはなんぞや / パブリック娘。

www.youtube.com