【開発メモ】体力0でミスとなった場合の処理の実装

というわけで、最近Googleアナリティクスを見ていると、「モグフィー」という検索ワードで来る方がいるようです。
自分としてはブログ3キャラの内の1匹に適当に付けた名前なのですが、どうやら離乳食の製品名と被ってしまっていたようです。
半分検索妨害のような感じですが、今更被ったからと名前を変えるのもアレなので、このまま行かせていただきます!

今回は「体力がなくなりミスとなった時」の処理について考えてみます。
前回の「落下時のダメージ処理」に続き、ゲームとしての体裁を保つためには必須の処理ですね。

shot2ss20160723090956792

要するに「体力なくなって死んだとき」の処理ですが、直接死亡と書くのはこの手のゲームでは避けたいので、ミスと表記することにします。
「倒れた」とか「ちからつきた」とかそんなニュアンスです。
最近のRPGでは「戦闘不能」とか「気絶」とかで、死亡扱いしているのはドラクエや硬派なゲームだけな気がします。

前回の記事はこちらになります。

【開発メモ】ステージ外へ落下した際の処理について

ミスとなった場合の処理

ゲームとしてはシンプルにゲームオーバーにします。
但し無限にコンティニューが可能で、コンティニューした場合は体力を全回復させて復帰させます。

コンティニューをしなかった場合はタイトルにでも飛ばせば良いでしょう。
まだまともなタイトル画面は作っていませんが・・・。
ちなみに Unity5.3 からシーン遷移が Application 系から SceneManager を使ったものに変わっているようなので注意します。

キャラクター的にはフラフラと倒れるようなアニメーションをさせればそれっぽくなりそうです。
また当たり前ですが、体力が0になった段階で操作できなくする必要があります。
とりあえず CharacterControoler の canControl をfalseに設定して動けないようにはしておけば、最低限の体裁は整えられそうな感じ。

ゲームオーバー時のUI作成

まずゲームオーバー時のロゴを作ってしまいます。
GIMP で適当にやります。

20160723_gameover

ゲーム開発ってデザインセンスも求められるわけですよ。
自分の水準以下のデザインセンスでこの先ゲームを作っていけるのか心配になってきます。
そんなクオリティです。
まあキャラクターデザインとかも割と適当なので、今に始まったことではありませんが。

shot2ss20160723091447812

最低限必要なものはゲームオーバーのロゴ、コンティニューボタンとENDボタンです。
それだけでは不親切なので、コンティニューボタンとENDボタンの説明文なんかも欲しいところです。
ロゴはただの画像なので配置するだけですが、コンティニューボタンとENDボタンは押下時にイベントを走らせる必要があります。
なので UI の Button として作成します。

shot2ss20160723091050222

ゲームオーバー専用の UI としてまとめて管理したいので、上のように空オブジェクトの子にしました。
その場合、親となる空オブジェクトも Transform から RectTransform にしておいた方が良いようです。

shot2ss20160723092244763

uGUI であればクリック時の処理や各種イベント処理が簡単に登録できます。
UI 上から実行したいスクリプトのオブジェクトとメソッドを選択するだけ!
OnGUI() で頑張っていた4.1の頃と比べると便利になったものです。

ボタンが反応しない場合、ヒエラルキーに「EventSystem」が存在するか確認します。
ない場合、メニューバーから「GameObject→UI→EventSystem」で追加します。

shot2ss20160723091142622

そのまま実行すると例外が発生し、「Input Button Submit is not setup.」とか言われます。
Standalone Input Module の各項目に対応する入力が InputManager 上に存在する必要があります。
上記エラーの場合、InputManager で新しく「Submit」を作成するか、モジュールの項目名を InputManager に存在する入力の何れかに変更して対応します。

ゲームオーバー時のスクリプト処理

ゲームオーバー時の処理の UI 制御をまとめたスクリプトを作成します。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
using System.Collections;

/// <summary>
/// ゲームオーバー時のUIを制御するクラス
/// </summary>

public class GameOverUI : MonoBehaviour {

    private Text description;
    private StageManager stageManager;

    void Start () {
        stageManager = GameObject.Find("StageManager").GetComponent<StageManager>();
        description = transform.FindChild("MenuDescription").GetComponent<Text>();
    }

    /// <summary>
    /// コンティニューボタンを押下した際の処理
    /// </summary>
    /// <param name="continueButton"></param>
    public void OnClickContinue(GameObject continueButton) {
        stageManager.toContinue();
        Destroy(this.gameObject);
    }

