AIを使って脳死でアプリを作ろう+おまけ

初めまして。名誉部長の宮島と申します。
早速このようなかなり~~いいかげん~~挑戦的なタイトルで申し訳ありませんが、今回は最近話題の生成AI（ChatGPTとか)を使ってとにかく急ぎでアプリを作らなければいけない、しかしプログラミングの知識が何もないという状況にある皆様におすすめなライフハック（？）でございます。
ちなみに、今回一番大事なところは3番目にまとめてあるので、あまり興味がない人は読み飛ばしてそちらへGOだ！（次回予告風）
# 1.生成AIとは何か
もはや説明不要になりつつありますが、一応今回の使い方も兼ねて軽く紹介しておきます。
生成AIは通常のAIと違い、文章、画像、動画等の**出力能力がある**らしいです。~~知らんけど~~
今回使うChatGPTは2021年までのインターネットを学習しているらしいので、2021年までの情報で特に問題がないかつ**ネット上に情報が多い**言語やアプリで作成するようにしましょう。
例えば、2021年時点で開発されていないAtsEX(@automatic9045 さん開発)についてChatGPTに聞いてみましょう。
![スクリーンショット 2023-12-14 190307.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/ba9f127d-3065-b3fb-2eae-b809d9d332a1.png)
このようになってしまいます。
次に、資料の少ないBVE5のMapファイルを作ってもらいましょう。
ChatGPTの出してきた回答はこちらです。
```plaintex:united.txt
; BVE5 Mapファイルの例

[Metadata]
Format=2
RouteTitle=Example Route
Route=example_route
Author=Your Name
Comment=Example BVE5 Map File

[Structure]

; 直線部分（100mまで）
Track.0 = -100, 0, 0, 0, 0

; 曲線部分（右R600）
Track.1 = -R600, 0, 100, 0, 0

; 緩和曲線部分（80mからスタート）
Track.2 = -R80, 0, 80, 0, 0

[Object]

```
正解はこっちです。
```plaintex:united.txt
BveTs Map 2.02
80;
Curve.BeginTransition();
100;
Curve.Begin(600,0);
```
見ての通り、構文が全然違いますね。
このように、資料は少ないより多い方がよく、2021年の時点の情報でも問題がないものを選ぶべきなのです。
で、これを満たす最適解の一つが、**Unity**です。
Unityは3日あれば基本的な理解は可能で、かつC#を使うので情報は多分にあり、互換性もかなりよいです。
では実際にやってみましょう。（遅い）
# 2 実際にやってみる
## 2.1 Unityの使い方を心得る
一回もUnityをさわったことのない方はhttps://learn.unity.com/project/roll-a-ball-visual-scripting-jp を~~コピペ~~参考にしつつやってみましょう。
ここでポイントなのが、敢えてビジュアルスクリプティングを用いず、C#で書かせたコードを使うことです。
例えば、残りのアイテムをカウントする実装の時に以下のように聞いてみましょう。
```plaintext:ChatGPTにこれを聞きませう
UnityでC#を使い「Items」タグの付いている子オブジェクトの数を数え、テキストに出力してみなさいな
```
これを唱えると筆者の環境では以下のように表示されました。
```csharp:example.cs
using UnityEngine;
using UnityEngine.UI;

public class ItemCounter : MonoBehaviour
{
    public Text itemCountText;

    void Start()
    {
        CountItemsWithTag();
    }

    void CountItemsWithTag()
    {
        // "Items" タグが付いている子オブジェクトの数を数える
        GameObject[] items = GameObject.FindGameObjectsWithTag("Items");
        int itemCount = items.Length;

        // 結果をテキストに表示
        if (itemCountText != null)
        {
            itemCountText.text = "Items Count: " + itemCount.ToString();
        }
    }
}
```
あとはUnity上でプロジェクトウインドウの+マークより、「create\C# script」を選択、そしてゲームオブジェクトにアタッチし、適切なオブジェクトをアサインします（詳しくはRoll a ballのチュートリアル参照）
## 2.2 実装例
今回は、「オブジェクトを選択し、Xキーを押すと外部アプリが起動する」というものにしてみます。
では早速作っていきましょう。
### 2.2.1 場を整える
まずは、場を整えましょう。でっち上げ感を出さないためにも、ここはかなり力を込めて作るべきです。
おすすめなのはhttps://qiita.com/aluminum1981/items/d8f3cfce77731b5ecd32 のクリスタルシェダーで、これを使うといい感じに出来上がります。![スクリーンショット 2023-12-15 16.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/10554163-7f45-0105-6a79-6f0d6a14aa98.png)
以上は今年の文化祭で私が作った~~バグだらけの~~インストーラアプリです。この透明感は以上のリンクを使って作っています。
今回は時間がないので（製作開始:2023-12-14)適当にそれっぽくやっておきます。

