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

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

ThirdPersonShooterを作る(1)

 ThirdPersonなShooterを作ってみます。
 以前作っていたゾンビ狩りゲームと近くなってきました。
 プレイヤーと、AIの味方が二人。敵はゾンビおじさんでwaveで襲ってきます。
 AIがどんどん敵を倒してくれるので、ぼーっとしててもゲームが進む(*´ω`*)
 簡単で受け身でも遊べるゲームもあっていいかもw

f:id:yasu9780:20161004004046g:plain
 以前と比べて違うのは

  • 照準をつけた
  • 獲得expが表示されて上にスクロールしていって消える
  • キューブの障害物(破壊可能)
  • waveによる敵の投入
  • AIが自分と離れすぎると戻ってくる


 今後の改良点

  • 手投げ弾など範囲攻撃の武器
  • 剣など近接攻撃
  • ソンビを倒すと、アイテムの報酬
  • ヒールポーション
  • 敵の投入に関しては、レベルデザイン的な緩急が大事なので、このへんはよく研究してみたい。
  • カメラは現在は単純なfollowカメラですが、もっと演出的なカメラワークをやってみたい。
  • 背景というか舞台セットをちゃんとしたのに変えたい。
  • navMeshはやってないので、ゾンビがキューブの後ろ側にいると、キューブに向かって突進していくというアホな行動をAIがとってしまう。
  • ジャンプとか、大剣振り回しとか派手目な演出技もやってみたい。
  • IKを使って銃口を動かす。(味方のAIがまだ銃をもっていない。念動力w)
  • 敵に、飛行物体やボス的なでかいやつもほしい。
  • レーダー


 ゾンビのspawnは、invokeだけでやってみた。デバッグ用にgameSpeedを変えて進行を早くできる。
 ゾンビははじめに20体生成しておいて、損壊してもdestroyせずに、deadフラグを立てて、SetActive(false)にして、次のwaveで使いまわしている。

    void waveIncoming()
    {
        state.text = "Wave " + (waveIndex + 1) + " INCOMING";
        Invoke("waving", 3f/ gameSpeed);
    }

    void waving()
    {
        zomMax = waveIndex*2 + 2;

        wavingFlag = true;
        zomIndex = 0;
        state.text = "Wave " + (waveIndex + 1) + " of " + waveMax;
        Invoke("spawn", 3f/ gameSpeed);
    }
    void spawn()
    {
        Vector3 pos;
        pos = blue[0].transform.position + new Vector3(Random.Range(-20f, 20f), 5f, Random.Range(-20f, 20f));

        red[zomIndex].transform.position = pos;
        red[zomIndex].GetComponent<Enemy>().speed = 0.2f;
        red[zomIndex].GetComponent<Enemy>().hpMax = 50;
        red[zomIndex].GetComponent<Enemy>().hp    = 50;
        red[zomIndex].GetComponent<Enemy>().dead = false;
        red[zomIndex].SetActive(true);

        zomIndex++;
        if (zomIndex < zomMax) Invoke("spawn", 2f/ gameSpeed);
    }
    void waveComplete()
    {
        state.text = "Wave " + (waveIndex + 1) + " of " + waveMax + " COMPLETE";
        waveIndex++;
        if(waveIndex<waveMax)
            Invoke("waveIncoming", 5f/ gameSpeed);
        else
            Invoke("gameComplete", 5f/ gameSpeed);
    }
    void gameComplete()
    {
        state.text = "GAME COMPLETE!";
    }

 HPのステータスバーは、uGUIのスライドバーを使っている。
 コードからのアクセスは、以下。

  Slider sl;
  sl = transform.FindChild("Canvas/Panel/Slider").GetComponent<Slider>();
  sl.value = 100 * hp / hpMax;

 Canvas(RenderModeはWorldSpaceにする)をキャラの子供にして、Sliderをさらに子供にして、Interactableをoffにすれば変更ボタンが非表示になる。
 向きをカメラの向きに合わせると常にこちら側に向くので、ビルボード的に使える。 

 transform.FindChild("Canvas").transform.rotation = Camera.main.transform.rotation;


 1ドルのアセットの村を舞台にしてみた。
f:id:yasu9780:20161004025510p:plain
 問題点は、thirdPersonの自分の後ろ側に高い建物があると建物が邪魔で画面が見えなくなる(´・ω・`)
 街だと迷路になるので、AIが経路探索対応してないとゾンビを探せない
 やはりNavMeshAgentじゃないとだめかな。
 もしくは、建物系の舞台は避ける(プレイ環境の周囲が高い分には問題ない)