Unity接入ChatGPT:实现游戏AI对话系统

[复制链接]
查看1102 | 回复0 | 2024-11-27 14:37:36 | 显示全部楼层 |阅读模式
本项目工程是用2022.3.17f1c1,亲测可用,工程在附件链接里。
资源均来源于网络,仅供学习和参考使用,版权归原作者所有,勿作商业用途,请在下载后24小时之内自觉删除。
本站发布的内容若无意中侵犯到您的权益,请联系我们,本站将在看到后立即删除。
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.Events;
  6. using UnityEngine.Networking;
  7. /// <summary>
  8. /// ChatGpt的管理器。
  9. /// </summary>
  10. public class ChatGptManager : MonoBehaviour
  11. {
  12.     //构造方法私有化,防止外部new对象。
  13.     private ChatGptManager() { }

  14.     //提供一个属性给外部访问,这个属性就相当于是单例对象。
  15.     private static ChatGptManager instance;
  16.     public static ChatGptManager Instance
  17.     {
  18.         get
  19.         {
  20.             if (instance==null)
  21.             {
  22.                 instance = FindObjectOfType<ChatGptManager>();
  23.                 if (instance == null)
  24.                 {
  25.                     GameObject go = new GameObject("ChatGptManager");//创建游戏对象
  26.                     instance=go.AddComponent<ChatGptManager>();//挂载脚本到游戏对象身上
  27.                     DontDestroyOnLoad(go);
  28.                 }
  29.             }
  30.             return instance;
  31.         }
  32.     }

  33.     //要调用ChatGpt的API的网址。
  34.     //string chatGptUrl = "https://use.52apikey.cn/v1/chat/completions";
  35.     //https://my.52apikey.cn/ 令牌key查询
  36.     string chatGptUrl = "https://api.openai.com/v1/chat/completions";

  37.     //使用的ChatGPT的模型
  38.     //string chatGptModel = "gpt-3.5-turbo";
  39.     string chatGptModel = "gpt-4o-mini";

  40.     //使用的ChatGPT的API Key
  41.     string chatGptApiKey = "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-phS90j9w3JegjDorN9qwldpxF3DWJNTAy6vCqiDE1JP9D8Ld";

  42.     //AI人设的提示词
  43.     public string aiRolePrompt = "和我是青梅竹马的女孩子";

  44.     //与ChatGPT的聊天记录。
  45.     public List<PostDataBody> chatRecords = new List<PostDataBody>();


  46.     void Awake()
  47.     {
  48.         //给AI设定的人设。
  49.         chatRecords.Add(new PostDataBody("system", aiRolePrompt));
  50.     }

  51.     /// <summary>
  52.     /// 异步向ChatGPT发送消息(不连续对话)
  53.     /// </summary>
  54.     /// <param name="message">询问ChatGPT的内容</param>
  55.     /// <param name="callback">回调</param>
  56.     /// <param name="aiRole">ChatGPT要扮演的角色</param>
  57.     public void ChatDiscontinuously(string message,UnityAction<string> callback,string aiRole="")
  58.     {
  59.         //构造要发送的数据。
  60.         PostData postData = new PostData
  61.         {
  62.             //使用的ChatGPT的模型
  63.             model = chatGptModel,

  64.             //要发送的消息
  65.             messages = new List<PostDataBody>()
  66.             {
  67.                 new PostDataBody("system",aiRole),
  68.                 new PostDataBody("user",message)
  69.             }
  70.         };

  71.         //异步向ChatGPT发送数据。
  72.         SendPostData(postData, callback);
  73.     }

  74.     /// <summary>
  75.     /// 异步向ChatGPT发送消息(连续对话)
  76.     /// </summary>
  77.     /// <param name="message">询问ChatGPT的内容</param>
  78.     /// <param name="callback">回调</param>
  79.     public void ChatContinuously(string message,UnityAction<string> callback)
  80.     {
  81.         //缓存聊天记录
  82.         chatRecords.Add(new PostDataBody("user",message));

  83.         //构造要发送的数据。
  84.         PostData postData = new PostData
  85.         {
  86.             //使用的ChatGPT的模型
  87.             model = chatGptModel,

  88.             //要发送的消息
  89.             messages = chatRecords
  90.         };

  91.         //异步向ChatGPT发送数据。
  92.         SendPostData(postData, callback);
  93.     }

  94.     /// <summary>
  95.     /// 清空ChatGPT的聊天记录,并重新设置连续对话时,AI的人设。
  96.     /// </summary>
  97.     /// <param name="aiRolePrompt">AI的人设。我们可以用一段话来描述这个人设。</param>
  98.     public void ClearChatRecordsAndSetAiRole(string aiRolePrompt="")
  99.     {
  100.         //清空聊天记录。
  101.         chatRecords.Clear();

  102.         //给AI设定人设。
  103.         chatRecords.Add(new PostDataBody("system", aiRolePrompt));
  104.     }

  105.     public void SendPostData(PostData postData, UnityAction<string> callback)
  106.     {
  107.         StartCoroutine(SendPostDataCoroutine(postData,callback));
  108.     }
  109.     IEnumerator SendPostDataCoroutine(PostData postData, UnityAction<string> callback)
  110.     {
  111.         //创建一个UnityWebRequest类的对象用于发送网络请求。POST表示向服务器发送数据。using关键字用于在执行完这段语句之后释放这个UnityWebRequest类的对象。
  112.         using (UnityWebRequest request = new UnityWebRequest(chatGptUrl, "POST"))
  113.         {
  114.             //把传输的消息的对象转换为JSON格式的字符串。
  115.             string jsonString = JsonUtility.ToJson(postData);

  116.             //把JSON格式的字符串转换为字节数组,以便进行网络传输。
  117.             byte[] data = System.Text.Encoding.UTF8.GetBytes(jsonString);

  118.             //设置要上传到远程服务器的主体数据。
  119.             request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);

  120.             //设置从远程服务器接收到的主体数据。
  121.             request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();

  122.             //设置HTTP网络请求的标头。表示这个网络请求的正文采用JSON格式进行编码。
  123.             request.SetRequestHeader("Content-Type", "application/json");

  124.             //设置HTTP网络请求的标头。这里的写法是按照OpenAI官方要求来写的。
  125.             request.SetRequestHeader("Authorization", string.Format("Bearer {0}", chatGptApiKey));

  126.             //等待ChatGPT回复。
  127.             yield return request.SendWebRequest();

  128.             //回复码是200表示成功,404表示未找到,500表示服务器内部错误。
  129.             if (request.responseCode == 200)
  130.             {
  131.                 //获取ChatGPT回复的字符串,此时它是一个JSON格式的字符串。
  132.                 string respondedString = request.downloadHandler.text;

  133.                 //将ChatGPT回复的JSON格式的字符串转换为指定的类的对象。
  134.                 RespondedData respondedMessages = JsonUtility.FromJson<RespondedData>(respondedString);

  135.                 //如果ChatGPT有回复我们,则我们就挑第0条消息来显示。
  136.                 if (respondedMessages != null && respondedMessages.choices.Count > 0)
  137.                 {
  138.                     //获取第0条消息的字符串。
  139.                     string respondedMessage = respondedMessages.choices[0].message.content;

  140.                     //执行回调。
  141.                     callback?.Invoke(respondedMessage);
  142.                 }
  143.             }
  144.         }
  145.     }

  146.     //发送给ChatGPT的数据
  147.     [Serializable]
  148.     public class PostData
  149.     {
  150.         //使用哪一个ChatGPT的模型
  151.         public string model;

  152.         //发送给ChatGPT的消息。
  153.         //如果发送的列表含有多条消息,则ChatGPT会根据上下文来回复。
  154.         public List<PostDataBody> messages;
  155.     }

  156.     [Serializable]
  157.     public class PostDataBody
  158.     {
  159.         //说话的角色
  160.         public string role;

  161.         //说话的内容
  162.         public string content;

  163.         //构造方法
  164.         public PostDataBody() { }
  165.         public PostDataBody(string role, string content)
  166.         {
  167.             this.role = role;
  168.             this.content = content;
  169.         }
  170.     }

  171.     //ChatGPT回复我们的数据
  172.     [Serializable]
  173.     public class RespondedData
  174.     {
  175.         public string id;
  176.         public string created;
  177.         public string model;
  178.         public List<RespondedChoice> choices;
  179.     }
  180.     [Serializable]
  181.     public class RespondedChoice
  182.     {
  183.         public RespondedDataBody message;
  184.         public string finish_reason;
  185.         public int index;
  186.     }
  187.     [Serializable]
  188.     public class RespondedDataBody
  189.     {
  190.         public string role;
  191.         public string content;
  192.     }
  193. }
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

10

主题

10

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
10152