月別アーカイブ: 2025年3月

FreetokenWithOpenAI

Geminiで会話履歴をPrefsに覚えさせ、会話を続けられるようにしていたが、やはり1日50requestで「Gemini API Error: HTTP/1.1 429 Too Many Requests」となる事が判明・・・やはりOpenAIで作ったほうが得策か。。。そういえば、無料トークンの話あったよな。
OpenAI API を毎日無料で 100 万トークン使えるらしい?によれば、条件をみたすと100万トークン毎日無料で使えるようになるという。本当に?!ブログに従って無料トークン用のAPIキーを作成してみる。Pythonで試してみようか・・・あ、動きますね!これなら無駄に会話を続けてもダメージは最小限に抑えられる。これで開発しようか。

Gemini再来

UezoさんのChatdollkitを見て気がつく。まえにもBard使ってたけど、かなり賢いGeminiがなんと使い放題らしい。人格も維持し、JSON出力もキープしてくれる。これはひょっとして・・・。Unityから使う方法も一応紹介されている。もっと簡単に使える方法はないものか。。
C#でAIと無料で会話できるようにしてみた
これとか良いのではないか・・・。dllが必要!?

GASを使うと3分でできるというが・・・。めんどくさい。やるしかないのか。
Gemini↔️GAS↔️UnityでGeminiを使ってみる(テキスト編)


Geminiは、ChatGPTにUnityでの使い方を聞いたらあっさり動作した。・・・がしかし、50リクエスト/日とある。50リクエストしかできないって事じゃ??はぁ~

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using TMPro;
using UnityEngine.UI;

public class GeminiChat : MonoBehaviour
{
    public string apiKey = ""; // あなたのGemini APIキー
    public TextMeshProUGUI outputText;
    public InputField IF1;
    public Text outputmessage;

    private List<Content> conversationHistory = new List<Content>(); // 会話履歴(最大100)

    void Start()
    {
        // 初期化時は空の会話でもOK
    }

    public void procMessage(string message)
    {
        string userInput = IF1.text;
        if (!string.IsNullOrEmpty(userInput))
        {
            AddToHistory("user", userInput); // ユーザー発言を履歴に追加
            StartCoroutine(SendRequestToGemini());
        }
    }

    void AddToHistory(string role, string text)
    {
        // Gemini APIのフォーマットは content[].parts[].text を使用
        Content content = new Content
        {
            role = role,
            parts = new Part[]
            {
                new Part { text = text }
            }
        };

        conversationHistory.Add(content);

        // 最大100件までに制限(roleごとではなく全体で100)
        if (conversationHistory.Count > 100)
        {
            conversationHistory.RemoveAt(0);
        }
    }

    IEnumerator SendRequestToGemini()
    {
        string url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-pro-exp-02-05:generateContent?key=" + apiKey;

        GeminiRequest requestData = new GeminiRequest
        {
            contents = conversationHistory.ToArray()
        };

        string jsonData = JsonUtility.ToJson(requestData, true);
        byte[] postData = System.Text.Encoding.UTF8.GetBytes(jsonData);

        UnityWebRequest request = new UnityWebRequest(url, "POST");
        request.uploadHandler = new UploadHandlerRaw(postData);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");

        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
        {
            string result = request.downloadHandler.text;
            GeminiResponse response = JsonUtility.FromJson<GeminiResponse>(result);

            string reply = response.candidates[0].content.parts[0].text;

            Debug.Log("Gemini Response: " + reply);

            if (outputText != null)
                outputText.text = reply;

            outputmessage.text = reply;

            // AIの返答を履歴に追加(role: "model")
            AddToHistory("model", reply);
        }
        else
        {
            Debug.LogError("Gemini API Error: " + request.error);
            outputmessage.text = request.error;
        }
    }

    // JSON構造(Gemini API仕様)
    [System.Serializable]
    public class GeminiRequest
    {
        public Content[] contents;
    }