:::note info
インフォメーション
以下の画像のように、オブジェクト、スクリプト、サウンドなどにフォルダを分けましょう。
:::
![スクリーンショット 2023-12-14 215058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/8e778ea8-3229-cba9-b6e6-09cd0f48b5bd.png)
場を設置します。
![スクリーンショット 2023-12-14 215251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/be12df80-ad4e-8118-f7db-70bb6fc02280.png)
しました。ここら辺はセンスに依存するところが多いので、いい感じに作っといてください。（適当）
![スクリーンショット 2023-12-14 215732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/2eb65aab-1c50-57be-08de-2fde6a21de33.png)
オブジェクトは回転させると一気にそれらしさが出ます。
この立方体は、（後にわかりますが）選択されている方を見せるために用意しました。
次に、テキストを追加します。（チュートリアル参照）
![スクリーンショット 2023-12-14 220731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/68c41aca-508c-a84b-88aa-dc0b627ae7b0.png)
しました。
フォントアセットを導入するとテキストを日本語で出せます。詳しくはこちら→ https://www.sejuku.net/blog/83669 https://cgbox.jp/2023/07/27/unity-font/
ライトを追加してみましょう。今回はこれをオンオフすることで選択されている方を表示します。
![スクリーンショット 2023-12-14 222526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/d50641c9-017c-9cd1-baf7-353efa5b3784.png)
次はアニメーションをしてみましょう。
固まってないかわかりやすくするために光を点滅させます。
![スクリーンショット 2023-12-14 222957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/2f536c17-6905-2485-1594-450a8be9158f.png)
しました。これで実行中いい感じに点滅します。
これで場の準備は完了しました。
### 2.2.2脳死でゴリ押そう
ここからC#を用いたごり押しを始めます。
まずは矢印キーでライトを移動させましょう。
複数のオブジェクトの場合は、すべてまとめて1~番号付けをし、current valueの値のオブジェクトのみを有効にするというやり方が必要ですが、今回は２つなので左を押したら「１」を有効に、右を押したら「２」を有効に、みたいにみたいな感じでいきます。
ではChatGPT君に聞いてみましょう。
```plaintext:ＯＲＥ
UnityでC#を使用して左矢印を押したらライト「1」を有効、ライト「2」を無効に、右矢印を押したらライト「１」を無効、「２」を有効にするスクリプトを書いてね♡
```
ChatGPT君が出してくれたC#コードです。（実際は注意書きをつけてくれるのでちゃんと見てやりましょう。）
```csharp:ChatGPT
using UnityEngine;

public class LightController : MonoBehaviour
{
    public GameObject light1;
    public GameObject light2;

    void Update()
    {
        // 左矢印が押されたら
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            EnableLight(light1);  // ライト1を有効にする
            DisableLight(light2); // ライト2を無効にする
        }

        // 右矢印が押されたら
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            DisableLight(light1); // ライト1を無効にする
            EnableLight(light2);  // ライト2を有効にする
        }
    }

    void EnableLight(GameObject lightObject)
    {
        if (lightObject != null)
        {
            lightObject.SetActive(true);
        }
    }

    void DisableLight(GameObject lightObject)
    {
        if (lightObject != null)
        {
            lightObject.SetActive(false);
        }
    }
}
```
Unity側の作業に移ります。
![スクリーンショット 2023-12-15 160541.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/d2ad1f6d-0575-5899-a39e-e521fe1441f4.png)
.csスクリプトを作りました。
これをVSCodeで開き、以上のChatGPT君の回答を**コピペ**します。
この際、class名（using 以後の public classのあと）を.csスクリプトのファイル名と同一になるように変更しましょう。
今回、初期位置は左側にするので、事前に「２」を無効にしておきましょう。
動かしましょう。
![スクリーンショット 2023-12-15 163112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/fa66f467-a433-8532-8d16-6110736a32bd.png)
動きましたね。
次は今回のミソとなる、アプリを起動する処理を実装していきましょう。
といっても、ただChatGPTに聞くだけです。
```plaintext:ORE
オブジェクト「１」が有効かつ「X」キーが押されたときにAssets/Apps/app1.exeを起動するスクリプト
```
```csharp:ChatGPT
using UnityEngine;
using System.Diagnostics;

public class LaunchApp : MonoBehaviour
{
    public GameObject objectToCheck; // 確認するオブジェクト
    public KeyCode launchKey = KeyCode.X; // 起動キー
    public string appPath = "Assets/Apps/app1.exe"; // アプリケーションのパス

    void Update()
    {
        // オブジェクトが有効かつキーが押されたら
        if (objectToCheck != null && objectToCheck.activeSelf && Input.GetKeyDown(launchKey))
        {
            // アプリケーションを起動
            LaunchApplication(appPath);
        }
    }

    void LaunchApplication(string path)
    {
        try
        {
            Process.Start(path);
        }
        catch (System.Exception e)
        {
            Debug.LogError("アプリケーションの起動中にエラーが発生しました: " + e.Message);
        }
    }
}
```
アプリのパスは適当なので各自いじりましょう。UnityEditor上では動かないので、ここではAssetsフォルダ直下に配置したフォルダの中にいれてみました。
で、ここでエラーが出たと思うので修正しましょう。