    /// <summary>
    /// ENDボタンを押下した際の処理
    /// </summary>
    public void OnClickEnd() {
        stageManager.toEnd();
    }

    /// <summary>
    /// コンティニューボタンにカーソルを合わせた際の処理
    /// </summary>
    public void OnPointerEnterContinue() {
        String message = YamlUtility.getMessageValue("gameover.continue");
        description.text = message;
    }

    /// <summary>
    /// ENDボタンにカーソルを合わせた際の処理
    /// </summary>
    public void OnPointerEnterEnd() {
        String message = YamlUtility.getMessageValue("gameover.end");
        description.text = message;
    }

    /// <summary>
    /// コンティニューボタンからカーソルを離した際の処理
    /// </summary>
    public void OnPointerExitContinue() {
        description.text = null;
    }

    /// <summary>
    /// ENDボタンからカーソルを離した際の処理
    /// </summary>
    public void OnPointerExitEnd() {
        description.text = null;
    }
}

どうしても関数が多くなってしまうので、コメントをしっかり書いて分かるようにしておきます。
Visual Studio ならスラッシュ3回入力で自動的にsummaryが入ってくれるのでラクラクです。

メッセージにある Yaml 系に関しては以下の記事をご参照下さい。

【Unity】YAMLファイルの読み込みと表示用メッセージの管理

UI 制御とは別で、ゲームオーバー時やコンティニュー時の処理を行うマネージャクラスを作成します。
ステージ上のゲーム進行を担うので、「StageManager」と命名してみました。
GameOverUI から呼ばれた処理はこちらで行います。

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

/// <summary>
/// ステージの進行・状態を管理するマネージャクラス
/// </summary>

public class StageManager : MonoBehaviour {

    public GameObject playerPrefab;
    public Transform checkPoint;
    public GameObject gameOverUI;
    private GameObject canvas;

    private GameObject playerObject;
    private Player player;

    void Awake() {
        playerObject = Instantiate(playerPrefab, checkPoint.position, Quaternion.identity) as GameObject;
        player = playerObject.GetComponent<Player>();
    }

    void Start () {
        canvas = GameObject.Find("Canvas");
    }

    public void toGameOver() {
        GameObject gameOver = Instantiate(gameOverUI) as GameObject;
        gameOver.transform.SetParent(canvas.transform);
        gameOver.GetComponent<RectTransform>().localPosition = Vector3.zero;
    }

    public void toContinue () {
        player.initToContinue(checkPoint.position);
    }

    public void toEnd() {
        // タイトル画面に戻す
        SceneManager.LoadScene("title");
    }
}

プレイヤーキャラの処理は Player クラスに initToContinue() メソッドを作っておき、それを呼んで処理させます。
いろいろ処理が絡み合っているので割愛しますが、スタート地点への移動や無敵判定の解除、パラメータ類のリセットを行っています。

あとは死んで動作チェック!
プレイヤーの体力100に対し、接触時の被ダメを1000に設定した無慈悲なウニに突撃してテストします。

20160723_01

死亡するとゲームオーバー画面が表示されること、プレイヤーが動かせなくなること、コンティニュー押下時にスタート地点へ戻されることを確認します。
GIFアニメーションにこれら全て入れるのは難しかったので、画像的にはぶっ倒れるマリンパだけですが・・・。
とりあえず動作に問題はなさそうです。

チェックポイントの作成

基本的に復帰地点はスタート地点ですが、チェックポイントに触れていればそこから再開にします。
これまたアクションゲームではよくあるシステムです。
中間ポイントのようなものを設けるのが手っ取り早いですが、どこまで進むとチェックポイントを通ったか分かりにくいので、私的には好きな形式ではないです。

となれば、チェックポイントと分かるようなオブジェクトが必要ですね!
これまた適当に作ります。

shot2ss20160723091606072

貝殻!
某ヒトデのマリンアクションもチェックポイントは貝殻だった気がします。
マーメイドとかそれに類するものは入っていないので問題ないかと思われます!
触れたのか分かりやすくするため、アニメーションで貝殻を開くようにしておきます。

で、貝殻にチェックポイント用のスクリプトを追加します。

using UnityEngine;
using System.Collections;

public class CheckPoint : MonoBehaviour {

    public Transform returnPoint;

    private StageManager stageManager;
    private Animator animator;

    void Start () {
        stageManager = GameObject.Find("StageManager").GetComponent<StageManager>();
        animator = this.GetComponent<Animator>();
    }

