Search

Computer House Random
Computer House Random
  • Randomについて
  • ブログ
  • Project
  • 作品紹介
  • 部員紹介

ゲーム制作_AimTarget

Unityについて真面目に語ります

ふじさん
最終更新 2020/12/01

はじめに

こんにちは,三回生のふじいです.
2020年の新歓イベントに向けて作ったAimTargetというゲームを紹介します.

目次
  • はじめに
  • 作品について
  • 頑張ったところ
  • 反省点
  • 技術的なお話
  • 余談

作品について

webが日本語対応していなく,ちょっと重いし,よくわからんことになってますが,できるひとはやってみててくださいまし. ゲームはこちら.

AimTargetはAim Labを丸パクリ,もとい参考にして作ったFPSエイム練習ゲームです.

ゲーム内にはエイム練習ができる三つのミニゲームがあり,それぞれ3ポイントゲーム,フリックゲーム,トラッキングゲームです.
全てのゲームに言えることですが,制限時間30秒の間にターゲットをFPS視点で正確に狙うことで高得点を目指すことでエイム練習をするのが目的です.

3ポイントゲームは,ある範囲内に出てくる3つのターゲットをモグラたたきのように狙うゲームです.ターゲットは弾が当たらなければ消えることはなく,範囲内に必ず3つ存在するようになっています.

フリックゲームは,現れては1秒ほどで消えてしまう1つのターゲットをモグラたたきのように狙うゲームです.

トラッキングゲームは,ランダムに動く一つのターゲットにエイムを合わせ続けるゲームです.

みんなで一緒につよつよエイムになりましょう.

頑張ったところ

  • できるだけすぐにゲームを繰り返せるように画面推移を無くして,スクリーンみたいなものを浮かしてそれを銃で狙うことでボタンを表現しました.これ結構頑張ったんですよ.ほんとに.
  • BGMとかあとカーソルとかをたくさん選べるようにしました.練習となると長時間やるのでできるだけプレイヤーにストレスを与えない方がいいと思ったので.
  • ターゲットが壊れるときのエフェクトもこだわりました.といってもアセットましましなわけですが… UnityのParticle Systemは奥が深そうですね(他人事).
  • FPS視点カメラをクォータニオンを使って制御しました.プレイヤーにカメラの子オブジェクトをつけてもよかったのですが,クォータニオンの練習のために頑張りました.
  • トラッキングゲームで,ターゲットが完全にランダムに移動するとフィールド外に出て行ってしまうのをどうにかして出ていかないようにしました.
  • Unityではオブジェクトにテクスチャをはっつけ,オブジェクトを大きくすると,テクスチャが引き延ばされてしまいます.今回はShaderを用いてテクスチャが引き延ばされないように解決しました.
    このゲームを作っているときに思い出したのですが,スーパーモンキーボールもこんな感じの手法を用いてたんだろうなと思いました.
  • 良いコーディングを目指して独立性・保守性を意識しました.といったものの可読性はあるのかよくわからないし,要素の独立性は高いものの高すぎると拡張時に加えないといけないコードが多くなり,加えてクラスは多いし難しいなあと感じます.

反省点

反省はしない,ポジティブに行こう.強いて言うならちょっとバグがあるくらい.さっさと作ればよかった…

技術的なお話

Unityの話を主に上記の頑張ったところについて真面目に長々とします.興味のある部分だけご覧ください.
・カーソルの色
・クォータニオン
・FPS視点
・マウスカーソルの判定

カーソルの色

カーソルの種類が10種類ほどあったと思いますが,すべてのカーソルは赤色になっています.ですが実際のところ,カーソルのための画像には赤色ではないものや,赤色であったとしても配色が微妙に違うものが含まれていました.
私はどうにかして同じ配色の赤色に統一したかったのですが,これをShaderで解決しました.
Shaderとは素材となる画像をどのように描画するかを記述したプログラミングです.
画像のグレースケールが一定以下,すなわち黒に近い色をすべて赤色にするというShaderをカーソルに当てはめることで解決しました.

クォータニオン

このページや このページを参考にしています.

クォータニオンとは,数学的には複素数を拡張した数体系であり$q = ai + bj + ck + d$で表され,$i^2 =j^2=k^2=ijk = -1$が成り立ちます.
つまり任意のクォータニオンは4次元ベクトル空間のベクトルで表され,数式で表すと$q = (a,b,c,d)$となります.

