0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】ChatGPT によるバグ取りを効率的に行うための Editor 拡張

Last updated at Posted at 2025-05-28

ChatGPT の有料版をご利用中の方であれば、質問時により多くの文字数を扱うことができます。
これは、バグ修正や機能実装の詳細を記述する際に非常に有効です。

そんな ChatGPT を最大限活用するために、
.unity ファイルに紐づいている .cs スクリプトのファイル名と中身をまとめてクリップボードにコピーする
Editor 拡張を作成しました。

ChatGPT に質問したいシーンファイルを右クリックして
Tools > SephirothChatGPTPromptCreator > CSOnly
を選択するだけで、関連する .cs ファイルの中身を一括コピーできます。

この拡張を使うと、怪しい .cs ファイル 1 個 1 個に対して質問する必要がなくなるため、 ChatGPT の活用が楽になります。

ここでは、その拡張機能について紹介します。

サクっと導入したい方は
unitypackage 版 をご利用ください。


SephirothChatGPTPromptCreator.cs
#if UNITY_EDITOR

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;

public static class SephirothChatGPTPromptCreator
{
    [MenuItem("Assets/Tools/SephirothChatGPTPromptCreator/All", true)]
    private static bool ValidateSelectedUnityFile()
    {
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);
        return path.EndsWith(".unity");
    }

    [MenuItem("Assets/Tools/SephirothChatGPTPromptCreator/All")]
    private static void GeneratePromptFromScene()
    {
        string scenePath = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (!scenePath.EndsWith(".unity"))
        {
            Debug.LogWarning("選択されたファイルは .unity ファイルではありません。");
            return;
        }

        var builder = new StringBuilder();

        // .unity ファイルの内容を追加
        string fullScenePath = Path.Combine(Directory.GetCurrentDirectory(), scenePath);
        builder.AppendLine(Path.GetFileName(scenePath));
        builder.AppendLine(File.ReadAllText(fullScenePath));
        builder.AppendLine();

        // シーンを開いてすべての MonoBehaviour を取得
        var openedScene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
        var allObjects = openedScene.GetRootGameObjects();

        var uniqueScripts = new HashSet<MonoScript>();

        foreach (var go in allObjects)
        {
            foreach (var mb in go.GetComponentsInChildren<MonoBehaviour>(true))
            {
                if (mb == null) continue; // Missing Script の場合
                var script = MonoScript.FromMonoBehaviour(mb);
                if (script != null)
                    uniqueScripts.Add(script);
            }
        }

        // 各スクリプトファイルを読み込み(Assetsフォルダ内のスクリプトのみ対象)
        foreach (var monoScript in uniqueScripts)
        {
            string scriptPath = AssetDatabase.GetAssetPath(monoScript);
            if (!scriptPath.StartsWith("Assets/")) 
                continue; // Unity内部やパッケージのスクリプトは除外

            string fullScriptPath = Path.Combine(Directory.GetCurrentDirectory(), scriptPath);
            builder.AppendLine(Path.GetFileName(scriptPath));
            builder.AppendLine(File.ReadAllText(fullScriptPath));
            builder.AppendLine();
        }

        // クリップボードにコピー
        EditorGUIUtility.systemCopyBuffer = builder.ToString();
        Debug.Log("シーンと関連付けられた .cs スクリプトがクリップボードにコピーされました。");
    }

    [MenuItem("Assets/Tools/SephirothChatGPTPromptCreator/CSOnly", true)]
    private static bool ValidateSelectedUnityFile2()
    {
        string path = AssetDatabase.GetAssetPath(Selection.activeObject);
        return path.EndsWith(".unity");
    }

    [MenuItem("Assets/Tools/SephirothChatGPTPromptCreator/CSOnly")]
    private static void GeneratePromptFromScene2()
    {
        string scenePath = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (!scenePath.EndsWith(".unity"))
        {
            Debug.LogWarning("選択されたファイルは .unity ファイルではありません。");
            return;
        }

        var builder = new StringBuilder();

        // シーンを開いてすべての MonoBehaviour を取得
        var openedScene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Single);
        var allObjects = openedScene.GetRootGameObjects();

        var uniqueScripts = new HashSet<MonoScript>();

        foreach (var go in allObjects)
        {
            foreach (var mb in go.GetComponentsInChildren<MonoBehaviour>(true))
            {
                if (mb == null) continue; // Missing Script の場合
                var script = MonoScript.FromMonoBehaviour(mb);
                if (script != null)
                    uniqueScripts.Add(script);
            }
        }

        // 各スクリプトファイルを読み込み(Assetsフォルダ内のスクリプトのみ対象)
        foreach (var monoScript in uniqueScripts)
        {
            string scriptPath = AssetDatabase.GetAssetPath(monoScript);
            if (!scriptPath.StartsWith("Assets/")) 
                continue; // Unity内部やパッケージのスクリプトは除外

            string fullScriptPath = Path.Combine(Directory.GetCurrentDirectory(), scriptPath);
            builder.AppendLine(Path.GetFileName(scriptPath));
            builder.AppendLine(File.ReadAllText(fullScriptPath));
            builder.AppendLine();
        }

        // クリップボードにコピー
        EditorGUIUtility.systemCopyBuffer = builder.ToString();
        Debug.Log("シーンと関連付けられた .cs スクリプトがクリップボードにコピーされました。");
    }
}