    void OnTriggerEnter(Collider c) {
        if (c.gameObject.tag == "Player") {
            animator.SetTrigger("open");
            stageManager.checkPoint = returnPoint;
        }
    }
}

貝殻に触れるとパカっと開き、コンティニュー時の復帰地点を触れた貝殻にします。
貝殻自体を復帰地点に登録すると地形にめり込んでしまうので、復帰地点用の空オブジェクトを指定し、そこに戻すようにしています。
見た目が猛烈に地味なので、そのうちエフェクトとか付けます!

まとめ

そんなわけで、ミス時の処理とゲームオーバー処理について作ってみました!
これで最低限のゲームとしてのルールはできたと思われます。
この状態でステージ上に敵やトラップを配置すればそれっぽくはなるので、そこまで作ってしまいたいです。

にしても uGUI は使いやすいですね!
特にイベント系の処理が簡単に実装できるようになったので、メニュー画面などの複雑なUIの作成も捗りそうです。

富士見高原リゾート「花の里」へ行ってきました!

というわけで、最近ゲーム開発そっちのけな記事が続いている気がしますが、お出かけシリーズになります!
今回は富士見高原リゾート「花の里」へ行ってきました!

CIMG2039_R

以前鹿の湯へ行ったのと同様、南アルプスICから双葉JCT~小淵沢ICまでいきます
小淵沢ICから富士見高原リゾートまでは6kmほどです。
鹿の湯の様子は以下をご参照下さい。

富士見高原 八峯園鹿の湯へ行ってきました!

ちなみに花の里の公式サイトで割引クーポンが公開されています。
印刷して持っていけば安くなるので、これから行く方は持っていくことをおすすめします。

http://hanano-sato.jp/guide/general/coupon.html

主に「ロマンスエリア」「白樺エリア」「展望エリア」の3つで構成せれていました。
本命は白樺エリアの百合ですが、一通り回ってみました。

以下、エリア毎に撮った写真を載せてきます!

ロマンスエリア

CIMG2046_R

CIMG2047_R

CIMG2050_R

一面のヒャクニチソウやサルビアが並ぶ広いエリアです。
量は十分ですが、時期が早かったのか個々が小さかったです。

CIMG2080_R

エリア内で見るより登りリフトで上から見たほうが綺麗です。
スキーリフト自体7年振りくらいだったりします。

白樺エリア

百合と白樺があるエリアです。
入口にはアジサイも咲いていました。

CIMG2054_R

CIMG2056_R

本命の百合はまだちょっと早いかなーと思いつつも、そこそこ咲いていました!
以下、ひたすら百合の写真です。

CIMG2060_R

CIMG2068_R

CIMG2072_R

CIMG2074_R

CIMG2075_R

展望エリア

スキーリフトに乗って一気に上まで登ります。
小型な上に背もたれが小さめでなかなか怖かったです。

CIMG2082_R

頂上付近から撮った写真です。
正に高原という風景と、心地よい風が絶妙でした。

CIMG2086_R

CIMG2089_R

展望エリアにも百合があるようです。
こちらの方が花の1つあたりが大きかったです。

まとめ

というわけで、富士見高原リゾート方面へ行ってきました!
暑い日が続くこの季節、避暑も兼ねて高原へ行くのもオツなものです。
山梨は内陸の県故にそういった観光地には困らないのが長所?かもしれません。

【ボウリング】ラウンドワンの初心者ボウリング教室にいってきました!

というわけで、マイボールを作って以来定期的にボウリングをやっているりべるんですが・・・。
作った当初こそアベレージ120とかだったものの、今は90いけるかどうかというレベルになってしまいました。
特に球速のなさが致命的で、8km前後のへなへなボールではフックボールも何もありません。

ボウリング上達の本も買い、フォームを直そうとしたのですが、まあ上手くいかないものです。
変に意識して普通に投げられなくなってしまったのも問題です。

DSC_0225

ここまで来ると自分ではどう直せば良いか分からないため、ラウンドワンの初心者教室に行くことにしました。
山梨県内では石和にしかないので、6月にキャンペーンボールを作ったのと同じラウンドワンになります。

申し込み~当日まで

ラウンドワン公式曰く「周1~3回、1回10人まで」とのことですが、山梨石和店のページをみても予定などが書いていません。
電話してみると、「インストラクターとお客様の都合に合わせて決める」と言われました。
要するに予約制ってことですね。

