├── .gitignore ├── Chat.cs ├── Chat.cs.meta ├── ChatGPTConversation.cs ├── ChatGPTConversation.cs.meta ├── ChatGPTWrapper.asmdef ├── ChatGPTWrapper.asmdef.meta ├── Editor.meta ├── Editor ├── ChatGPTEditor.cs ├── ChatGPTEditor.cs.meta ├── ChatGPTWrapper.Editor.asmdef └── ChatGPTWrapper.Editor.asmdef.meta ├── GenericUnityEvents.cs ├── GenericUnityEvents.cs.meta ├── LICENSE ├── LICENSE.meta ├── Prompt.cs ├── Prompt.cs.meta ├── README.md ├── README.md.meta ├── Requests.cs ├── Requests.cs.meta ├── UI.meta ├── UI ├── UI.cs ├── UI.cs.meta ├── UI.uxml ├── UI.uxml.meta ├── styles.uss └── styles.uss.meta ├── WebRequestClasses.meta ├── WebRequestStructs.meta ├── WebRequestStructs ├── ChatGPTChoices.cs ├── ChatGPTChoices.cs.meta ├── ChatGPTReq.cs ├── ChatGPTReq.cs.meta ├── ChatGPTRes.cs ├── ChatGPTRes.cs.meta ├── GPTChoices.cs ├── GPTChoices.cs.meta ├── GPTReq.cs ├── GPTReq.cs.meta ├── GPTRes.cs ├── GPTRes.cs.meta ├── GPTResError.cs ├── GPTResError.cs.meta ├── Message.cs ├── Message.cs.meta ├── ProxyReq.cs └── ProxyReq.cs.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /Chat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace ChatGPTWrapper { 5 | // Due to OpenAI's new chat completions api, this replaces the old "Prompt" class, but the prompt class is still used for the older models. 6 | public class Chat 7 | { 8 | private string _initialPrompt; 9 | private List _currentChat = new List(); 10 | 11 | public Chat(string initialPrompt) { 12 | _initialPrompt = initialPrompt; 13 | Message systemMessage = new Message("system", initialPrompt); 14 | _currentChat.Add(systemMessage); 15 | } 16 | public List CurrentChat { get { return _currentChat; } } 17 | 18 | public enum Speaker { 19 | User, 20 | ChatGPT 21 | } 22 | 23 | public void AppendMessage(Speaker speaker, string text) 24 | { 25 | 26 | switch (speaker) 27 | { 28 | case Speaker.User: 29 | Message userMessage = new Message("user", text); 30 | _currentChat.Add(userMessage); 31 | break; 32 | case Speaker.ChatGPT: 33 | Message chatGPTMessage = new Message("assistant", text); 34 | _currentChat.Add(chatGPTMessage); 35 | break; 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chat.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfa1bd79ef604394e9dec016f1c8a2b7 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /ChatGPTConversation.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using Reqs; 4 | 5 | namespace ChatGPTWrapper { 6 | 7 | public class ChatGPTConversation : MonoBehaviour 8 | { 9 | [SerializeField] 10 | private bool _useProxy = false; 11 | [SerializeField] 12 | private string _proxyUri = null; 13 | 14 | [SerializeField] 15 | private string _apiKey = null; 16 | 17 | public enum Model { 18 | ChatGPT, 19 | Davinci, 20 | Curie 21 | } 22 | [SerializeField] 23 | public Model _model = Model.ChatGPT; 24 | private string _selectedModel = null; 25 | [SerializeField] 26 | private int _maxTokens = 500; 27 | [SerializeField] 28 | private float _temperature = 0.5f; 29 | 30 | private string _uri; 31 | private List<(string, string)> _reqHeaders; 32 | 33 | 34 | private Requests requests = new Requests(); 35 | private Prompt _prompt; 36 | private Chat _chat; 37 | private string _lastUserMsg; 38 | private string _lastChatGPTMsg; 39 | 40 | [SerializeField] 41 | private string _chatbotName = "ChatGPT"; 42 | 43 | [TextArea(4,6)] 44 | [SerializeField] 45 | private string _initialPrompt = "You are ChatGPT, a large language model trained by OpenAI."; 46 | 47 | public UnityStringEvent chatGPTResponse = new UnityStringEvent(); 48 | 49 | private void OnEnable() 50 | { 51 | 52 | TextAsset textAsset = Resources.Load("APIKEY"); 53 | if (textAsset != null) { 54 | _apiKey = textAsset.text; 55 | } 56 | 57 | 58 | _reqHeaders = new List<(string, string)> 59 | { 60 | ("Authorization", $"Bearer {_apiKey}"), 61 | ("Content-Type", "application/json") 62 | }; 63 | switch (_model) { 64 | case Model.ChatGPT: 65 | _chat = new Chat(_initialPrompt); 66 | _uri = "https://api.openai.com/v1/chat/completions"; 67 | _selectedModel = "gpt-3.5-turbo"; 68 | break; 69 | case Model.Davinci: 70 | _prompt = new Prompt(_chatbotName, _initialPrompt); 71 | _uri = "https://api.openai.com/v1/completions"; 72 | _selectedModel = "text-davinci-003"; 73 | break; 74 | case Model.Curie: 75 | _prompt = new Prompt(_chatbotName, _initialPrompt); 76 | _uri = "https://api.openai.com/v1/completions"; 77 | _selectedModel = "text-curie-001"; 78 | break; 79 | } 80 | } 81 | 82 | public void ResetChat(string initialPrompt) { 83 | switch (_model) { 84 | case Model.ChatGPT: 85 | _chat = new Chat(initialPrompt); 86 | break; 87 | default: 88 | _prompt = new Prompt(_chatbotName, initialPrompt); 89 | break; 90 | } 91 | } 92 | 93 | public void SendToChatGPT(string message) 94 | { 95 | _lastUserMsg = message; 96 | 97 | if (_model == Model.ChatGPT) { 98 | if (_useProxy) { 99 | ProxyReq proxyReq = new ProxyReq(); 100 | proxyReq.max_tokens = _maxTokens; 101 | proxyReq.temperature = _temperature; 102 | proxyReq.messages = new List(_chat.CurrentChat); 103 | proxyReq.messages.Add(new Message("user", message)); 104 | 105 | string proxyJson = JsonUtility.ToJson(proxyReq); 106 | 107 | StartCoroutine(requests.PostReq(_proxyUri, proxyJson, ResolveChatGPT, _reqHeaders)); 108 | } else { 109 | ChatGPTReq chatGPTReq = new ChatGPTReq(); 110 | chatGPTReq.model = _selectedModel; 111 | chatGPTReq.max_tokens = _maxTokens; 112 | chatGPTReq.temperature = _temperature; 113 | chatGPTReq.messages = _chat.CurrentChat; 114 | chatGPTReq.messages.Add(new Message("user", message)); 115 | 116 | string chatGPTJson = JsonUtility.ToJson(chatGPTReq); 117 | 118 | StartCoroutine(requests.PostReq(_uri, chatGPTJson, ResolveChatGPT, _reqHeaders)); 119 | } 120 | 121 | } else { 122 | 123 | _prompt.AppendText(Prompt.Speaker.User, message); 124 | 125 | GPTReq reqObj = new GPTReq(); 126 | reqObj.model = _selectedModel; 127 | reqObj.prompt = _prompt.CurrentPrompt; 128 | reqObj.max_tokens = _maxTokens; 129 | reqObj.temperature = _temperature; 130 | string json = JsonUtility.ToJson(reqObj); 131 | 132 | StartCoroutine(requests.PostReq(_uri, json, ResolveGPT, _reqHeaders)); 133 | } 134 | } 135 | 136 | private void ResolveChatGPT(ChatGPTRes res) 137 | { 138 | _lastChatGPTMsg = res.choices[0].message.content; 139 | _chat.AppendMessage(Chat.Speaker.User, _lastUserMsg); 140 | _chat.AppendMessage(Chat.Speaker.ChatGPT, _lastChatGPTMsg); 141 | chatGPTResponse.Invoke(_lastChatGPTMsg); 142 | } 143 | 144 | private void ResolveGPT(GPTRes res) 145 | { 146 | _lastChatGPTMsg = res.choices[0].text 147 | .TrimStart('\n') 148 | .Replace("<|im_end|>", ""); 149 | 150 | _prompt.AppendText(Prompt.Speaker.Bot, _lastChatGPTMsg); 151 | chatGPTResponse.Invoke(_lastChatGPTMsg); 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /ChatGPTConversation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cd863684a93292844b47a08ec0809828 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /ChatGPTWrapper.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ChatGPTWrapper" 3 | } 4 | -------------------------------------------------------------------------------- /ChatGPTWrapper.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e2dd40b6c1f59ce4aa07be2b237fc5ee 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 48e67fbffe5546a478b00abaffd1333e 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/ChatGPTEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace ChatGPTWrapper { 5 | [CustomEditor(typeof(ChatGPTConversation))] 6 | public class ChatGPTEditor : Editor 7 | { 8 | SerializedProperty _useProxy; 9 | SerializedProperty _proxyUri; 10 | SerializedProperty _apiKey; 11 | SerializedProperty _model; 12 | SerializedProperty _maxTokens; 13 | SerializedProperty _temperature; 14 | SerializedProperty _chatbotName; 15 | SerializedProperty _initialPrompt; 16 | SerializedProperty chatGPTResponse; 17 | 18 | 19 | private void OnEnable() 20 | { 21 | _useProxy = serializedObject.FindProperty("_useProxy"); 22 | _proxyUri = serializedObject.FindProperty("_proxyUri"); 23 | _apiKey = serializedObject.FindProperty("_apiKey"); 24 | _model = serializedObject.FindProperty("_model"); 25 | _maxTokens = serializedObject.FindProperty("_maxTokens"); 26 | _temperature = serializedObject.FindProperty("_temperature"); 27 | _chatbotName = serializedObject.FindProperty("_chatbotName"); 28 | _initialPrompt = serializedObject.FindProperty("_initialPrompt"); 29 | chatGPTResponse = serializedObject.FindProperty("chatGPTResponse"); 30 | 31 | } 32 | public override void OnInspectorGUI() 33 | { 34 | serializedObject.Update(); 35 | 36 | EditorGUILayout.LabelField("Parameters", EditorStyles.boldLabel); 37 | EditorGUILayout.PropertyField(_useProxy); 38 | if (_useProxy.boolValue == true) { 39 | EditorGUILayout.PropertyField(_proxyUri); 40 | } else { 41 | EditorGUILayout.PropertyField(_apiKey); 42 | } 43 | EditorGUILayout.PropertyField(_model); 44 | EditorGUILayout.PropertyField(_maxTokens); 45 | EditorGUILayout.PropertyField(_temperature); 46 | 47 | 48 | EditorGUILayout.Space(5); 49 | 50 | EditorGUILayout.LabelField("Prompt", EditorStyles.boldLabel); 51 | 52 | if (_model.enumValueIndex != 0) { 53 | EditorGUILayout.PropertyField(_chatbotName); 54 | } 55 | EditorGUILayout.PropertyField(_initialPrompt); 56 | 57 | EditorGUILayout.Space(20); 58 | 59 | EditorGUILayout.PropertyField(chatGPTResponse); 60 | 61 | 62 | serializedObject.ApplyModifiedProperties(); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /Editor/ChatGPTEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a10d5baffc0044b49afa601a4188bb93 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/ChatGPTWrapper.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ChatGPTWrapper.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:e2dd40b6c1f59ce4aa07be2b237fc5ee" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/ChatGPTWrapper.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3cb7f3aa65ec2ca489aa8ebe8f77ead3 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /GenericUnityEvents.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine.Events; 3 | 4 | namespace ChatGPTWrapper { 5 | // This is required for older versions of Unity 6 | [System.Serializable] 7 | public class UnityStringEvent : UnityEvent{} 8 | } -------------------------------------------------------------------------------- /GenericUnityEvents.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 53fd5614b7a894e4b80c932064c8ab02 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 GraesonB 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 725f609703bc3e14b9734f38397a272c 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Prompt.cs: -------------------------------------------------------------------------------- 1 | namespace ChatGPTWrapper { 2 | public class Prompt 3 | { 4 | private string _initialPrompt; 5 | private string _chatbotName; 6 | public Prompt(string chatbotName, string initialPrompt) { 7 | _initialPrompt = initialPrompt; 8 | _chatbotName = chatbotName; 9 | } 10 | private string _currentPrompt; 11 | public string CurrentPrompt { get { return _currentPrompt; } } 12 | 13 | public enum Speaker { 14 | User, 15 | Bot 16 | } 17 | 18 | public void AppendText(Speaker speaker, string text) 19 | { 20 | if (_currentPrompt == null) _currentPrompt = _initialPrompt; 21 | switch (speaker) 22 | { 23 | case Speaker.User: 24 | _currentPrompt += " \n User: " + text + " \n " + _chatbotName + ": "; 25 | break; 26 | case Speaker.Bot: 27 | _currentPrompt += text; 28 | break; 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Prompt.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5316b1f3b2c8493488fe4b621d1f79e6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChatGPT Unity Wrapper 2 | This wrapper serves as an easy-to-use tool for those looking to explore ChatGPT applications in game development. 3 | 4 | ### 🚨 IMPORTANT NOTE 🚨 5 | In its current state, this wrapper is not suitable for production use. If you ship a game with your API key inside, it has potential to get leaked. I will work on setting up a proxy server template that can be self-hosted or hosted on Cloudflare so you can protect your key, and the server will also be able to pipe your data into a database so you can save your conversations and load them in later. In the mean time, happy prototyping :-) 6 | 7 | ## Guide 8 | 1. Either download the zip and extract it into an existing Unity project, or clone the repo into your project's Assets directory.
9 | If you are using a version of Unity that does not support Unity's UI Toolkit, you can just delete the whole UI folder as it's not required.
10 | Also you can import package using **Unity Package Manager** (**Add package from Git URL** - https://github.com/GraesonB/ChatGPT-Wrapper-For-Unity.git) or just add "com.graesonb.chat-gpt-wrapper-for-unity": "https://github.com/GraesonB/ChatGPT-Wrapper-For-Unity.git" to **Packages/manifest.json** 11 | 12 | 2. Create an empty game object, and add the "ChatGPTConversation" script to it. 13 | ![Screenshot 2023-03-01 at 8 41 26 PM](https://user-images.githubusercontent.com/89364458/222325449-47a833a6-9f10-4583-a78d-69aef54b7e3d.png) 14 | 15 | 3. Add your API key (you can generate your own key on OpenAI's website), and set your parameters. 16 | 17 | 4. Use the UnityEvent below the parameters to subscribe something to ChatGPT's response (a function/method that takes a string as an argument). 18 | 19 | 5. Create a UnityStringEvent somewhere else in your project, and add ChatGPTConversation's method "SendToChatGPT" to the newly created event. 20 | 21 | Congrats, now whenever your new UnityEvent is invoked, a request will be sent to ChatGPT's API, and whatever is subscribed to ChatGPT's response will be notified as soon as a response is received. Have fun! 22 | 23 | 24 | Here's a screenshot of a demo I put together with a simple UI. The UI files are included in the repo, however, you'll have to setup the UnityEvents and plugin the UI elements yourself. If anyone is interested I can also upload the whole project file. 25 | ![Screenshot 2023-02-05 at 10 47 13 PM](https://user-images.githubusercontent.com/89364458/216893256-efe3d9e2-fb7d-4833-bae5-9dcb0e9d5717.png) 26 | 27 | 28 | ## Credits 29 | This repo gave me the idea to do this in Unity:
30 | https://github.com/acheong08/ChatGPT 31 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c9a073ff786c6284394dee28ebe007c2 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Requests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Networking; 5 | using ChatGPTWrapper; 6 | 7 | namespace Reqs { 8 | 9 | public class Requests 10 | { 11 | private void SetHeaders(ref UnityWebRequest req, List<(string, string)> headers) 12 | { 13 | for (int i = 0; i < headers.Count; i++) 14 | { 15 | req.SetRequestHeader(headers[i].Item1, headers[i].Item2); 16 | } 17 | } 18 | 19 | public IEnumerator GetReq(string uri, System.Action callback, List<(string, string)> headers = null) 20 | { 21 | UnityWebRequest webRequest = new UnityWebRequest(uri, "GET"); 22 | if (headers != null) SetHeaders(ref webRequest, headers); 23 | webRequest.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer(); 24 | webRequest.disposeUploadHandlerOnDispose = true; 25 | webRequest.disposeDownloadHandlerOnDispose = true; 26 | 27 | yield return webRequest.SendWebRequest(); 28 | 29 | #if UNITY_2020_3_OR_NEWER 30 | switch (webRequest.result) 31 | { 32 | case UnityWebRequest.Result.ConnectionError: 33 | case UnityWebRequest.Result.DataProcessingError: 34 | Debug.LogError("Error: " + webRequest.error); 35 | break; 36 | case UnityWebRequest.Result.ProtocolError: 37 | Debug.LogError("HTTP Error: " + webRequest.error); 38 | break; 39 | case UnityWebRequest.Result.Success: 40 | var responseJson = JsonUtility.FromJson(webRequest.downloadHandler.text); 41 | callback(responseJson); 42 | break; 43 | } 44 | #else 45 | if(!string.IsNullOrWhiteSpace(webRequest.error)) 46 | { 47 | Debug.LogError($"Error {webRequest.responseCode} - {webRequest.error}"); 48 | yield break; 49 | } 50 | else 51 | { 52 | var responseJson = JsonUtility.FromJson(webRequest.downloadHandler.text); 53 | callback(responseJson); 54 | } 55 | #endif 56 | webRequest.Dispose(); 57 | 58 | } 59 | 60 | public IEnumerator PostReq(string uri, string json, System.Action callback, List<(string, string)> headers = null) 61 | { 62 | UnityWebRequest webRequest = new UnityWebRequest(uri, "POST"); 63 | if (headers != null) SetHeaders(ref webRequest, headers); 64 | 65 | byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json); 66 | webRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend); 67 | webRequest.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); 68 | webRequest.disposeDownloadHandlerOnDispose = true; 69 | webRequest.disposeUploadHandlerOnDispose = true; 70 | 71 | yield return webRequest.SendWebRequest(); 72 | 73 | #if UNITY_2020_3_OR_NEWER 74 | switch (webRequest.result) 75 | { 76 | case UnityWebRequest.Result.ConnectionError: 77 | case UnityWebRequest.Result.DataProcessingError: 78 | Debug.LogError("Error: " + webRequest.error); 79 | break; 80 | case UnityWebRequest.Result.ProtocolError: 81 | Debug.LogError("HTTP Error: " + webRequest.error); 82 | if (uri.EndsWith("/completions")) { 83 | var errJson = JsonUtility.FromJson(webRequest.downloadHandler.text); 84 | Debug.LogError(errJson.error.message); 85 | if (webRequest.error == "HTTP/1.1 429 Too Many Requests") 86 | { 87 | Debug.Log("retrying..."); 88 | yield return PostReq(uri, json, callback, headers); 89 | } 90 | } 91 | break; 92 | case UnityWebRequest.Result.Success: 93 | var responseJson = JsonUtility.FromJson(webRequest.downloadHandler.text); 94 | callback(responseJson); 95 | break; 96 | } 97 | #else 98 | if(!string.IsNullOrWhiteSpace(webRequest.error)) 99 | { 100 | Debug.LogError($"Error {webRequest.responseCode} - {webRequest.error}"); 101 | yield break; 102 | } 103 | else 104 | { 105 | var responseJson = JsonUtility.FromJson(webRequest.downloadHandler.text); 106 | callback(responseJson); 107 | } 108 | #endif 109 | 110 | webRequest.Dispose(); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Requests.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43217bbb6cb2cf04b82fa9b5bd2b5a14 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UI.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 027c589cc458ab348b8b26d647a03194 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UI/UI.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Events; 3 | using UnityEngine.UIElements; 4 | using Reqs; 5 | 6 | namespace ChatGPTWrapper { 7 | public class UI : MonoBehaviour 8 | { 9 | private Requests _requests = new Requests(); 10 | private TextField inputText; 11 | private Label chatGPTText; 12 | 13 | 14 | public UnityEvent onButtonClick = new UnityEvent(); 15 | public UnityEvent onGrumpyClick = new UnityEvent(); 16 | public UnityEvent onFriendlyClick = new UnityEvent(); 17 | 18 | private void OnEnable() 19 | { 20 | 21 | // _convo = GetComponent(); 22 | VisualElement root = GetComponent().rootVisualElement; 23 | VisualElement box = root.Q("box"); 24 | Button requestOne = root.Q