ブロックバスター制作資料

33
ブブブブブブブブ ブブブブ By Max Neet Games

Upload: maxneetgames

Post on 21-Feb-2017

800 views

Category:

Software


2 download

TRANSCRIPT

Page 1: ブロックバスター制作資料

ブロックバスター 制作資料By Max Neet Games

Page 2: ブロックバスター制作資料

注意事項 ( 言い訳 )

技術面では適当で汚い実装が多いので、参考にすべきかは微妙な感じです。( なら何故公開する!?)

このスライドの内容は過去作やブログで解説した事はあまり載せていませんので、良ければそちらも参照ください。 Farm Fury! 技術資料 幽霊の棲む家技術資料

Page 3: ブロックバスター制作資料

スライド概要 Max Neet Games について ゲーム紹介 開発環境 技術解説 使用アセット一覧

Page 4: ブロックバスター制作資料

チーム情報 Max Neet Games

( 訳 : Hatarakitakunai-De-Gozaruuuu!!)

活動概要 まったりとゲーム作ってます。きっと、多分、恐らく 作ったゲームの資料も公開していく予定

ホームページ http://maxneet.web.fc2.com/

メンバー 大熊猫 : プログラム、エゴサーチ、惰眠担当 まる : アート、雑用担当

Page 5: ブロックバスター制作資料

ブロックバスター紹介 プラットフォーム: Windows

プレイ人数 : 2~4人 ジャンル : 対戦アクション 想定プレイ時間 : 1試合35~125秒 コントローラー必須

Page 6: ブロックバスター制作資料

開発環境

Page 7: ブロックバスター制作資料

開発環境 ゲームエンジン

Unity5

ファイル管理 Dropbox 上に svn のリポジトリ作成し、 Dropbox のフォルダを共有

Page 8: ブロックバスター制作資料

技術解説

Page 9: ブロックバスター制作資料

入力周り

Page 10: ブロックバスター制作資料

入力周り コントローラー必須と割り切ったので、基本は XBOX コントローラー基準

基準にしているだけで他でも動きます 下記の物を改良しました

http://deciduousgames.blogspot.jp/2013/05/xbox-controller-input-wrapper-for-unity.html

改良点は主に XNA に近づける感じです ( 改悪の可能性有り )

コントローラーの各ボタンの enum を定義し、ゲームの入力状態を保持する構造体 (GamepadState) に各状態を保持する Dictionary<GamePad.Button, bool> で各ボタン(スティックの向きを含む ) 各スティックの状態も保持

Page 11: ブロックバスター制作資料

入力周り2 前のスライドを元に、入力管理クラスを作成 コントローラー4つを基準とし、各 GamePadState の現在のフレームと、前のフレームの状態を保持する

毎フレーム更新します 上記の状態を元に入力確認を行っております。

押されているか、このフレームに押されたか、離されたか 入力管理を別に作成したのはスティック方向も入力したフレームだけを確認したかったり、実装してませんがリピート入力も出来る様にしたかったからです。 ついでにリプレイでも使える様にしたかったからです。

Page 12: ブロックバスター制作資料

キャラの入力 キャラに各キーのアサインを設定するコンポーネントをアタッチしてます コントローラーのインデックスも設定 中で入力可能なボタンの種類も定義しています。

Page 13: ブロックバスター制作資料

キャラ入力コードの一部 public enum Type { Kick, Grab, Special, }

public GamePad.Index Controller = GamePad.Index.One;

public GamePad.Axis Move = GamePad.Axis.LeftStick;

public GamePad.Button KickButton = GamePad.Button.A;

public GamePad.Button GrabButton = GamePad.Button.B;

public GamePad.Button SpecialButton = GamePad.Button.Y;

Page 14: ブロックバスター制作資料

キャラ入力確認If ( InputManager.Instance.IsPressed(

InputSettings.Controller, InputSettings.KickButton))

{// … 処理

}

Page 15: ブロックバスター制作資料

キーコンフィグ やる事としては、前のスライドで紹介した入力設定 (InputSetting) に入る値を設定する

Page 16: ブロックバスター制作資料

キーコンフィグ 確認方法はコントローラーに入力が有るかを確認 有った場合は同じボタンが使われているか確認 使われていた場合、今設定しているボタンにアサインされているボタンと交換する

無かったらそのまま設定 キーコンフィグを抜けたらセーブしています。

セーブには通常の PlayerPref を使用 ゲーム開始時にセーブデータの設定を読み込んでます

Page 17: ブロックバスター制作資料

キャラの当たり

Page 18: ブロックバスター制作資料

キャラの当たり 基本的に Unityの BoxCollider2D と

Rigid Body2D を使っています。 キャラには自身と子オブジェクトにコライダーを付けてます。 自身はブロックや他のキャラ等の当たり、子オブジェクトにはステージの壁だけに対する当たりを付けています。 壁の当たりを別にしているのはキャラの当たりだと、体の上の方で移動が停止してしまうからです。 子オブジェクトは別のレイヤー設定にし、プロジェクト設定で当たりの確認を壁以外とはしない様にしています。

Page 19: ブロックバスター制作資料

ブロック連鎖

Page 20: ブロックバスター制作資料

ブロック連鎖 ブロックが他のブロックとぶつかった時に、爆発するかの確認を行っています。 処理としては、そのブロックの周りに接触しているブロックがあるか確認。 同じ確認処理を接触しているブロックにし、それを繰り返す。接触したブロックをリストに保存し、それが一定数(3個)を超えた場合、それらを爆発させます。