また、ラウンドワンには似たようなものとして「初心者フリー練習会」「健康ボウリング教室」などがあります。
予約するとき非常に紛らわしいので注意が必要です。
前者はティーチングなどが一切ない投球会、後者は高齢者向けの健康面の説明を含んだ教室らしいです。

前売りのチケットを買うと安くなるようですが、そもそも家から遠いため行くだけでも大変です。
ガソリン代だけで数百円掛かってしまいそうなので見送ることに。

レッスン内容と感想

予約が自分1人だったためか、インストラクターの方とマンツーマンでのレッスンでした。
どうやら前にキャンペーンボールをドリルしてくれたのと同じ方だったようです。

いろいろとアドバイスを受けたり聞いたりしながら進めたので、実際の練習投球は10回ほどでした。
目的は「正しいフォームとそれに近づけるための方法」を知り、練習する際のコツを掴むことです。
以下、自分が指摘された部分や聞いたことを簡単に書いていきます。

・右足の側面を基準に立ち位置を変える
ボール投球後にポケットに対して曲がりすぎた場合、床の木目数個分左右にずらして調整します。
狙う位置は変えず、右から2番目のスパット固定です。

・脇を閉める
今までの自分の悪い癖その1。
リリースする際に脇が開いてしまっているため、コントロールがブレているようです。

20160716_01

上の画像はインストラクターの方に撮ってもらったものです。
確かに脇が開いてしまっており、そのまま右ガターに一直線です。
かなり体に染み込んでいる悪い癖なので、きゅっと閉めて投げることよう気を付ける必要があります。

・投げ終わった後に左足の側面を確認する
「投げ始めと投げ終わりで位置がずれている」ことがあります。
投球後の位置・ポーズを確認し、前へ移動できていることを確認する必要があります。

・右足は左足へ重心を移動させると同時に左へ蹴る
今まで右足を蹴るどころかクロスすらさせていませんでした。
左足へ重心を運ぶのと同時に右足を左側へ蹴ります。
頭とボールの垂直ラインを同一にするためにも重要なことらしいです。

・左手は2歩目でやや下、3歩目~終わりまでまっすぐ左側に伸ばす
今までの自分は左手が空気同然でした。
左手を伸ばすことで、右側から左側へ体重移動した際のバランスを保つらしいです。
また、意識しすぎて最初から左手を真横にピーンと伸ばしていたりしたので、タイミングにも気を付けます。

・リリース後の右手は顎の前まで肘を曲げない
今までの自分の悪い癖その2
リリース後の右手のフォロースルーで、顎の前どころかそれ以前の段階で肘が曲がってしまっていました。
頭の前あたりまで伸ばしたまま上げてから、耳のあたりで振り抜きつつ曲げるのが自然な形とのこと。
逆にこれを意識して投げると、真っ直ぐ綺麗なボールが投げられた・・・気がする。

・リリース後の右手が左側へ捻ってしまっている
左側へ捻っているということは、「2番スパットへ真っ直ぐ投げれていない」ということになります。
右肩を基点として2番スパットまで一直線に振り抜く必要がありそうです。

20160716_02

改めて見るとなかなかいい捻りっぷりです (白目)
フックボールで回転を掛けようとするとよくなってしまう気がします。

・球速について
冒頭で懸念店としてあげていた球速ですが、聞いてみると「球速意識するよりフォームとコントロールを意識しろ(要約)」とのことでした。
しっかりしたフォームとコントロールで慣れていけば「それなりには」速くなるそうで。
インストラクターの方曰く、アベレージ150くらい出せるようになってからでも遅くないそうです。
ということなので、自分のへっぽこボールもフォームと投げ方を意識すれば変わる・・・のかも。

終わった後の感想としては、「1時間の初心者向け教室」と考えれば十分かなーと思いました。
やはり1投1投の良い点/悪い点を指摘・解説してくれることが大きく、どのように投げ方を修正すれば良いかが分かりやすかったです。
自分のように「今のフォームをどう修正すれば良いか分からない」という人にはオススメできる内容です。

まとめ

そんなわけで、ラウンドワンの初心者ボウリング教室に行ってみました!
予約が必要な分面倒ですが、自分の直すべき点・気を付ける点も分かったので、そういった意味では十分目的を達成できたレッスンだったと言えます。

あとは正しいフォームと投げ方に近づけられるよう、ひたすら練習あるのみですね!
一度に複数のことをやるのは難しいですが、このフォームで自然と投げれるようになりたいです。

