yumeの日記: Unity制作 メデューサ・ゲーム #32 2
ゲームは更新してない。
・猫を複数乗せられるように(そんなステージがまだないけど)
・猫が頭に乗るときに、ちょっとしたアニメーションを追加。
●レバー
近づいて触れて、インタラクトボタンを押すとレバーを押す
レバーが押されると関連したドアが開いたり閉じたりする、というものを作る。
すでに魔法の鏡を作っているので、まずこれと共通する基底クラス「ItemControll」を作ろう。
プレイヤーが近づくと、ItemControllのCheckInOut(bool)に是非を入力する。
Itemは近づいたとき・離れたときの挙動(アウトラインが表示されるとか)を行う。
今のところ鏡はスプライトを切り替えるだけ(アウトラインありなし2枚しかない)。
レバーはアウトラインスプライトの表示だけを切り替える。
ここまではよい。
ただ、インタラクトする対象を選ぶ過程がちょっと複雑だな。
プレイヤーがアイテムをすでに持っている場合:
レバーにインタラクト可能ならレバーをインタラクト
そうでないならアイテムを置く
持っていない場合:
レバーがあるならレバーの一番近いやつ
レバーがないなら、とにかく一番近いやつ
という具合になるのが自然だから、やはりこの順にはしたい。
アイテムがインタラクト範囲に入った時、インタラクト対象を選ぶ:
・インタラクト対象内にレバーがあったら:対象はレバー。
・ないなら、所持品がすでにあるならそれを選ぶ。
・ないなら、最も近いインタラクト対象を選ぶ。
うーんごちゃごちゃしてきた。整頓すると:
//すべてのアイテムとの距離を測定し、
//1.範囲内にレバーがあるなら、それがインタラクト対象(優先度2)。
//2.何かアイテムを持っているなら、それがインタラクト対象(優先度1)。
//3.範囲内にある最も近いものがインタラクト対象。
//4.インタラクト対象はない。
インタラクトする対象のメッセージテキスト(Pick upとかPull Lever)も適宜変えなければいけない。
ともかく、基底クラスをそのまま当てていた目玉スイッチのクラスを新たな派生クラスに差し替えて(基底switchからeyeSwitchへ)、
とかやってたら、全ステージの目玉スイッチの対象ドアを設定しなおすハメに……。
とにかく計画段階でもっと抽象的な概念をちゃんと考えておくべきだなぁ。なんにでも言えることだけど。
まだ少なかったからよかったけど……とか思ってたら「5ケタのダイヤル・ロック」で死にそうになった。
--
かなり複雑なことになってきたな……。いかんもうこんな時間だ。とにかくコードはこうなった:
private void CheckDist()
{
if (!canItemIntract) return; //getsetができないときはスルー
float closestDist = 100.0f;
int closestIndex = -1;
int nowPriority = 0;
if (holdItem != null) nowPriority = 1;
//hasIntractItem = false;
for (int i = 0; i < distances.Length; i++)
{
//すべてのアイテムとの距離を測定し、
//1.範囲内にレバーがあるなら、それがインタラクト対象(優先度2)。
//2.何かアイテムを持っているなら、それがインタラクト対象(優先度1)。
//3.範囲内にある最も近いものがインタラクト対象。
//4.インタラクト対象はない。
distances[i] = Vector2.Distance(transform.position, itemsObjects[i].transform.position);
if (distances[i] <= holdRange)
{
//アイテムが範囲内に入った
//hasIntractItem = true;
//優先度が現在値未満なら、無視。
if (itemControlls[i].interactPriority >= nowPriority)
{
//優先度が現在値以上なら
if (itemControlls[i].interactPriority > nowPriority)
{
//優先度が現在値を超えるなら、それを新たな対象の基準にする。
nowPriority = itemControlls[i].interactPriority;
closestDist = distances[i];
closestIndex = i;
}
else if (distances[i] < closestDist)
{
//優先度=現在値なら、これまでのものと距離をチェックし、現在最短ならそれを保持。
closestDist = distances[i];
closestIndex = i;
}
}
}
}
if (closestIndex != -1)
{
//インタラクト対象が所持品以外なら(-1以外なら何であれ所持品以外が対象になっている)
for (int i = 0; i < distances.Length; i++)
{
if(i != closestIndex)
{
itemControlls[i].CheckInOut(false); //対象以外の強調アウトラインを非表示
}
}
interactTarget = itemControlls[closestIndex];
interactTarget.CheckInOut(true); //対象の強調アウトラインを表示
}
else
{
if (nowPriority == 1)
{
//対象は所持品
if (interactTarget != null) interactTarget.CheckInOut(false);
interactTarget = holdItem;
}
else
{
//対象は無し
if(interactTarget != null) interactTarget.CheckInOut(false);
interactTarget = null;
}
}
}
こうなると「持っているアイテム」をミスティ自身にどうにかして表示する必要があるな(レバーに触れるときに「あれ持ってなかったっけ?」ってなるので)
あとレバーのアニメーションのオンオフ状態をSprite Resolverで切り替えているが、どうもこいつがうまく動かない。
exprementalだから使うのは諦めた方がいいのだろうか。全く動かないならともかく、わりとうまくいくこともそこそこあって困る。
アニメーション中にResolverを切り替えるのをやめて、各アニメーションで表示したいResolverをはじめと終わりにだけ指定したらなんかうまくいったのでこれでいく。
とにかく今日の成果はこんな感じ。
あれ? リバーススイッチのこと書いたっけ? まぁいいや。
今日やる予定だったこと全然やってないような。っていうかステージを思いついてもすぐ作らないと忘れてしまう。
日記もいつにもましてひどい散らかりぐあいだ。
優先度 (スコア:0)
あとから増やしたくなったり入れ替えたくなったりしたときのために列挙型の方がいいかな。
Re: (スコア:0)
あと列挙型は値指定したり同じ整数値を設定したりできるので、優先度のレベルじゃなくアイテムごと(レバーとか鍵とか)のレベルで設定するといいかも。