Page 21: ブロックバスター制作資料

ブロック連鎖処理1接触ブロックの確認には

Physics2D.OverlapAreaAll() を使用。 ブロックを専用のレイヤー設定にし、他のオブジェクトは確認しない様にしてます。 その中で同じ種類のブロックのみ接触リストに追加

Page 22: ブロックバスター制作資料

ブロック連鎖処理2 ( 接触確認 )

public void SearchCollidingBlocks(Block currentBolck, BlockType chainBlockType, ref List<GameObject> chainList) { Vector3 adjustments = new Vector3(0.1f, 0.1f, 0.0f); BoxCollider2D collider = currentBolck.GetComponent<BoxCollider2D>(); Collider2D[] colliders = Physics2D.OverlapAreaAll(collider.bounds.min - adjustments, collider.bounds.max + adjustments, m_layer); if (colliders == null || colliders.Length <= 0) { // 周りにブロックが無い return; }

Page 23: ブロックバスター制作資料

ブロック連鎖処理3 ( リスト追加 )

List<Block> toAdd = new List<Block>(); int count = colliders.Length; for (int i = 0; i < count; ++i) { Block block = colliders[i].GetComponent<Block>(); if (block == null || chainList.Contains(block.gameObject) || toAdd.Contains(block) ) { continue; }

if ( block.Type != chainBlockType ) { // 連鎖出来ない continue; }

toAdd.Add(block); chainList.Add(block.gameObject); }

Page 24: ブロックバスター制作資料

ブロック連鎖処理4接触リストを追加した後は確認処理を再帰的に繰り返す

int count = toAdd.Count; for (int i = 0; i < count; ++i) { SearchCollidingBlocks(toAdd[i], chainBlockType, ref chainList); } }

Page 25: ブロックバスター制作資料

ブロック連鎖処理5検索が終わったら実際に爆発させます

(検索処理呼び出し元) public void CheckChain() { List<GameObject> chainList = new List<GameObject>(); chainList.Add(gameObject); SearchCollidingBlocks(this, Type, ref chainList);

m_chainCount = chainList.Count; if (IsChain(m_chainCount)) { for (int i = 0; i < chainList.Count; ++i) { chainList[i].GetComponent<Block>().StartExplode(); } chainList.Clear(); } }

Page 26: ブロックバスター制作資料

リプレイ 主に展示用に実装しました

デジゲー博では不具合が出て使えませんでしたが・・・ なので、最適化とかはまったく考えてない作り

保存している情報 毎フレーム入力状態を保存 ブロックの生成時に位置情報を保存 試合設定と人数(キャラを含め )を保存

ファイルがそこそこ大きくなるので、保存は別にスレッドを作って行っています。 書き込みはC#のSystem.IO周りの物を使って実装

再生時の処理 キャラと試合設定を記録から指定 入力確認処理の戻り値を記録した物に変更する ブロック生成時の位置指定を記録した物に変更する

Page 27: ブロックバスター制作資料

リプレイ2 入力処理の上書き

private void UpdateCurrentState(int index) { if (Utility.IsPlayBack) { // リプレイ時 m_currentPadState[index] = BattleRecorder.Instance.GetPadState(index); } else { m_currentPadState[index] = GamePad.GetState((GamePad.Index)index + 1); } }

Page 28: ブロックバスター制作資料

UI(ゲージ類) uGui + UniRx で実装

UniRx は試しに使ってみただけだったりします・・・ キャラに ReactiveProperty<float> を保持させ、ゲージから Subscribe()を呼んでゲージ更新処理を登録しています。

ゲージにキャラの番号情報が有るので、それを元に登録 これでキャラの情報が変わったらゲージ更新処理が呼ばれます。

ゲージの表示にはスライダーを使用しています 上記で追加したゲージ更新処理で Slider.Value を設定しています Value は0~1なので、現在の値 /最大値の答えを割り当てています

Page 29: ブロックバスター制作資料

UIアニメーション

Page 30: ブロックバスター制作資料

UIアニメーション 基本スクリプトでごり押し!移動は iTween で実装、色は自前

色の変更をする方法が分からなかったので、自作のTween処理で行いました 毎回書くのは面倒なので、基本は似たパターンを使うようにし、ある程度パラメーター弄って調整出来る様に実装

Page 31: ブロックバスター制作資料

文字だけ色が変わらない問題位置やスケールは自動で反映されますが、色は子オブジェクトに反映されない為、画像と不一致になります。 解決策としては、アニメーションするオブジェクトに描画する子オブジェクトへの参照を持たせ、それらもアニメーションさせる Image や Text は UnityEngine.UI.Graphic継承しているので、 Graphic を探し、保持します

Page 32: ブロックバスター制作資料

子供の色を更新する処理protected Tweener<Color> m_colourTweener;protected UnityEngine.UI.Graphic[] m_childUIElements;private void FindAllChildUI(){ m_childUIElements = GetComponentsInChildren<UnityEngine.UI.Graphic>();}

void Update(){ if (m_colourTweener.IsActive) { m_colourTweener.Update(Time.deltaTime); UpdateColour(); }}

protected override void UpdateChildColour() { int length = m_childUIElements.Length; for (int i = 0; i < length; ++i) { m_childUIElements[i].color = m_colourTweener.CurrentValue; }}