Türkiye'nin Oyun Alemi

Oyun Alemi'nin tam kalbinde yerinizi almak istemez misiniz? Güncel tartışmalara dahil olmak, rehber içeriklere hızlıca erişmek ve güzide topluluğumuzun tüm ayrıcalıklarından faydalanmak için hemen ücretsiz hesabınızı oluşturun.

Unity'de Ollama (Local LLM) ile İnternetsiz Akıllı NPC Yapmak: C# Deneyimim

Yennefer

Player [0]
Mesajlar
18
Tür
Aksiyon/Macera
Projemdeki NPC'lerin klasik diyalog ağaçlarından çıkıp oyuncunun yazdığı metinlere göre anlık tepkiler vermesini istiyordum. Ancak OpenAI API anahtarına bağımlı kalmak hem maliyet oluşturuyordu hem de oyuncunun internet bağlantısı kesildiğinde sistemi çökertiyordu.

Bu sorunu çözmek için oyuncunun bilgisayarında yerel olarak çalışan Ollama altyapısını Unity'ye bağladım. Hem tamamen ücretsiz hem de internetsiz çalışan bu sistemdeki kurulum adımlarını ve C# kodlarını paylaşıyorum.




1. Neden Local LLM (Ollama) Tercih Ettim?

Bulut tabanlı API'ler ile bilgisayarda çalışan yerel modeller arasındaki temel farklar şu şekilde:

ÖzellikOpenAI / Cloud APIOllama (Local LLM)
İnternet BağlantısıZorunluGerekmiyor (Çevrimdışı)
MaliyetSorgu başına ödeme (API Key)Tamamen Ücretsiz
Yanıt SüresiSunucu yoğunluğuna bağlıKullanıcının GPU / VRAM gücüne bağlı
Veri GizliliğiVeri dış sunucuya giderVeri tamamen bilgisayarda kalır



2. Ollama Kurulumu ve Model Seçimi

Öncelikle ollama.com üzerinden Ollama'yı kurduktan sonra terminalden küçük boyutlu ama diyalog başarısı yüksek bir model indirmemiz gerekiyor. 8 GB VRAM'e sahip sistemlerde akıcı çalışması için Llama 3.2 (3B) veya Phi-3 Mini modellerini öneririm.

Kod:
# Terminal veya CMD üzerinden modeli indirin ve başlatın
ollama run llama3.2

Model çalıştıktan sonra Ollama varsayılan olarak http://localhost:11434/api/generate portundan HTTP isteklerini dinlemeye başlar.



3. Unity C# HTTP İletişim Scripti

Oyun kilitlenmeden (donmadan) arka planda isteği gönderip yanıtı alabilmek için UnityWebRequest yapısını async/await ile kullandım:

C#:
using System;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;

[Serializable]
public class OllamaRequest
{
    public string model = "llama3.2";
    public string prompt;
    public bool stream = false; // Tek parça yanıt almak için false
}

[Serializable]
public class OllamaResponse
{
    public string response;
}

public class NPCBrain : MonoBehaviour
{
    private const string OllamaURL = "http://localhost:11434/api/generate";

    public async Task<string> AskNPC(string playerMessage, string npcPersonality)
    {
        // System Prompt ile karakter kişiliği tanımlıyoruz
        string fullPrompt = $"Kişilik: {npcPersonality}\nOyuncu: {playerMessage}\nNPC:";

        OllamaRequest requestData = new OllamaRequest
        {
            prompt = fullPrompt
        };

        string jsonPayload = JsonUtility.ToJson(requestData);

        using (UnityWebRequest request = new UnityWebRequest(OllamaURL, "POST"))
        {
            byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonPayload);
            request.uploadHandler = new UploadHandlerRaw(bodyRaw);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");

            var operation = request.SendWebRequest();

            while (!operation.isDone)
                await Task.Yield();

            if (request.result == UnityWebRequest.Result.Success)
            {
                OllamaResponse responseData = JsonUtility.FromJson<OllamaResponse>(request.downloadHandler.text);
                return responseData.response;
            }
            else
            {
                Debug.LogError("AI Hatası: " + request.error);
                return "Şu an kafam biraz karışık...";
            }
        }
    }
}



4. Yaşadığım Yanıt Gecikmesi ve Çözümü

Sistemi ilk kurduğumda modelin cevabı hazırlaması 2-3 saniye sürüyordu ve bu durum oyun içi diyalog akışını bozuyordu. Bunu çözmek için iki yöntem uyguladım:

  1. Streaming (Akış) Kullanımı: stream = true yaparak kelimeler üretildikçe ekrana yazdırma (typewriter efekti) altyapısına geçtim. Bu sayede ilk kelime 300ms içinde ekranda görünmeye başlıyor.
  2. Context Sınırlaması: Modete gönderilen geçmiş diyalog hafızasını (memory) son 4 mesaj ile sınırlandırarak VRAM yükünü azalttım.



5. Sık Karşılaşılan Sorular

S: Oyunu yayınladığımda oyuncunun da bilgisayarına Ollama kurması gerekir mi?
C: Evet, local çalışacağı için oyuncunun sisteminde Ollama servisi arka planda açık olmalı. Eğer kurulumla uğraştırmak istemiyorsanız llama.cpp kütüphanesini C++ eklentisi (Plugin) olarak doğrudan Unity projesinin içine gömebilirsiniz (Mac/PC build alırken içine dâhil olur).

S: Ekran kartı zayıf olan sistemlerde kasma yapar mı?
C: VRAM'i 4 GB'ın altında olan sistemlerde işlemciye (CPU) yük bindiği için yanıt süresi 5-6 saniyeye çıkabilir. Bu yüzden oyun ayarlarına "Klasik Diyalog / Akıllı AI Diyalog" seçeneği koymak en mantıklısı.




Projelerinde yerel model denemeleri yapan veya farklı prompt teknikleri kullanan varsa tecrübelerinizi duymak isterim.
 
shape1
shape2
shape3
shape4
shape5
shape6
Geri
Üst