    [System.Serializable]
    public class Content
    {
        public string role; // "user" or "model"
        public Part[] parts;
    }

    [System.Serializable]
    public class Part
    {
        public string text;
    }

    [System.Serializable]
    public class GeminiResponse
    {
        public Candidate[] candidates;
    }

    [System.Serializable]
    public class Candidate
    {
        public Content content;
    }
}

GroomingStack

GroomingStack – Hair, Fur and More
良いのか悪いのか、情報が少なくて評価しにくいアセット。Fluffy Grooming Toolなら紹介が見つかるのだけれど。しかしHDRPが動作する環境なら、これくらいの表現力があっても良いのではないか。しかしこの髪データ、どうやって作るんだ・・・。これはBlenderParticleHairという仕組みで作成したものを取り込めるらしい。CardtoStrandというツールが付いているようだが、実際どの程度の表現力なのかわからない。・・・おおお、Blender であらゆるヘアカードをグルーミング ストランドに変換するなどのチュートリアルが!ハイフィデリティな髪はこうやって作ってるのか!!すぅげぇ~!

HDRP250317

深みにはまるHDRP。もう何が良いのか悪いのかわからなくなってきた。Sun>Shadows>ContactShadowsをmedium以上にすると、髪の毛の影が顔に落ちるようになった。何が違うのかポニーテールの場合は、髪テクスチャのアラが目立ちにくい。これはカメラのPostAntialiasingをTAA(High)にしてる効果が大きいと思われる。リアルタイムレンダリングとしては、かなり良いところまで来た気がする。

ショートカットは、コンタクトシャドウがつくと、とたんに前髪が邪魔そうな印象になる。まぁそれはそれでリアルなのだろうが・・・。

ロングヘアーのヒトは印象がすっかり変わってしまい、モードな雰囲気に・・・。影の濃さを変えるには、環境光(HDRI)のExposureを変える必要があるようだ。が、そうすると背景も変わってしまう。難しいところだ。HDRPの画作りが真実に近いと言うなら、見る側もそれに慣れなければいけないのか。でも全員に言われそう。「前髪がジャマ」って。それは、IdaFaber(髪アセット作者)に言ってくれ。

ところで、HDRPの作画を画像検索にかけると、高い確率で「いかがわしいCG」に認定されてしまう。しかし、ポニーテールとショートカットは、とうとうGoogleに「個人の写真は検索できない(つまり人間)」認定をうけた。やった。残念ながらロングヘアーは相変わらずいかがわしい画像認定であった。

UnityHiarSystem

Unityでのリアルな髪の毛表現には、Unity製のHairsystemというアセットがあるらしいのだが、これはAlembic形式というファイルを作成する必要があるらしい。MayaやMAXなどの環境が必要なのだろうか。。いつか作れる日がくるのだろうか?

Alembicファイルはここから手に入るらしい。気が遠くなるほどセットアップ手順が長い。
Unityがデジタルヒューマン構築に消極的で、行く先が割と絶望的であることが議論されている。やはりUEに移行するしかないのか。

MediapipeWithWeb

MediaPipeはブラウザでも動作するだと?!そんなことあってたまるか・・・。KDDIのTOYOTAさんの記事によればMediaPipeStudioでは、様々なWeb版MediaPipeの機能を体験できるという。

顔の検出手の検出、確かにWebのみで動作する。MediaPipeは、以前にBarracuda経由でためしたものよりバージョンアップして機能や精度が改善されているようだ。52の顔ブレンドシェイプ値を出してくれるのが良い。しかし・・・実際に動作を確認すると「笑顔の検出が鈍い(そのぶん飽和しないので、強い笑顔の検出はできる)」「ネガティブ表情の検出が非常に悪い」などの問題があるように感じた。こういうAIは一長一短で、なかなかパーフェクトなものは存在しないようだ。いちいち確かめるのは不毛とも言える。