using System;
using System.Collections.Generic;
using OpenAI_API;
using OpenAI_API.Chat;
using OpenAI_API.Models;
using UnityEngine;
public enum ChatMessageSampleRole
{
System,
User,
Assistant
}
[System.Serializable]
public class ChatMessageSample
{
public ChatMessageSampleRole role = ChatMessageSampleRole.System;
public string content = "Hello, World!";
}
public class OpenAIController : MonoBehaviour
{
private OpenAIAPI api;
private List<ChatMessage> messages;
private Conversation chat;
// Start is called before the first frame update
private OpenAI_TTS tts; //★
private OpenAIAnimator animator; //★
void Start()
{
api = new OpenAIAPI(Environment.GetEnvironmentVariable("OPENAI_API_KEY", EnvironmentVariableTarget.User));
tts = gameObject.GetComponent<OpenAI_TTS>(); //★
animator = gameObject.GetComponent<OpenAIAnimator>(); //★
//환경 변수로 부터 API KEY를 받아오기
StartConversation();
}
public int maxResponseWordLimit = 10;
[TextArea(3,10)]
public string personality = "수학에 관련된 답변만 해줍니다. 수학의 역사, 수에 관한 재밌는 이야기 등. 수학과 관련이 있다면 다른 과목이라도 답변을 해줍니다. 답변의 마지막엔 수학에 관한 재미있는 이야기를 하나 알려줍니다. 도덕적으로 옳지 못한것을 바로잡아줍니다.";
[TextArea(3,10)]
public string scene = "교실입니다";
public ChatMessageSample[] sample_message; //★;
public void StartConversation()
{
string defult_content = "You are a teacher and will answer to the message the player ask you. \n" +
"You must reply to the player message only using the information from your Personnality and the Scene that are provided afterwards. \n" +
"Do not invent or create response that are not mentionned in these information. \n" +
"Do not break character or mention you are an AI or a teacher. \n" +
"You must answer in less than " + maxResponseWordLimit + "words. \n" +
"Here is the information about your Personnality : \n" + personality + "\n" +
"Here is the information about the Scene around you : \n" + scene + "\n" +
"Here is the message of the player : \n";
messages = new List<ChatMessage>{
new ChatMessage(ChatMessageRole.System, defult_content)
};
//새 시스템 메세지를 생성하는 것으로 캐릭터 설정
foreach (var item in sample_message)
{
if(ChatMessageSampleRole.System == item.role)
messages.Add(new ChatMessage(ChatMessageRole.System, item.content));
else if(ChatMessageSampleRole.User == item.role)
messages.Add(new ChatMessage(ChatMessageRole.User, item.content));
else if(ChatMessageSampleRole.Assistant == item.role)
messages.Add(new ChatMessage(ChatMessageRole.Assistant, item.content));
}
//시스템 메세지를 추가하는 것으로 캐릭터 강화
}
public async void GetResponse(string ins_input_string = null)
{
Debug.Log("GetResponse");
if (ins_input_string != null) input_string = ins_input_string;
if (input_string.Length < 1) return;
isTypeable = false; //typing lock
ChatMessage userMessage = new ChatMessage();
userMessage.Role = ChatMessageRole.User;
userMessage.TextContent = input_string;
if (userMessage.TextContent.Length > 100)
{
// limit message length to 100 characters
userMessage.TextContent = userMessage.TextContent.Substring(0, 100);
} //사용자 메세지 100글자 제한 (넘을 경우 잘라냄)
output_string += string.Format("{0}:{1}", userMessage.rawRole, userMessage.TextContent) + "\n";
Debug.Log(output_string);
messages.Add(userMessage);
input_string = ""; //clear the input field
//Send the message to the API
var chatResult = await api.Chat.CreateChatCompletionAsync(
new ChatRequest()
{
Model = Model.ChatGPTTurbo,
Temperature = 0.1,
MaxTokens = 150,
Messages = messages
}
);
//메세지를 발송하고 답변을 기다림
//get the response
ChatMessage responseMessage = new ChatMessage();
responseMessage.Role = chatResult.Choices[0].Message.Role;
responseMessage.TextContent = chatResult.Choices[0].Message.TextContent;
Debug.Log(string.Format("{0}:{1}", responseMessage.rawRole, responseMessage.TextContent));
output_string += string.Format("{0}:{1}", responseMessage.rawRole, responseMessage.TextContent) + "\n";
tts.text_to_speech(responseMessage.TextContent); //★
animator.playAniamtion(responseMessage.TextContent); //★
//메세지를 전달 받으면 UI에 출력
//Add the response to the list of messages
messages.Add(responseMessage);
isTypeable = true; //typing unlock
}
private string input_string = "";
private string output_string = "";
private Vector2 scroll_pos = Vector2.zero;
private int font_size = 20;
private bool isTypeable = true;
private void OnGUI(){
//return; //이 코드를 주석 해제하면 GUI가 출력되지 않음
//Graphic User Interface 출력
if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return){
GetResponse();
}
GUIStyle LabelStyle = new GUIStyle(GUI.skin.label);
LabelStyle.fontSize = font_size;
GUIStyle TextAreaStyle = new GUIStyle(GUI.skin.textArea);
TextAreaStyle.fontSize = font_size;
GUIStyle verticalScrollbar = GUI.skin.verticalScrollbar;
GUILayout.BeginVertical();
scroll_pos = GUILayout.BeginScrollView(scroll_pos, GUILayout.Width(400), GUILayout.Height(300));
GUILayout.Label(output_string, TextAreaStyle);
GUILayout.EndScrollView();
scroll_pos.y = Mathf.Infinity; //scroll_pos update last line
if(isTypeable){
input_string = GUILayout.TextField(input_string, TextAreaStyle);
}else{
GUILayout.Label(input_string, TextAreaStyle);
}
GUILayout.EndVertical();
}
}