Unity接入ChatGPT基于Python.Runtime的实现

这篇具有很好参考价值的文章主要介绍了Unity接入ChatGPT基于Python.Runtime的实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言

编译Python.Runtime.dll

Unity接入ChatGPT

1.第一步 准备环境

2.第二步 python代码的书写

3.第三步 C#调用python代码


前言:

相信各位游戏人都用过ChatGPT吧,那么怎么在unity里接入ChatGPT呢?本文章会通过一种极其简单的方式来实现,最终效果如下:

python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

  1. 可以进行中文对话,可以记住一点的上下文(实际上几乎记不住任何上下文,可能是free版本的限制吧,等拿到万事达卡再试试plus版本的)
  2. 可调节的准确率(诚恳度越低准确度越高,但是更冷漠),Ai说话时的“温度”
  3. 简单的python和c#交互

好的,下面开始教程:

编译Python.Runtime.dll

看标题可知,这是基于Python.Runtime的,所以首先要拿到这个.dll文件

github地址
GitHub - pythonnet/pythonnet: Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers. - GitHub - pythonnet/pythonnet: Python for .NET is a package that gives Python programmers nearly seamless integration with the .NET Common Language Runtime (CLR) and provides a powerful application scripting tool for .NET developers.https://github.com/pythonnet/pythonnet

在GitHub上clone 下来的文件需要编译成dll文件,建议使用vs进行编译,下面是教程

用vs打开解决方案(根目录下的pythonnet.sln)

 python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

 在python.runtime项目上右键打开属性

  1. 将目标平台设置为x64python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#
  2. 选择一个基路径,这个路径是你在编译好的dll文件的存放路径,是相对根目录而言的,我的就在这里面了,大家编译完成后直接在根目录里面找就好了
  3. python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#
  4. 哦,忘记了,输出类型选择类库python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

 然后再次右键选择生成python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

 等待编译完成后即可在设置的基目录下看到这个dll文件

python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

 然后把这个dll文件拖到unity里

python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

 好了,准备工作已经完成,现在开始正式在Unity里接入ChatGPT!!!

Unity接入ChatGPT

首先要获取openai的api的使用权限,所以我们要有key才行

在openai的官网可以获取:key在这里弄

弄好key一定要复制好,保存好,因为一旦获取了之后,key就永久隐藏了。如果丢失了就只能再获取一次(虽然不麻烦,但是耗money呀)

ok废话介绍完毕,开始撸码,注意哦,教程是循循渐进的,代码都不是完整的,如果只想copy可以直接跳到底部复制完整代码自己看。

1.第一步 准备环境

首先引入using Python.Runtime的命名空间,设置好时间间隔,建议为20s,为啥,我也不知道,官网说的...

再就是要告诉这个插件python解释器的dll文件路径,这个很好弄,在官网上下载好python就直接能看到这个dll,还有环境变量别忘记配置了,有的大佬可能懒得登录,但是又想复制,所以我直接贴出来代码,hh

using System.IO;
using Python.Runtime;
using UnityEngine;

public class PythonManager : MonoBehaviour
{
    // Start is called before the first frame update
    [SerializeField] public float _timer;
    private float _interval = 20;

    void Start()
    {
        _timer = _interval;
        // 获取python.all的路径(调用python解释器来执行python代码)
        string pythonPath = @"C:\Python311"; 
        string dllPath = Path.Combine(pythonPath, "python311.dll");
        Runtime.PythonDLL = dllPath;
    }
}
using System.IO;
using Python.Runtime;
using UnityEngine;

public class PythonManager : MonoBehaviour
{
    // Start is called before the first frame update
    [SerializeField] public float _timer;
    private float _interval = 20;

    void Start()
    {
        _timer = _interval;
        // 获取python.all的路径(调用python解释器来执行python代码)
        string pythonPath = @"C:\Python311"; 
        string dllPath = Path.Combine(pythonPath, "python311.dll");
        Runtime.PythonDLL = dllPath;
    }
}

2.第二步 python代码的书写

这里我先说一下我的实现思路,免得大家看不懂。

我没有使用文件读取的方式来提交prompt和获取gpt回答的内容,因为我很菜,hhh,用python调用resources里的文件实在是麻烦透顶,研究了一会就放弃了,当然也可以使用绝对路径的方式来用,但是这样一打包就彻底废了,因为路径全乱了,所以干脆放弃使用文件读取的方式。然后怎么办呢???突然我想到了一个极其极其的野路子,哈哈哈哈,就是用游戏物体的名字来当临时储存“文件”,这样就方便多了,而且还不用开线程去读文件,性能也高了不少,哈哈哈哈哈快夸我。