そんなことはどうでもよく,ゲームを制作する上では,クォータニオンは姿勢,もしくは回転を表すのに便利なものとしてだけ扱います.実際Unityではオブジェクトの姿勢を表す変数はクォータニオンになってます.クォータニオンはベクトルや他のクォータニオンに対する回転を表現することができ,数式で表すと以下のようになります. \begin{align} v’ &= q \otimes v \otimes \bar{q} \\
p’ &= q \otimes p \otimes \bar{q} \\
\end{align} \begin{align} q : 回転クォータニオン,v,v’ : ベクトル,p,p’:姿勢クォータニオン \end{align} つまり上のように掛けると,$v$は$q$だけ回転された$v'$に,$p$は$q$だけ回転された$p'$になったということです.
例えば,北を向いているプレイヤー姿勢$p$を東を向けたければ,右回りに90°回転するクォータニオン$q$を上のように掛けると,東を向いたプレイヤー姿勢$p'$となります.
Unityでは

v1 = q * v 
p1 = q * p

と,単に掛け算で表すことができます
また,ある軸$v$まわりにs回転するクォータニオン$q$をUnityでは以下のよう生成できます.

Quaternion q = Quaternion.AngleAxis(s,v);

うん,便利.

以上クォータニオンの説明でしたが,これを用いたFPS視点の実装の話に移ります.

FPS視点

FPS視点にて横向きの軸まわりの回転をピッチといいます.カメラが真上に向いたときピッチは90°なわけですが,この時制御がおかしくなりやすく,できれば真上は向かないようにしたいです.
作品の実装では左右に$yoko°$,上下に$tate°$回転させたいとき以下のように実装しました.

/* Transform pt : プレイヤーのトランスフォーム(playerTransform)
** Transform ct : カメラのトランスフォーム(cameraTransform)
** float pitch : 現在のピッチ
** float maxPitch : 最大ピッチ
*/
/***まず左右の回転***/
pt.rotation = Quaternion.AngleAxis(yoko, pt.up) * pt.rotation ;//左右にs°回転
/***次に上下の回転***/
pitch += tate ; //ピッチの計算
pitch = Mathf.Clamp(pitch, -maxPitch, maxPitch) ; //ピッチを最大ピッチ以下にする
Quaternion PitchQ = Quaternion.AngleAxis(pitch, tf.right) ; //ピッチの分だけ回転するクォータニオン
Vector3 viewForward = PitchQ * pt.forward ; //プレイヤーの向きを計算
ct.rotation = Quaternion.LookRotation(viewForward) ;  //プレイヤーをviewForwardの方に向かせる

なんだか難しい感じですが,ピッチ範囲を考慮したFPS視点の実装は,子オブジェクトにカメラを入れるだけでは難しく,クォータニオンを使った方が簡単だと思います.

マウスカーソルの判定

トラッキングゲームやボタンのような空中スクリーンでもマウスカーソルを乗せるだけで反応したり,マウスカーソルを外すと反応が消えたりなど細かい制御が必要でした.またそれぞれのオブジェクトが起きてほしい反応は違います.
私は今回,MousePointerとMousePointeeというコンポーネントを作り,MousePointerをPlayerに,MousePointeeを反応が起きてほしいオブジェクトに加えることで解決しました.
それぞれのComponentを以下に示します.ちなみにその実装に使っているUnityEventとはインスペクターでどのような関数を実行するかを決められるイベント変数です.