```plaintext:ORE
以上のコードでAssets\Scripts\one.cs(28,13): error CS0104: 'Debug' is an ambiguous reference between 'UnityEngine.Debug' and 'System.Diagnostics.Debug'
と出る問題を修正
```
次にChatGPT側の回答です。
```csharp:ChatGPT
using UnityEngine;
using System.Diagnostics;

public class LaunchApp : MonoBehaviour
{
    public GameObject objectToCheck; // 確認するオブジェクト
    public KeyCode launchKey = KeyCode.X; // 起動キー
    public string appPath = "Assets/Apps/app1.exe"; // アプリケーションのパス

    void Update()
    {
        // オブジェクトが有効かつキーが押されたら
        if (objectToCheck != null && objectToCheck.activeSelf && Input.GetKeyDown(launchKey))
        {
            // アプリケーションを起動
            LaunchApplication(appPath);
        }
    }

    void LaunchApplication(string path)
    {
        try
        {
            Process.Start(path);
        }
        catch (System.Exception e)
        {
            UnityEngine.Debug.LogError("アプリケーションの起動中にエラーが発生しました: " + e.Message);
        }
    }
}
```
すると多分治ったと思います。
![スクリーンショット 2023-12-15 171942.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/d327a544-31f0-9fe1-126f-5e9e1f4271b2.png)
アプリへのパスを直しました。
次にこのままだと終了ができないのでQキーを押して終了させるようにします。
```plaintext:ORE
「Q」キーが押されたらアプリケーションを終了するスクリプト
```
```csharp:ChatGPT
using UnityEngine;

public class QuitApplication : MonoBehaviour
{
    void Update()
    {
        // Qキーが押されたらアプリケーションを終了
        if (Input.GetKeyDown(KeyCode.Q))
        {
            Quit();
        }
    }

    void Quit()
    {
        // アプリケーションを終了
        #if UNITY_EDITOR
            UnityEditor.EditorApplication.isPlaying = false;
        #else
            Application.Quit();
        #endif
    }
}
```
さて、以上ですべての実装が終わりました。お疲れさまでした。
勿論ビルドして正しい配置にするまでがアプリ製作なので、お忘れなきよう。
# 3 宣伝とか
ここまでクソ長い文章読んでくれてありがとうございました。（え？読んでない？）
今回のUnityプロジェクトはhttps://github.com/cydiawaltz/Christmas2023 に載せました。よかったらご自身でビルドし、今回の作品の~~低クオリティっぷり~~すばらしさを実感してみてください。（手前味噌）

そういえば、本郷祭2023に来ていただけた方はいらっしゃいますでしょうか？今年はこんなパッケージのクソゲーCDを発売しました。
![ゲームジャケット-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962100/6d0164e1-627e-8433-d81b-eb996af01fa1.png)
背景のUnity以外のパクリに気付いたそこのあなた、50台です。
そんな冗談はさておき、クソゲー類を遊びたいという猛者の皆様に朗報です。
http://komenezumi.net/hongomcc2023/GAME-HAPPYSET-2023.zip ここより、CDの中身がダウンロード可能です。
ぜひとも遊んでみてください！

おしながき
**・モニターマンの逆襲**
→アプデで実装すると言ったな、あれは嘘だ
**・solitire**
→rinrin高校部長の渾身の作品。いたって普通のソリティア
**・氷上の秘塔**
→思考系のゲーム。結構おもしろい
**・一次元セルオートマトン**
→~~なんだこりゃ~~ctes091x氏の作品
**・BulletGalaxy**
→~~弾丸銀河?~~ めちゃめちゃクオリティ高い。文化祭一番の人気作。
**・Morse**
→モールス信号打つゲーム
**・弾幕-ATO-**
→いたって普通の弾幕ゲー。~~弾幕ゲー多くない？~~
**・Fourier**
→波形を合わせる謎ゲー。かなり難しい
**・BetterMineSweeper**
→麻布コラボでやるつもりだった。詳しくは部誌をご覧あれ。
**・さいたまゲーム**
→我が父の使ってたWin95ノパソから発掘された謎ゲー。
**・Yamaura vs Touga**
→究極の身内ネタ。もともとはctes091x氏が出る予定だった
**・ただのボタン**
→@scratch221171 の自己満。ただの謎ゲー
**・Update**
アップデート機能。バグで使えない
**・CSS完全に理解した**
→CSS完全に理解するゲーム。
**・グラフ探索**
→~~なんじゃこりゃpart2~~

謎ゲーが極めて多いですがご了承を。
あとブラウザは結構バグだらけなのでgamehappyset2023.exeと同ディレクトリにあるAssetsフォルダの中身からexeを見つけ出す方が早いかも

アップデート機能は付けましたが、使う予定はなさそうです

# 4 次回予告
UHA視覚党高校部長によるC++でGBAゲームを作る話
乞うご期待。