#endif

SephirothChatGPTPromptCreator.cs を作成して
内容を上記の内容にして下さい。

その後、バグが出ているシーンのシーンファイルを右クリックして
Tools > SephirothChatGPTPromptCreator > CSOnly
を選択すると、そのシーンに紐づいた全ての .cs ファイルの
ファイル名と中身がクリップボードに保存されます。

その後 ChatGPT を開いて
「このシーンの〇〇のバグを取りたい」
「このシーンに〇〇の機能を付けたい」
という文章の後に貼り付けて使用して下さい

※文字数制限に引っかかった場合は、20万文字程度ずつ質問して下さい。


シーンファイルに関係なく
.cs ファイルをクリップボードにコピーしたい方は
下記のコードを活用下さい。

小規模のプロジェクトでないと
文字数が大変な事になる点に注意です。

将来的に ChatGPT の文字数制限が
更に拡張された場合に使ってみたい所です

SephirothChatGPTPromptCreatorB.cs
#if UNITY_EDITOR

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;

public class SephirothChatGPTPromptCreatorB : EditorWindow
{
    [MenuItem("Tools/SephirothChatGPTPromptCreaterB/All")]
    public static void CreatePrompt()
    {
        StringBuilder builder = new StringBuilder();

        // .unityファイルを検索して追加
        string[] unityFiles = Directory.GetFiles(Application.dataPath, "*.unity", SearchOption.AllDirectories);
        foreach (string filePath in unityFiles)
        {
            builder.AppendLine(Path.GetFileName(filePath));
            builder.AppendLine(File.ReadAllText(filePath));
            builder.AppendLine();
        }

        // .csファイルを検索して追加
        string[] csFiles = Directory.GetFiles(Application.dataPath, "*.cs", SearchOption.AllDirectories);
        foreach (string filePath in csFiles)
        {
            builder.AppendLine(Path.GetFileName(filePath));
            builder.AppendLine(File.ReadAllText(filePath));
            builder.AppendLine();
        }

        // クリップボードにコピー
        EditorGUIUtility.systemCopyBuffer = builder.ToString();

        Debug.Log("全 .unity と .cs ファイルがクリップボードにコピーされました。");
    }

    [MenuItem("Tools/SephirothChatGPTPromptCreaterB/CSOnly")]
    public static void CreatePrompt2()
    {
        StringBuilder builder = new StringBuilder();

        // .unityファイルを検索して追加
        // string[] unityFiles = Directory.GetFiles(Application.dataPath, "*.unity", SearchOption.AllDirectories);
        // foreach (string filePath in unityFiles)
        // {
        //     builder.AppendLine(Path.GetFileName(filePath));
        //     builder.AppendLine(File.ReadAllText(filePath));
        //     builder.AppendLine();
        // }

        // .csファイルを検索して追加
        string[] csFiles = Directory.GetFiles(Application.dataPath, "*.cs", SearchOption.AllDirectories);
        foreach (string filePath in csFiles)
        {
            builder.AppendLine(Path.GetFileName(filePath));
            builder.AppendLine(File.ReadAllText(filePath));
            builder.AppendLine();
        }

        // クリップボードにコピー
        EditorGUIUtility.systemCopyBuffer = builder.ToString();

        Debug.Log("全 .cs ファイルがクリップボードにコピーされました。");
    }
}

#endif

🎉 おわりに

以上、至極真っ当な Editor 拡張を紹介しました。
この記事が少しでも皆さんの Unity 開発の助けになれば嬉しいです。

最後までご覧いただき、ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?