読者です 読者をやめる 読者になる 読者になる

AIプログラムとかUnityゲーム開発について

探索や学習などを活用したAI系ゲームを作りたいと思います。

FTLみたいなものを作ってみる(8) 敵艦の船員が消火活動

FTL

f:id:yasu9780:20161214012551g:plain

海賊船の船員が消火活動・修理をするようにした。

  • まずレーザーで特定の部屋を攻撃する

(シールドがあると当たらないので、シールドは無しにしておく)

  • レーザーが当たった部屋で、システムが壊れる。そして火災発生
  • 狙った部屋にはO2システムがあるので、壊れると酸素供給が止まるので艦内の酸素が減り始める。
  • 船員は壊れたシステムがある部屋に移動する
  • 部屋につくと、消火活動&修理を始める
  • 火が消える
  • 修理が完了する→酸素供給が戻る
  • 初めの場所に戻る

単純に見えるけどけっこう手順がややこしい。
人間側とAI側は処理は共通だけど、あくまで船員を動かすのはAIは自己判断でやらないといけない。


仕様的に迷うのは、修理と消火は同時でいいのか? 本来は消火をやってから、修理って流れと思う。
修理を先にしても、火災があれば壊れ続けるので意味がない。

船員が増えた場合などは、たとえばパイロットが消火に行くと船の回避率が0になるので、パイロットは持ち場を離れないといった優先順位を考える必要がある。
平時であればパイロットも関係ないけど。

        void FireUpdate()
        {
            for (int i = 0; i < floor.Count; i++)
            {
                if (floor[i].fire == 0)
                {
                    if (floor[i].fireParticle != null) { Destroy(floor[i].fireParticle); floor[i].fireParticle = null; }
                    continue;
                }

                int x = (int)(floor[i].o2Filter.transform.position.x- parent.position.x);
                int y = (int)(floor[i].o2Filter.transform.position.z- parent.position.z);
                int no = GetRoomNo(x, y);// 床が所属する部屋番号を取得
                if (no == -1) continue;

                if (floor[i].fire < 100)
                {
                    floor[i].fireUp(room[no].o2 / 50);//酸素濃度に応じて延焼が進む
                    if (floor[i].fire == 100) { floor[i].fire = 50; FireAdvance(x, y); } //隣に燃え広がる
                }
                if (floor[i].fire > 0)
                {
                    if (room[no].type > 0 && floor[i].fire > 60)
                        PowerMaxLimit[room[no].type] -= Time.deltaTime;//火災でシステムが壊れていく

                    floor[i].fireDown((100f - room[no].o2) / 10);//酸素薄いと鎮火進む
                    if (floor[i].fire == 0) {
                        LogPrint("room#" + no + "が真空により鎮火\n");
                        Destroy(floor[i].fireParticle);
                        floor[i].fireParticle = null;
                        continue;
                    }
                }
                // 船員は火災部屋で消火活動する
                for (int j = 0; j< ch.Count; j++)
                {
                    int no2 = GetRoomNo(ch[j].transform.position - parent.position);
                    if (no2 == no) //火災部屋と船員がいる部屋が一致
                    {
                        ch[j].GetComponent<Man>().HPdown(Time.deltaTime * floor[i].fire/10);//船員が火災でダメージを負う
                        floor[i].fireDown(4); //船員が火を消す
                        if(floor[i].fire<=0)
                            LogPrint("room#"+no+"の消火完了\n");
                    }
                }
            }
        }