パスワードを忘れた? アカウント作成
14941697 journal
日記

yumeの日記: Unity制作 メデューサ・ゲーム #17 1

日記 by yume

●鏡 再考

鏡の角度をとることで作ることはできたが、これはこれで置いといて、別のバージョンの魔法の鏡を作ろう。「配置するタイプの視界」だ。
次のような挙動にしよう:
・ステージ上にスプライトで置いてある。
・触れているときに何らかのキーを押すと「手に持つ」
・手に持っている状態で、もう一度キーを押すと、その場にその時点の視界を持った鏡を置く。
・鏡はプレイヤーと同じ挙動をする。再度拾って置きなおすこともできる。
プレイヤーと同じ邪眼の挙動をするために、また依存関係の整理が必要だ。ちょっとこれは無頓着すぎたなぁ。
ステージマネージャーに新たに邪眼管理コンポーネントを追加する。これは邪眼に必要なキャラクターのリストなどを保持する。
リストの増減は邪眼管理側で行い、ステージ上の各邪眼は邪眼管理にアクセスするだけでうまく動くようにする。
あ、FOVのリストの管理も同じ方式にしないとダメだ。
ちょっと整理してみると:
FOVマネージャー:FOVに必要な頂点座標リストを持つ。各ステージに1つある。
FOVコンポーネント:各ステージのプレイヤーや魔法の鏡が持つ。FOVマネージャーのリストを読み取り、FOV用のメッシュを作る。
EvilEyeマネージャー:キャラクターを検索し、邪眼に必要なキャラクターリストを持つ。各ステージに1つある。
EvilEyeコンポーネント:EvilEyeマネージャーにあるリストに基づいて、邪眼判定をCastする。
壁オブジェクト:ステージ開始時や壁の移動・生成時に、自分の持つ頂点座標をマネージャーに送る。
キャラクター:自分が削除されたり追加されたときに、EvilEyeマネージャーのリストを更新する。
とする。これで、FOVや邪眼そのものはマネージャーに依存するが、壁やキャラクターにはしない。壁やキャラクターもマネージャーにはアクセスするが、FOVや邪眼そのものにはアクセスしない。

ともかく整理はできたので、アイテムをピックアップ/設置する仕組みを作る。
プレイヤー側に新たにInventoryコンポーネントを作り、プレイヤーとステージ上の鏡との距離(複数ある場合もあるのでリストで)を毎フレームチェックする。
鏡側は設定した距離以内なら「ピックアップ可能」なことを示すためにスプライトを赤枠付きのものに変える。
プレイヤー側はピックアップキーを入力したとき、最も近い距離の鏡を保持し、対象の鏡を非アクティブ状態にする。
何かを保持しているときにまたキーを押すと、今度は非アクティブだった鏡をアクティブにし、角度を座標を更新する。

こんな感じ。

--

●スイッチ
「見ている状態ならON」、「見ていない状態ならOFF」にして、連動するドアなどのON、OFFを同期させる。
見ている限りONメソッドを実行し続ける……という方式だとものすごく無駄なので、「OFFからONに切り替わったときだけONメソッド」を動かす、逆もしかりという仕組みにしたい。
かなり試行錯誤したが、以下のような感じになった。

public bool isON = false; //視界にとらえると、毎フレームTrueにされる。
private bool isPrev = false;
private void FixedUpdate() //毎フレーム(厳密にいうともっと)実行される
{
        if(isON != isPrev)
        {
                FlipSwitch(isON);
                isPrev = isON;
        }

        isON = false;
}

private void FlipSwitch(bool flipTo)
{
        ///<summary>
        ///入力に応じて、スプライトや関連するもののON/OFFを同期させる。
        /// </summary>
        if(flipTo)
        {
                Debug.Log("open");
                //ONにする場合
                mySprite.sprite = onSprite;
                myDoor.OpenDoor();
                isON = true;
        }
        else
        {
                Debug.Log("close");
                //OFFにする場合
                mySprite.sprite = offSprite;
                myDoor.CloseDoor();
                isON = false;
        }
}

初めは「視界外や視野角外なら常にFlipSwitchメソッドを実行すればいいか(引数と現在のisONが等値なら即returnにすれば)」と思ったが、魔法の鏡の視界外=falseにし続ける、PLayerの視界内=Trueにし続ける、というのが毎フレーム同時に起こってわけわからなくなっていた。
これなら誰の視界であろうと、「誰かの視界内に入ったらTrueでFlipが実行」「誰かの視界内から外れて、だれの視界内でもなくなったらFalseでFlipが実行」ということが実現できた。
こんな感じになる。いいぞいいぞ!!

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • by Anonymous Coward on 2020年10月05日 10時29分 (#3900694)

    isONは書き換え・参照時にlockしとかないとまずくないかな?

typodupeerror

吾輩はリファレンスである。名前はまだ無い -- perlの中の人

読み込み中...