【PHP】Symfony2のFormBuilderにデフォルト値を設定する方法

※投稿時の Symfony のバージョンは 2.7.9 、EC-CUBE のバージョンは3.0.10です。

というわけで、今回は PHP のフレームワーク Symfony2 に関するメモです。
仕事で使っている関係上いろいろと詰まることがあり、今日もちょっとしたことで詰まってしまいました。
主に「EC-CUBE3」で使っているので、それを元にして書いておきます。

shot2ss20160714205855672

やりたかったことは「FromBuilder の時にデフォルト値を設定する」です。
(プレースホルダとは別で、画面表示時からフォームに値が設定されている状態です)
普通なら getForm() した後に setData() すれば問題ないのですが、EC-CUBE のフックポイント的に FormBuilder の状態でいじれると便利だったりします。

テストとして、会員登録画面の「生年月日」欄の年をデフォルトで「2000」にしようと思います。
そこでこんなコードを書きましたが、フォームにデフォルト値として設定されません。

$Customer = $app['eccube.repository.customer']->newCustomer();

$builder = $app['form.factory']->createBuilder('entry', $Customer);
$builder->get('birth')->get('year')->setData(2000);

ぐぐったらスタックオーバーフローにそんな話題がありました。

http://stackoverflow.com/questions/18870866/symfony-2-3-form-getdata-doesnt-work-in-subforms-collections

setDataLocked() なる関数でロックしてあげないと getForm() 時に消える(?)らしいです。
ならこれでロックすればOKですね。

$Customer = $app['eccube.repository.customer']->newCustomer();

$builder = $app['form.factory']->createBuilder('entry', $Customer);
$builder->get('birth')->get('year')->setData(2000)->setDataLocked(true);

shot2ss20160714205839398

今度はデフォルト値としてしっかり入りました!
値を変えて確認画面に行ってもちゃんと変わったので、大丈夫かと思われます。

ちなみに getForm() 後であれば普通に $form->get(‘フィールド名’)->setData() で設定できます。
但し handleRequest() してしまうと変えられなくなります。
また、「プラグインからフックして設定する」などの理由がなければ Type クラスの $buider->add() のオプションで指定しまう方が確実です。

まとめ

そんなわけで、Symfony2 の setData() に関するお話でした。
Symfony2 は初見ではとっつきにくい割に日本語サイトが少ないので厳しいです。
EC-CUBE3 のフレームワークとしても使われているので、もっと日本語サイトも増えてくれるといいなーなんて思います。

ゲーム開発とは関係ありませんが、今後も何か詰まったことがあったらメモして忘れないようにしたいです。
特に PHP は一生付き合っていく言語になりそうなので、尚更ですね。
そもそもゲーム開発だけでは話題が続かなくなってきているので、いろいろ話題を織り交ぜていくブログに方向転換しようかと思います。

カテゴリー PHP

【開発メモ】ステージ外へ落下した際の処理について

というわけで、今回はタイトル通り、「ステージ外へ落下した際の処理」について考えてみます。

shot2ss20160713230800516

この処理がないと落下しても亜空間を移動できたり、落下後に復帰できなくなってしまいます。
ゲームとしての体裁を保つためには必須の処理ですが、全然作っていなかったので実装してしまおうと思います!

実際の処理はゲーム内容によって大きく異なる部分かと思われます。
落下時は即死するのか、ダメージを受けるだけなのか、その場合どこに戻されるのか・・・とかですね。
まあ見ての通り堅苦しいゲームではないので、ペナルティは軽めにする予定です。

判定用オブジェクト作成とスクリプト設定

「落下時は一定ダメージを受けて特定の地点へ移動」 で実装してみます。
残機というシステムを入れるつもりがないこと、その上で落下=即死では難易度が高くなると感じたためです。

shot2ss20160713231310804

まず、「触れると落下した扱いになる」判定を作ります。
落下判定をする場所に配置する他、ステージ全体の下に大き目の判定で配置し、イレギュラーな挙動をしてしまった場合でも落下扱いにして戻ってこれるようにします。

次に「落下後に戻される場所」として空のオブジェクトを作成し、上で作成した判定の子オブジェクトにします。
子オブジェクトにしなくても問題はありませんが、セットで管理しやすくなるのでオススメです。
戻ってくる位置として使うだけなので、Transform 以外のコンポーネントは不要です。

その後、判定を作ったオブジェクト(=親オブジェクト)にスクリプトを設定します。