其实呢。。。我这个文章的缺陷也很多,就是应该只能在pc上运行,我用安卓测试的时候会闪退,应该和python解释器的调用有关系,没有去研究....要是有大佬知道怎么解决的话欢迎提供解决方案哈,嘻嘻嘻嘻。

然后这是python代码的部分(纯享版,没有注释)

import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []
for obj in objects:
    if obj.tag == 'duiBaQi':
        duiBaQis.append(obj)
openai.api_key = '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'
model_engine = 'gpt-3.5-turbo' 
prompt = 'hello'
temperature = random.uniform(0.1,2)
for o in duiBaQis:
    if('@temperature:' in o.name):
        temperatureStr = format(temperature,'.2f')
        o.name = '@temperature:' + temperatureStr;
max_tokens = 255
for o in duiBaQis:
    if('@prompt:' in o.name):
        promptText = o.name.replace('@prompt:','');
        prompt = promptText
completion = openai.ChatCompletion.create(
   model='gpt-3.5-turbo',
   messages=[
     {'role': 'user', 'content': prompt}
   ],
   temperature = temperature,
   max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:
    if('@ai:' in o.name):
        o.name = '@ai:'+ completion.choices[0].message.content;
import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []#这个数组是储存所有含有duibaqi标签的游戏物体,为了加快查找速度用的,当然要是大家熟悉python的话,应该可以使用一个全局管理器来管理每一个用到的游戏物体,这样就只需要查找一遍就行了(思路就是定义几个bool值,查找完毕后设置为false,检测到false就跳过for in 循环),但是我不太会用python,hhh,没有学过...所以就放弃了,大家完全可以不比这样做
for obj in objects:
    if obj.tag == 'duiBaQi':
        duiBaQis.append(obj)#将这三个游戏物体推进这里面,哪怕是提高一丢丢的效率也是好的...
openai.api_key = '这里填在官网拿到的key'#这里是在官网得到的key
model_engine = 'gpt-3.5-turbo' #在这里选择gpt的模型,因为不同模型的使用方法有点不同,所以这里最好和我一样,等这个实现了以后大家再去琢磨别的。
prompt = 'hello'#这里是prompt,就是大家在用ChatGPT的时候给问他的那些问题
temperature = random.uniform(0.1,2)#这里就是可调节“温度”了,也就是gpt的语气
for o in duiBaQis:
    #查找temperature物体
    if('@temperature:' in o.name):
        temperatureStr = format(temperature,'.2f')
        o.name = '@temperature:' + temperatureStr;
max_tokens = 255#这个是gpt回答内容的最大字符,因为我们用的是游戏物体的名字来存储这个数据,但是在unity里游戏物体的名字最多也就能存255个字符,所以....就这样咯。
for o in duiBaQis:
    #查找prompt物体
    if('@prompt:' in o.name):
        promptText = o.name.replace('@prompt:','');#需要把"@prompt:"这个字符串替换掉才能作为prompt使用,不要忘记了,不然的话prompt都成啥了,笑死。
        prompt = promptText
#最核心的代码,调用openai提供的api,将我们设置好的model,prompt,temperature,max_tokens参数严格按照官方文档给出的格式填入,然后用completion接受返回结果。返回的是一个对象,结构比较复杂,包含很多细节,大家有兴趣可以打印出来看看,这里我们只需要使用choices[0].message.content这个数据即可。
completion = openai.ChatCompletion.create(
   model='gpt-3.5-turbo',
   messages=[
     {'role': 'user', 'content': prompt}
   ],
   temperature = temperature,
   max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:
    #查找ai物体
    if('@ai:' in o.name):
        o.name = '@ai:'+ completion.choices[0].message.content;#直接更改ai物体的名字为gpt回答的内容,注意前缀不要忘记加上"@ai:",因为我们不是只用一次,不要卸磨杀驴了,hhh

 代码讲解我都放在注释里面了,大家可以对照着代码一起看,我觉得还是蛮清晰的,哈哈。

 好了,python代码的部分就是这么多,还是挺简单的,下面是用c#来调用python的部分

3.第三步 C#调用python代码

string code = @"那一坨python代码"
PythonEngine.Initialize();
using (Py.GIL())
{
    PythonEngine.Exec(code);
}
        string code = @"那一坨python代码"
        PythonEngine.Initialize();
        using (Py.GIL())
        {
            PythonEngine.Exec(code);
        }

code就是刚才写的那一坨python代码 ,注意@不要忘记写了哈,不然就没法缩进。

就这么简单?对!就这么简单,哈哈哈哈。

没了,完了,调用成功了,接入完成了,哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈。(博主已疯)

至于怎么gpt和游戏进行交互,怎么弄出好玩的效果,就靠各位大佬就自己发挥想象力吧~。

下面贴上我自己的代码给大家,这部分我就放在code里面了,就不贴出来凑字数了,hhh。

这是PythonManager.cs文件

using System.IO;
using Python.Runtime;
using UnityEngine;

public class PythonManager : MonoBehaviour
{
    [SerializeField] public float _timer;
    private float _interval = 20;

    void Start()
    {
        _timer = _interval;
        // 获取python.all的路径(调用python解释器来执行python代码)
        string pythonPath = @"C:\Python311"; 
        string dllPath = Path.Combine(pythonPath, "python311.dll");
        Runtime.PythonDLL = dllPath;
    }
    
    void Update()
    {
        _timer += Time.deltaTime;
        UIManager.Instance.timer.fillAmount = _timer / _interval;
        if (_timer < _interval) return;
        //控制代码执行顺序
        if (GameManager.Instance.canReadPy && GameManager.Instance.typeDone)
        {
            ExecCode();
        }
    }

    public void ExecCode()
    {   
        string code = @"
import UnityEngine as ue
import openai
import random
objects = ue.Object.FindObjectsOfType(ue.GameObject)
duiBaQis = []
for obj in objects:
    if obj.tag == 'duiBaQi':
        duiBaQis.append(obj)
openai.api_key = '这里填在官网拿到的key'
model_engine = 'gpt-3.5-turbo' 
prompt = 'hello'
temperature = random.uniform(0.1,2)
for o in duiBaQis:
    if('@temperature:' in o.name):
        temperatureStr = format(temperature,'.2f')
        o.name = '@temperature:' + temperatureStr;
max_tokens = 255
for o in duiBaQis:
    if('@prompt:' in o.name):
        promptText = o.name.replace('@prompt:','');
        prompt = promptText
completion = openai.ChatCompletion.create(
   model='gpt-3.5-turbo',
   messages=[
     {'role': 'user', 'content': prompt}
   ],
   temperature = temperature,
   max_tokens = max_tokens
)
print(completion.choices[0].message.content)
for o in duiBaQis:
    if('@ai:' in o.name):
        o.name = '@ai:'+ completion.choices[0].message.content;
";
        GameManager.Instance.canReadPy = false;
        GameManager.Instance.typeDone = false;
        _timer = 0;

        

        PythonEngine.Initialize();
        using (Py.GIL())
        {
            PythonEngine.Exec(code);
        }

    }
}

 这是DialogueManager.cs文件

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class DialogueManager : MonoBehaviour
{
    public static DialogueManager Instance;
    public string taDialogue;

    private float _timer;
    //缓冲时间
    private float _interval = 1.6f;

    private bool _writeDone;
    private string prompt;
    public GameObject promptObj;
    public GameObject aiObj;
    public GameObject temperatureObj;


    private void Awake()
    {
        Instance = this;
    }

    private void FixedUpdate()
    {
        //判断是不是点击完成了,如果点击了,就开始计时,然后执行readfile函数,放出ai的内容
        if (_writeDone)
        {
            _timer += Time.deltaTime;
            if (_timer >= _interval)
            {
                _writeDone = false;
                _timer = 0;
                ReadFile();
            }
        }
    }

    public void ReadFile()
    {
        //读取在temperature游戏物体的名字,来显示诚恳度,然后更改进度条。
        float temperature = float.Parse(temperatureObj.name.Replace("@temperature:", ""));
        GameManager.Instance.volume = temperature;

        //读取ai游戏物体的名字,来显示ai的内容
        string aiText = aiObj.name.Replace("@ai:", "");
        //哈哈哈,这里就体现我的菜了,不会正则,正能这样傻瓜式的校验
        if (aiText.Contains("AI") || aiText.Contains("ai") || aiText.Contains("语言模型") || aiText.Contains("开发") || aiText.Contains("人工智能")|| aiText.Contains("程序"))
        {
            aiText = aiText.Replace("AI", UIManager.Instance.taName.text);
            aiText = aiText.Replace("ai", UIManager.Instance.taName.text);
            aiText = aiText.Replace("语言模型", "玩伴");
            aiText = aiText.Replace("开发", "培育出来");
            aiText = aiText.Replace("人工智能", "超级聪明");
            aiText = aiText.Replace("程序", "人");
        }
        taDialogue = aiText;
        Debug.Log("@ReadSuccess");
        StartCoroutine(Type(taDialogue));
        Debug.Log(taDialogue);
        

    }

    //这个函数是在玩家输入完毕以后调用的,用的是On End Edit事件,在input field这个组件里面可以看到
    public void Ask(string ask)
    {
        prompt = ask;
    }
    //这个函数是按下准备按钮以后调用的,调用的是On Click事件,在button这个组件里可以看到
    public void WriteFile()
    {
        //加个判断条件,免得玩家们太多兴奋一直按个不停,导致我们的钱钱不断流失,哈哈哈,因为每次发请求都是要收费的呀!!!
        if (UIManager.Instance.timer.fillAmount < 0.99f)
        {
            UIManager.Instance.warning.SetActive(true);
            return;
        }

        UIManager.Instance.taDialogue.text = UIManager.Instance.taName.text + "正在思考哦~";
        
        if (prompt == "")
        {
            prompt = "hello";
        }
        
        promptObj.name = "@prompt:" + prompt;//这里就是更改游戏物体的名字为我们设置好的prompt了,注意"@prompt:"不要忘记了,因为我们在python里是通过这个来查找的
        
        GameManager.Instance.canReadPy = true;
        GameManager.Instance.typeDone = true;

        _writeDone = true;
        Debug.Log("@WriteSuccess");

    }

    private IEnumerator Type(string str)
    {
        UIManager.Instance.taDialogue.text = "";
        for (int i = 0; i < str.Length; i++)
        {
            UIManager.Instance.taDialogue.text += str[i];
            yield return null;
        }
    }
}

既然都贴出来了,那就讲一下吧(其实都在注释里写上了),大家完全可以不用看的,就是我自己想写一下,hh,上面讲的那些就是核心了,这部分大家可以自己发挥创意的。

python.runtime.dll,捣鼓一些好玩的东西,chatgpt,unity,python,c#

我的思路就是玩家可以输入文字(那个输入框),然后输入完以后会调用ask函数,然后把输入的内容传到prompt里,然后接着玩家点击小爪子(那个按钮)就会执行writefile函数(但是呢?还要先校验一下是不是在冷却时间里,我的ui改变都是在UIManager里完成的)

然后这是代码:

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public static UIManager Instance;
    public Image chenKenDu;
    private float _value;
    public Text youName;
    public Text taName;
    public Text taDialogue;
    public Image timer;
    public GameObject warning;
    public Text error;
    public bool useGpt;
    private void Awake()
    {
        Instance = this;
        _value = useGpt ? 2 : 200;
    }
    

    public IEnumerator ChangeValueToUI()
    {
        chenKenDu.fillAmount = 0;
        var filla = GameManager.Instance.volume / _value;
        
        var f = filla / 60;
        for (float i = 0; i < filla; i += f)
        {
            yield return null;
            chenKenDu.fillAmount += f;
        }
    }
}

接着上面的讲,执行完WriteFile这个函数以后,就会把这三个bool值改成true,一旦为true了,PythonManager里马上就会检测到,然后执行ExceCod函数,运行python代码。这个时候_writeDone也成true了,然后开始计时,计时1.6s以后执行readfile函数,读取游戏物体的名字,然后在UI里显示出来。

至此,ChatGPT的接入就完全结束了,感谢大家能读到  3.第三步 C#调用python代码 或者能坚持读到这里,哈哈哈,那就不浪费大家时间了,就这样,结束!拜拜!文章来源地址https://www.toymoban.com/news/detail-627784.html

到了这里,关于Unity接入ChatGPT基于Python.Runtime的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【unity】Runtime Editor的简单使用

    版本v2.26 定位、旋转、伸缩变形句柄 添加句柄预制体 位置:Battlehub→RTEditor→Content→Runtime→RTHandles→Prefabs PositionHandle(移动句柄) RotationHandle(旋转句柄) ScaleHandle(缩放句柄) 将预制体拖入场景中 下面以PositionHandle(移动句柄)为例,其余句柄使用方法都一样 选中编辑

    2024年02月09日
    浏览(35)
  • 详细介绍 Yolov5 转 ONNX模型 + 使用ONNX Runtime 的 Python 部署(包含官方文档的介绍)

    对ONNX的介绍强烈建议看,本文做了很多参考:模型部署入门教程(一):模型部署简介 模型部署入门教程(三):PyTorch 转 ONNX 详解 以及Pytorch的官方介绍:(OPTIONAL) EXPORTING A MODEL FROM PYTORCH TO ONNX AND RUNNING IT USING ONNX RUNTIME C++的部署:详细介绍 Yolov5 转 ONNX模型 + 使用 ONNX Runti

    2024年02月01日
    浏览(51)
  • [Unity] GraphView 可视化节点的事件行为树(一) Runtime Node

            这个框架最近自己终于补充完成了,使用文档和源码已经放在了Github上,可以在之前的文章中找到: [Unity] 使用GraphView实现一个可视化节点的事件行为树系统(序章/Github下载)_Sugarzo的博客-CSDN博客_unity graphview                  本文将开始介绍Runtime部分的

    2024年02月07日
    浏览(36)
  • Unity 数据读取|(三)ini文件解析(INIParser,StreamReader,System.Runtime.InteropServices)

    INI文件是一种纯文本文件,通常用于存储应用程序的配置信息。它由多个节( section )和键值对( key-value pair )组成,可以方便地组织和管理配置信息。INI文件的特点包括易于编辑和阅读,结构简单,支持多层级节,不支持数据类型等。在Windows操作系统中,INI文件被广泛应

    2024年02月02日
    浏览(53)
  • 基于onnx模型和onnx runtime推理stable diffusion

    直接用diffusers的pipeline: 在pipeline_onnx_stable_diffusion的基础上修改得到的直接调用onnx模型版本,可以用于其他推理引擎推理参考: pipe_onnx_simple.py onnx_utils_simple.py 生成1张512x512图的shape信息

    2024年02月11日
    浏览(39)
  • 【工具插件类教学】Unity运行时监控变量,属性,事件等的值和调用Runtime Monitoring

    目录 一、介绍 二、安装方式 三、入门 1.实例化和静态成员

    2024年02月21日
    浏览(52)
  • Unity接入ChatGPT实现NPC聊天

    实现要求 1、能向OpenAI官网发送消息         API官网:https://api.openai.com/v1/chat/completions 2、拥有自己的APIKey 1、明确发送消息的格式 2、明确收取消息的格式 转化成对象类   能一本正经地回答一些呆瓜问题,挺好玩的,聊得越多越了解你,经过一定训练能当游戏的NPC。

    2024年02月21日
    浏览(40)
  • 【Unity 踩坑系列】配置VScode的C#环境自动下载 .NET Runtime Failed to download 问题解决后续!!!

    想必大家这几天肯定都被Vscode C#插件的自动下载.net runtime的问题所烦恼,之前我也出了一期文章是来解决这个问题的但是,只是解决了部分网友们的问题有部分网友还是会自动下载! 【Unity 踩坑系列】配置VScode环境Downloading the.NET Runtime Failed to download 之前没看过这篇解决方案

    2024年02月10日
    浏览(45)
  • Unity 2021 打包WebGL之后,用火狐浏览器打开报错,报错信息:Uncaught ReferenceError: Runtime is not defined

    Unity 发布WebGL,使用火狐浏览器打开报错 报错信息:Uncaught ReferenceError: Runtime is not defined 查找了半天的原因,发现是使用网络通讯的问题 参考网址:https://stackoverflow.com/questions/70411564/unity-webgl-throws-error-referenceerror-runtime-is-not-defined 发现如果不是使用WebSocket写的话,会不知道如

    2024年02月05日
    浏览(54)
  • Python如何接入ChatGPT

    ChatGPT现在越来越火,许多小伙伴都不知道如何去使用,或者没有梯子/国外手机号注册,Pycharm中可以安装nexchatgpt来使用,给有需要的小伙伴门做参考。 ChatGPT是一种基于GPT模型的聊天机器人,可以与人类进行自然语言交互,回答问题或通过对话提供有用的信息。它使用深度学

    2023年04月09日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包