public class MousePointee : MonoBehaviour {
	public UnityEvent onEvent;         //カーソルが乗っているときのイベント
	public UnityEvent downEvent;  //カーソル上でマウスを押しているときのイベント
	public UnityEvent upEvent;        //カーソル上でマウスを離したときのイベント
	public UnityEvent clickEvent;    //カーソル上でマウスを押したときのイベント
	public UnityEvent offEvent;        //カーソルが離れた時のイベント
}
public class MousePointer : MonoBehaviour {
	void Update(){
		 MouseEvent();
	}
	void MouseEvent() {
	//カーソル方向にオブジェクトがあるかどうかを判定
		Physics.Raycast(cameraT.position, cameraT.forward, out mRaycastHit); 
		/*以下は簡単に言うと判定されたオブジェクトがMousePointeeを
		**持っているかを判定し,その判定により適したUnityEventを処理する
		*/
		if (!mRaycastHit.transform) {
			mMousePointee = null;
			mBeforeMousePointee = null;
			return;
		}
		mMousePointee = mRaycastHit.transform.GetComponent<MousePointee>();
		if (mBeforeMousePointee != null && mBeforeMousePointee != mMousePointee) {
			mBeforeMousePointee.offEvent.Invoke();
		}
		if (mMousePointee == null) {
			mBeforeMousePointee = null;
			return;
		}
		mMousePointee.onEvent.Invoke();
		if (Input.GetMouseButton(0))
			mMousePointee.clickEvent.Invoke();
		if (Input.GetMouseButtonDown(0))
			mMousePointee.downEvent.Invoke();
		if (Input.GetMouseButtonUp(0))
			mMousePointee.upEvent.Invoke();
		mBeforeMousePointee = mMousePointee;
		return;
	}
}

独立性・拡張性

コードの独立性・拡張性などを意識していた結果,大量にUniRx(Unity用ライブラリ)を使いまくっていて,その説明をしようと思ったのですが
ブログを書くのに疲れてしまいました(;・∀・).また今度書くかもしれません.

余談

もともとC++でフレームワークを作り,ゲームを作ろうとしていましたがさすがに時間が無いですね,というか作れる技量がないです.
Unityさいこー.

UNITY ゲーム制作 ゲーム 作品紹介 記事を共有
Avatar
ふじさん

わーーーい

    Computer House Random はパソコンによる創作活動を行っている大阪府立大学の部活動です

    Avatar
    ふじさん

    わーーーい

      UNITY ゲーム制作 ゲーム 作品紹介 記事を共有

      News

      コンピュータハウスランダムってどんな部活?

      【1日目】5分でわかるランダムのこと
      NEGI
      最終更新 2020/04/18

      はじめまして、らんだむちゃんです!

      自己紹介と最初の動画
      らんだむちゃん
      最終更新 2020/03/19

      作品紹介

      海中探検に出発!

      #ライザのアトリ絵
      IK
      最終更新 2020/12/01

      らんだむちゃんライブのパネルを担当しましたが

      Three.jsでライブしてみた
      ATsU
      最終更新 2020/12/25

      新入生歓迎イベント備忘録

      作品紹介とかも含む
      Ryo
      最終更新 2020/12/30

      Tag Cloud

      新歓ブログリレー2020 (37) 作品紹介 (32) 競技プログラミング (22) 競プロ勉強会 (21) 雑談 (15) 新入生歓迎イベント (14) らんだむちゃん (13) ゲーム (11) UNITY (9) グラフィック (9)

      最新の投稿

      重力付四目並べ

      Petrichor256
      最終更新 2020/12/13

      3d one minutes shooting

      3dシューティング
      kazetta
      2020/12/01

      ランチャー制作について

      反省文
      pngn
      2020/12/01

      オセロ作りました

      時間がないからコードで埋めた記事
      Haniwa
      最終更新 2020/12/01
      READ MORE

      関連記事


      新入生歓迎イベント備忘録

      作品紹介とかも含む

      Avatar

      らんだむしゅーてぃんぐ

      unityで弾幕STG作ってみた

      Avatar

      敵をいっぱい倒せたらすごいゲーム

      誰もプレイできなかった幻のゲーム

      Avatar

      BEDROCK MAZE (ver.0.6.2)

      ~マイクラで迷路をつくろう!~

      Avatar

      作品紹介 - といれっと☆へる

      【5日目】白鷺祭で作ったゲームについて

      Avatar

      Webで遊べる! ゆかりさんのゲーム

      作品紹介「Gift for Yukari 3」- カードゲーム

      Avatar

      Random
      Randomについて
      ライセンス
      Privacy Policy
      お問い合わせ
      部員専用サイト
      Project
      新歓2020
      競プロ勉強会
      Web
      らんだむちゃん
      ブログ
      作品紹介
      LT会
      グラフィック
      DTM
      タグ一覧
      Copyright © 2020 Computer House Random
      引用
      コピー ダウンロード