using UnityEngine;
using System.Collections;

public class DamageReturnArea : MonoBehaviour {

    public float power;

    private Transform returnPoint;

    void Start() {
        returnPoint = transform.FindChild("ReturnPoint");
    }

    private void OnTriggerEnter(Collider c) {
        string tag = TagUtility.getParentTagName(c.gameObject);

        if (tag == "Player") {
            c.GetComponent<Player>().forceDownDamage(this);
            StartCoroutine("returnCharacter", c.gameObject);
        }
    }

    private IEnumerator returnCharacter(GameObject character) {
        yield return new WaitForSeconds(1f);

        character.transform.position = returnPoint.position;
    }
}

TagUtility に関しては以下の記事をご参照下さい。

【Unity】タグの階層表示と判定方法について

判定に入ったのがプレイヤーキャラだった場合は StartCoroutine() を実行し、一定時間後に returnPoint に戻します。
ダメージ処理は forceDownDamage() から Player クラスで行っています。
Player クラスまで載せると長い上に他と絡み合っていて面倒なので、ここでは割愛します。

ちなみにエリアとして作った関係上、マグマや針びっしりの床などでも同様の処理ができます。
一般的なアクションゲームでよくある即死トラップ系はステージ外落下と同じ扱いにしてしまう予定です。

落下時のカメラワークについて

現状のカメラアングルはプレイヤーの位置に合わせて追従します。
mainCamera をプレイヤーと同位置に追従させているオブジェクトの子オブジェクトとして設定し、位置・角度を調整しています。
そのスクリプトは以下の記事に載せてあります。

【Unity】「ProBuilder Basic」を使ったシンプルなステージ作成

ただし、落下時にカメラに対して何も処理をしていないため、落下後も追従しっぱなしです。
この手のゲームでステージ外落下後もプレイヤーを追従するカメラなんてほとんどないでしょう。

そんなわけで、落下判定に触れた際はカメラをプレイヤーを追従しないようにします。
今は CameraController というスクリプトからカメラを制御しており、上記の追従もここで行っているので、フラグを持たせて切り替えてしまいます。
上で載せたスクリプトを少し修正します。

using UnityEngine;
using System.Collections;

public class DamageReturnArea : MonoBehaviour {

    public float power;

    private Transform returnPoint;
    private CameraController cameraController;

    void Start() {
        returnPoint = transform.FindChild("ReturnPoint");
    }

    void Update() {
        cameraController = GameObject.FindGameObjectWithTag("PlayerManager").GetComponent<CameraController>();
    }

    private void OnTriggerEnter(Collider c) {
        string tag = TagUtility.getParentTagName(c.gameObject);

        if (tag == "Player") {
            c.GetComponent<Player>().forceDownDamage(this);
            StartCoroutine("returnCharacter", c.gameObject);

            // カメラアングルを固定
            cameraController.fixCamera = true;
        }
    }

    private IEnumerator returnCharacter(GameObject character) {
        yield return new WaitForSeconds(1f);

        cameraController.fixCamera = false;
        character.transform.position = returnPoint.position;
    }
}

カメラの方はフィールドに fixCamera を追加し、「transform.position = player.transform.position」の前に if 文を追加して制御します。
以下は CameraController の Update() 内です。

void Update() {
    // キャラクターを見失った場合再取得
    if (player == null) {
        player = GameObject.FindGameObjectWithTag("Player");
    }

    if (!fixCamera) {
        transform.position = player.transform.position;
    }
}

最終的にはこんな感じになりました!

20160714_01

よくあるアクションゲームのようなカメラワークになった気がします。
とりあえず十分な出来です。

まとめ

そんなわけで、落下時の処理について考えてみました!
実装の雰囲気だけ見ると、「メトロイドプライム」シリーズや、「伝説のスタフィー」シリーズの処理に似ています。
(後者はエリアの初めまで戻るので、そこまで似ているわけでもないかも)
まあ最近のゲームはダークソウルとか硬派なものを除くと、どれもこんな感じだったりしますが。

今日のイラスト

久しぶりにランパを描いてみました。
イラストを描くこと自体が数ヶ月ぶりだったりします。
何かバランスが変ですが、パッと見の出来はまあまあな感じ。

ranpa30

そのうちTwitterで「ランパの台詞集bot」みたいなものを作ろうかと考えていたりします。
いろいろと下準備が必要になりそうなので、暇なときにやっていく感じ・・・でしょうか。