Compare commits

..

5 Commits

9 changed files with 283 additions and 55 deletions

View File

@ -282,10 +282,10 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
IsOn: 0 IsOn: 0
_turnOnTime: _turnOnTime:
_hour: 0 _hour: 21
_minutes: 0 _minutes: 0
_turnOffTime: _turnOffTime:
_hour: 0 _hour: 6
_minutes: 0 _minutes: 0
--- !u!4 &37507749 --- !u!4 &37507749
Transform: Transform:
@ -427,7 +427,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_daysUntilRelease: 20 _daysUntilRelease: 20
_secondsPerDay: 5 _secondsPerDay: 20
_totalTime: 0 _totalTime: 0
_sun: {fileID: 179279866} _sun: {fileID: 179279866}
--- !u!4 &227416519 --- !u!4 &227416519
@ -461,7 +461,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!4 &266099154 --- !u!4 &266099154
Transform: Transform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -489,8 +489,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: a61873b0f5608a44982d48387f34f682, type: 3} m_Script: {fileID: 11500000, guid: a61873b0f5608a44982d48387f34f682, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
ZombiePrefab: {fileID: 0} ZombiePrefab: {fileID: 856601670117699726, guid: a34b2d22562c7214f9daf0d3dea8d85c, type: 3}
_spawnRate: 1 _spawnRate: 2
_spawnTimer: 0 _spawnTimer: 0
--- !u!1001 &514859708 --- !u!1001 &514859708
PrefabInstance: PrefabInstance:
@ -502,7 +502,7 @@ PrefabInstance:
m_Modifications: m_Modifications:
- target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3} - target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3}
propertyPath: m_LocalPosition.x propertyPath: m_LocalPosition.x
value: 28.41 value: 28.09
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3} - target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3}
propertyPath: m_LocalPosition.y propertyPath: m_LocalPosition.y
@ -510,7 +510,7 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3} - target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3}
propertyPath: m_LocalPosition.z propertyPath: m_LocalPosition.z
value: -3.352 value: -5.49
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3} - target: {fileID: 958156999735417459, guid: 7c7f0805c6bdc4f41bd65ec128f6b658, type: 3}
propertyPath: m_LocalRotation.w propertyPath: m_LocalRotation.w
@ -616,6 +616,8 @@ MonoBehaviour:
serializedVersion: 2 serializedVersion: 2
m_Bits: 4294967295 m_Bits: 4294967295
grounded: 0 grounded: 0
_hand: {fileID: 0}
_carriedItem: {fileID: 0}
--- !u!1 &547927580 --- !u!1 &547927580
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1277,6 +1279,7 @@ MonoBehaviour:
_hungerNeed: {fileID: 0} _hungerNeed: {fileID: 0}
_wantedFood: 0 _wantedFood: 0
_toiletNeed: {fileID: 0} _toiletNeed: {fileID: 0}
_maxPrivateContextBufferSize: 5
_talkTimer: 10 _talkTimer: 10
--- !u!4 &983523620 --- !u!4 &983523620
Transform: Transform:
@ -1310,6 +1313,8 @@ MonoBehaviour:
speakingSpeed: 1.1 speakingSpeed: 1.1
playSound: 0 playSound: 0
generate: 0 generate: 0
newVoice: 0
Voice:
--- !u!114 &983523622 --- !u!114 &983523622
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1881,6 +1886,10 @@ PrefabInstance:
propertyPath: _player propertyPath: _player
value: value:
objectReference: {fileID: 514859709} objectReference: {fileID: 514859709}
- target: {fileID: 3650884189301972455, guid: e1e33f0b2075b5c40817665dd8a86f31, type: 3}
propertyPath: _maxContextBufferSize
value: 3
objectReference: {fileID: 0}
- target: {fileID: 3650884189301972455, guid: e1e33f0b2075b5c40817665dd8a86f31, type: 3} - target: {fileID: 3650884189301972455, guid: e1e33f0b2075b5c40817665dd8a86f31, type: 3}
propertyPath: _developers.Array.size propertyPath: _developers.Array.size
value: 1 value: 1
@ -2081,6 +2090,8 @@ MonoBehaviour:
speakingSpeed: 1.1 speakingSpeed: 1.1
playSound: 0 playSound: 0
generate: 0 generate: 0
newVoice: 0
Voice:
--- !u!114 &1814492793 --- !u!114 &1814492793
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -2135,6 +2146,7 @@ MonoBehaviour:
_hungerNeed: {fileID: 0} _hungerNeed: {fileID: 0}
_wantedFood: 0 _wantedFood: 0
_toiletNeed: {fileID: 0} _toiletNeed: {fileID: 0}
_maxPrivateContextBufferSize: 2
_talkTimer: 10 _talkTimer: 10
--- !u!82 &1814492795 --- !u!82 &1814492795
AudioSource: AudioSource:

View File

@ -1,7 +1,9 @@
using Microsoft.VisualStudio.Utilities;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.IO;
using UnityEngine; using UnityEngine;
using UnityEngine.Serialization; using UnityEngine.Serialization;
using Utility; using Utility;
@ -100,31 +102,52 @@ public class Developer : MonoBehaviour
[SerializeField] [SerializeField]
private GameObject _caffeineNeed; private GameObject _caffeineNeed;
[SerializeField] private WantedConsumable _wantedDrink; [SerializeField]
private WantedConsumable _wantedDrink;
[SerializeField] [SerializeField]
private GameObject _hungerNeed; private GameObject _hungerNeed;
[SerializeField] private WantedConsumable _wantedFood; [SerializeField]
private WantedConsumable _wantedFood;
[SerializeField] [SerializeField]
private GameObject _toiletNeed; private GameObject _toiletNeed;
private AudioSource _audioSource; private List<GameObject> _needList = new List<GameObject>();
private float _talkPauseTime = 15.0f; private bool _isDead = false;
/// <summary>
/// indicates wether the Dev is dead or not
/// </summary>
public bool IsDead => _isDead;
[SerializeField]
private int _maxPrivateContextBufferSize = 2;
[SerializeField]
private CircularBuffer<string> _privateContextBuffer;
/// <summary>
/// Returns the private Context Buffer
/// </summary>
public CircularBuffer<string> PrivateContextBuffer => _privateContextBuffer;
// stuff for talking
[SerializeField, ShowOnly] [SerializeField, ShowOnly]
private float _talkTimer; private float _talkTimer;
private AudioSource _audioSource;
private float _talkPauseTime = 15.0f;
private bool _hasTalkedWhileHyperactive = false; private bool _hasTalkedWhileHyperactive = false;
private bool _hasTalkedWhileOvercaffeinated = false; private bool _hasTalkedWhileOvercaffeinated = false;
private bool _hasTalkedBeforeSleeping = false;
private List<GameObject> _needList = new List<GameObject>();
void Start() void Start()
{ {
_developerNeeds = gameObject.GetComponent<DeveloperNeeds>(); _developerNeeds = gameObject.GetComponent<DeveloperNeeds>();
_audioSource = GetComponent<AudioSource>(); _audioSource = GetComponent<AudioSource>();
_talkTimer = UnityEngine.Random.Range(5.0f, 15.0f); _talkTimer = Random.Range(5.0f, 15.0f);
_fingersLeft = _baseStats.Fingers; _fingersLeft = _baseStats.Fingers;
_privateContextBuffer = new CircularBuffer<string>(_maxPrivateContextBufferSize);
} }
private void Update() private void Update()
@ -141,6 +164,12 @@ public class Developer : MonoBehaviour
} }
} }
[ContextMenu("Hurt him")]
private void TestHurt()
{
Hurt();
}
[ContextMenu("Give Coffee")] [ContextMenu("Give Coffee")]
private void TestCoffee() private void TestCoffee()
{ {
@ -186,12 +215,14 @@ public class Developer : MonoBehaviour
// TODO: Wie wäre es damit, das nicht fest zu coden? // TODO: Wie wäre es damit, das nicht fest zu coden?
if (drinkType == _wantedDrink) if (drinkType == _wantedDrink)
{ {
Talk($"The Devolper thanks Gottfried for the {drinkType.GetAsString()}"); Talk($"The Developer thanks Gottfried for the {drinkType.GetAsString()}", 1);
_privateContextBuffer.Add($"The Developer is greatful for the {drinkType.GetAsString()} Gottfried brought him a while ago");
_happiness += 0.2; _happiness += 0.2;
} }
else else
{ {
Talk($"The Devolper blames Gottfried for bringing {drinkType.GetAsString()} but he actaully wanted a {_wantedDrink.GetAsString()}"); Talk($"The Developer is happy about the caffeine but he blames Gottfried for bringing {drinkType.GetAsString()} because he actaully wanted a {_wantedDrink.GetAsString()} instead", 0, true);
_privateContextBuffer.Add($"The Developer is still annoyed and reminds Gottfried that he brought him {drinkType.GetAsString()} instead of {_wantedDrink.GetAsString()} a while ago");
_happiness -= 0.2; _happiness -= 0.2;
} }
} }
@ -217,7 +248,8 @@ public class Developer : MonoBehaviour
_needList.Remove(_hungerNeed); _needList.Remove(_hungerNeed);
NeedFullfilled(_hungerNeed); NeedFullfilled(_hungerNeed);
_hungerNeed = null; _hungerNeed = null;
Talk("The Developer thanks Gottfried for the Pizza"); Talk("The Developer thanks Gottfried for the Pizza", 1);
_privateContextBuffer.Add($"The Developer is greatful for the Pizza Gottfried brought him a while ago");
} }
if (_wantedFood != WantedConsumable.None) if (_wantedFood != WantedConsumable.None)
@ -250,7 +282,8 @@ public class Developer : MonoBehaviour
_needList.Remove(_toiletNeed); _needList.Remove(_toiletNeed);
NeedFullfilled(_toiletNeed); NeedFullfilled(_toiletNeed);
_toiletNeed = null; _toiletNeed = null;
Talk("The Developer finally can go to the toilet"); Talk("The Developer finally can go to the toilet", 1);
_privateContextBuffer.Add($"The developer is grateful that he went to the toilet a while ago");
} }
if (onToilet) if (onToilet)
@ -312,6 +345,8 @@ public class Developer : MonoBehaviour
if (_hungerLevel <= 0.0) if (_hungerLevel <= 0.0)
{ {
if (!_isDead)
Talk($"The developer is starving, The developer is dying, The developer blames Gottfried for letting him starve with his last words", 0, true);
Die(); Die();
} }
} }
@ -351,18 +386,32 @@ public class Developer : MonoBehaviour
private double CalculateCaffeineEfficiency() private double CalculateCaffeineEfficiency()
{ {
if (_isSleeping) if (_isSleeping)
{
if (!_hasTalkedBeforeSleeping)
{
Talk("The Developer is very sleepy right now duo to a lack of caffeine, The Developer takes a nap now", 0, true);
_privateContextBuffer.Add($"The developer took a refreshing nap but is annoyed that Gottfried forgot to bring him any caffeine before the nap");
_hasTalkedBeforeSleeping = true;
}
return 0.0; return 0.0;
}
else
{
_hasTalkedBeforeSleeping = false;
}
if (_isHyperactive) if (_isHyperactive)
{ {
if (!_hasTalkedWhileHyperactive) if (!_hasTalkedWhileHyperactive)
{ {
Talk("The Developer is surprisingly productive right now duo to caffeine"); GetComponent<Text2Speech>().speakingSpeed = 1.4f;
Talk("The Developer is surprisingly productive right now and feels an energyboost duo to caffeine", 0, true);
_hasTalkedWhileHyperactive = true; _hasTalkedWhileHyperactive = true;
} }
} }
else else
{ {
GetComponent<Text2Speech>().speakingSpeed = 1.1f;
_hasTalkedWhileHyperactive = false; _hasTalkedWhileHyperactive = false;
} }
@ -370,7 +419,8 @@ public class Developer : MonoBehaviour
{ {
if (!_hasTalkedWhileOvercaffeinated) if (!_hasTalkedWhileOvercaffeinated)
{ {
Talk("The Developer drank too much caffeine, The Developer needs a break immediately"); Talk("The Developer had too much caffeine, The Developer needs a break immediately", 0, true);
_privateContextBuffer.Add($"The developer overcaffeinated a while ago because Gottfried gave him too much caffeine");
_hasTalkedWhileOvercaffeinated = true; _hasTalkedWhileOvercaffeinated = true;
} }
return 0.0; return 0.0;
@ -417,11 +467,27 @@ public class Developer : MonoBehaviour
// Ob er stirbt oder nicht, für uns hat er auf jeden Fall seinen Nutzen verloren. // Ob er stirbt oder nicht, für uns hat er auf jeden Fall seinen Nutzen verloren.
if (_fingersLeft == 0) if (_fingersLeft == 0)
{
if (!_isDead)
Talk($"The developer lost all his fingers duo to an attack by a monster, The developer is dying, The developer gives a short speech with his last words, The developer blames Gottfried for his death", 0, true);
Die(); Die();
}
else
{
if (_fingersLeft == 9)
Talk($"The developer lost a finger duo to an attack by a monster, The developer has {_fingersLeft} left, The developer is in pain, The developer is irrevocably less productive now, The developer blames Gottfried for this", 0, true);
else
Talk($"The developer lost another finger duo to an attack by a monster, The developer has only {_fingersLeft} left, The developer is in pain, The developer is irrevocably less productive now, The developer blames Gottfried for this", 0, true);
if (Random.Range(0, 3) < 2)
_privateContextBuffer.Add($"The developer cries for his {10 - _fingersLeft} lost fingers");
else
_privateContextBuffer.Add($"The developer is greatful he still has {_fingersLeft} fingers even tho he had 10 once");
}
} }
private void Die() private void Die()
{ {
_isDead = true;
Debug.Log($"{Name} ist verreckt."); Debug.Log($"{Name} ist verreckt.");
} }
@ -431,29 +497,50 @@ public class Developer : MonoBehaviour
return distanceToPlayer <= _talkRange; return distanceToPlayer <= _talkRange;
} }
/// <summary>
/// Returns the context stored in the contextBuffer seperated with ',' as a string
/// </summary>
/// <returns></returns>
public string GetPrivateContextAsString()
{
if (_privateContextBuffer.Count != 0)
{
string output = "";
foreach (string context in _privateContextBuffer)
{
output += context + ", ";
}
return output;
}
return string.Empty;
}
/// <summary> /// <summary>
/// Starts talking when player is near to the Dev. /// Starts talking when player is near to the Dev.
/// </summary> /// </summary>
public void TalkIfInRange() public void TalkIfInRange()
{ {
if (IsGottfriedInRange()) if (IsGottfriedInRange() && !_isDead && !_isSleeping)
{ {
Talk(); string context = GetPrivateContextAsString();
context += GameManager.Instance.GetContextAsString();
Talk(context);
} }
} }
/// <summary> /// <summary>
/// Dev starts talking. /// Dev starts talking.
/// </summary> /// </summary>
public void Talk(string context = null) public void Talk(string context, int shortnessLevel = 0, bool priority = false)
{ {
if (context == null) if (priority)
{ {
context = GameManager.Instance.GetContextAsString(); _audioSource.Stop();
_audioSource.clip = null;
} }
if (!_audioSource.isPlaying) if (!_audioSource.isPlaying)
{ {
GetComponent<Text2Speech>().Generate(context); GetComponent<Text2Speech>().Generate(context, shortnessLevel);
} }
} }
} }

View File

@ -41,11 +41,11 @@ public class DeveloperNeeds : MonoBehaviour
{ {
case "coffee": case "coffee":
spawnedNeed = Instantiate(Needs[0], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation); spawnedNeed = Instantiate(Needs[0], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation);
context = "The Developer wants coffee"; context = "The Developer wants Gottfried to bring him a coffee";
break; break;
case "mate": case "mate":
spawnedNeed = Instantiate(Needs[1], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation); spawnedNeed = Instantiate(Needs[1], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation);
context = "The Developer wants a Blub Mate (Yes, its a drink called Blub Mate)"; context = "The Developer wants Gottfried to bring him a Blub Mate (Yes, its a drink called Blub Mate)";
break; break;
case "toilet": case "toilet":
spawnedNeed = Instantiate(Needs[2], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation); spawnedNeed = Instantiate(Needs[2], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation);
@ -53,7 +53,11 @@ public class DeveloperNeeds : MonoBehaviour
break; break;
case "hunger": case "hunger":
spawnedNeed = Instantiate(Needs[3], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation); spawnedNeed = Instantiate(Needs[3], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation);
context = "The Developer wants a pizza"; context = "The Developer wants Gottfried to bring him a pizza";
break;
case "money":
spawnedNeed = Instantiate(Needs[3], new Vector3(0.0f, 2f + (numNeeds * 0.5f), 0.0f), Needs[0].transform.rotation);
context = "The Developer wants a raise, The Developer needs more money";
break; break;
default: default:
Debug.LogError($"Unbekannter need \"{needName}\""); Debug.LogError($"Unbekannter need \"{needName}\"");
@ -66,7 +70,7 @@ public class DeveloperNeeds : MonoBehaviour
spawnedNeed.transform.localScale = new Vector3(0.4f, 0.01f, 0.4f); spawnedNeed.transform.localScale = new Vector3(0.4f, 0.01f, 0.4f);
if (!_audioSource.isPlaying) if (!_audioSource.isPlaying)
{ {
_text2speech.Generate(context); _text2speech.Generate(context, 1);
} }
return spawnedNeed; return spawnedNeed;
} }

View File

@ -41,7 +41,7 @@ public partial class GameManager : MonoBehaviourSingleton<GameManager>
private DifficultySettings _difficultySettings; private DifficultySettings _difficultySettings;
[SerializeField] [SerializeField]
private int _maxContextBufferSize = 5; private int _maxContextBufferSize = 3;
[SerializeField] [SerializeField]
private CircularBuffer<string> _contextBuffer; private CircularBuffer<string> _contextBuffer;
@ -91,6 +91,8 @@ public partial class GameManager : MonoBehaviourSingleton<GameManager>
TimeManager.Instance.Init(); TimeManager.Instance.Init();
_contextBuffer = new CircularBuffer<string>(_maxContextBufferSize); _contextBuffer = new CircularBuffer<string>(_maxContextBufferSize);
_contextBuffer.Add("The Developer is greatful to work at this office with Gottfried");
_contextBuffer.Add("The Developer excited to develope the new game");
_difficultySettings = _difficulty.GetSettings(); _difficultySettings = _difficulty.GetSettings();
@ -205,7 +207,7 @@ public partial class GameManager : MonoBehaviourSingleton<GameManager>
} }
return output; return output;
} }
return null; return string.Empty;
} }
/// <summary> /// <summary>
@ -216,4 +218,22 @@ public partial class GameManager : MonoBehaviourSingleton<GameManager>
{ {
_contextBuffer.Add(context); _contextBuffer.Add(context);
} }
/// <summary>
/// Removes the given string from the context
/// </summary>
/// <param name="context"></param>
public void RemoveContext(string context)
{
if ( _contextBuffer.Contains(context) )
{
List<string> contextAsList = _contextBuffer.ToArray().ToList();
_contextBuffer.Clear();
contextAsList.Remove(context);
foreach (var c in contextAsList)
{
_contextBuffer.Add(c);
}
}
}
} }

View File

@ -12,6 +12,7 @@ using System.Threading.Tasks;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using Google.Cloud.TextToSpeech.V1; using Google.Cloud.TextToSpeech.V1;
using Palmmedia.ReportGenerator.Core;
[Serializable] [Serializable]
public class TextToSpeechResponse public class TextToSpeechResponse
@ -35,7 +36,7 @@ public class Text2Speech : MonoBehaviour
[SerializeField] [SerializeField]
public bool generate = false; public bool generate = false;
[SerializeField] [SerializeField]
public bool newVoiceAndGenerate = false; public bool newVoice = false;
[SerializeField] [SerializeField]
public string Voice; public string Voice;
@ -49,8 +50,10 @@ public class Text2Speech : MonoBehaviour
private OpenAIAPI _openAiApi; private OpenAIAPI _openAiApi;
private Conversation? _conversation; private Conversation? _conversation;
private readonly string _openAiApiKey = "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"; private readonly string _openAiApiKey = "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";
private readonly string _prompt = "Write a short text for a Developer as an NPC in a game. The Developer works at a small gamedevelopement office and its manager is called Gottfried who is responsable for all the Developers needs. The text should be based on the following bullet-point context, which describes the events of the last moments. Remember to only respond with the short text that only this ONE Developer should speak and nothing else! The context is: "; private readonly string _defaultPrompt = "Write a short text for a Developer as an NPC in a game. The Developer works at a small gamedevelopement office and its manager is called Gottfried who is responsable for all the Developers needs and protection. The text should be based on the following bullet-point context, which describes the events of the last moments. Remember to only respond with the short text that only this ONE Developer should speak and nothing else! The context is: ";
private readonly string _shortPrompt = "Write a relatively short text for a Developer as an NPC in a game. The Developer works at a small gamedevelopement office and its manager is called Gottfried who is responsable for all the Developers needs and protection. The text should be based on the following bullet-point context, which describes the events of the last moments. Remember to only respond with the relatively short text that only this ONE Developer should speak and nothing else! The context is: ";
private readonly string _veryShortPrompt = "Write a very short text for a Developer as an NPC in a game. The Developer works at a small gamedevelopement office and its manager is called Gottfried who is responsable for all the Developers needs and protection. The text should be based on the following bullet-point context, which describes the events of the last moments. Remember to only respond with the very short text that only this ONE Developer should speak and nothing else! The context is: ";
private int _shortnessLevel = 0;
void Start() void Start()
{ {
_tmpPath = "tmp_audio_" + GetInstanceID().ToString() + ".wav"; _tmpPath = "tmp_audio_" + GetInstanceID().ToString() + ".wav";
@ -69,9 +72,9 @@ public class Text2Speech : MonoBehaviour
generate = false; generate = false;
if (voice == null) if (voice == null)
{ {
GetRandomGermanVoice(gender, (v) => { GetRandomEnglishVoice(gender, (v) => {
voice = v; voice = v;
Voice = voice.ToString(); Voice = voice.ToString();
//Debug.Log($"GoogleCloud: Choosen voice is\n{voice}"); //Debug.Log($"GoogleCloud: Choosen voice is\n{voice}");
StartCoroutine(GenerateAndSynthesizeText(context)); StartCoroutine(GenerateAndSynthesizeText(context));
}); });
@ -81,27 +84,27 @@ public class Text2Speech : MonoBehaviour
StartCoroutine(GenerateAndSynthesizeText(context)); StartCoroutine(GenerateAndSynthesizeText(context));
} }
} }
if (newVoiceAndGenerate) if (newVoice)
{ {
newVoiceAndGenerate = false; newVoice = false;
voice = null; voice = null;
Voice = null; Voice = null;
generate = true;
} }
} }
public void Generate(string c) public void Generate(string c, int shortnessLevel = 0)
{ {
context = c; context = c;
_shortnessLevel = shortnessLevel;
generate = true; generate = true;
} }
public void GetRandomGermanVoice(string gender, Action<JToken> callback) public void GetRandomEnglishVoice(string gender, Action<JToken> callback)
{ {
StartCoroutine(GetRandomGermanVoiceCoroutine(gender, callback)); StartCoroutine(GetRandomEnglishVoiceCoroutine(gender, callback));
} }
private IEnumerator GetRandomGermanVoiceCoroutine(string gender, Action<JToken> callback) private IEnumerator GetRandomEnglishVoiceCoroutine(string gender, Action<JToken> callback)
{ {
string url = $"https://texttospeech.googleapis.com/v1beta1/voices?key={_googelCloudApiKey}"; string url = $"https://texttospeech.googleapis.com/v1beta1/voices?key={_googelCloudApiKey}";
@ -191,7 +194,19 @@ public class Text2Speech : MonoBehaviour
}; };
_conversation = _openAiApi.Chat.CreateConversation(chatRequest); _conversation = _openAiApi.Chat.CreateConversation(chatRequest);
_conversation.AppendUserInput(_prompt + context);
string prompt = _defaultPrompt;
switch (_shortnessLevel)
{
case 1:
prompt = _shortPrompt; break;
case 2:
prompt = _veryShortPrompt; break;
default:
break;
}
_conversation.AppendUserInput(prompt + context);
string response = await _conversation.GetResponseFromChatbotAsync(); string response = await _conversation.GetResponseFromChatbotAsync();
//Debug.Log($"ChatGPT: {response}"); //Debug.Log($"ChatGPT: {response}");
return response; return response;

View File

@ -40,6 +40,11 @@ public class TimeManager : MonoBehaviourSingleton<TimeManager>
/// </summary> /// </summary>
public DateTime Deadline => _deadline; public DateTime Deadline => _deadline;
/// <summary>
/// Wie viele Sekunden ein Tag im Spiel hat
/// </summary>
public double SecondsPerDay => _secondsPerDay;
/// <summary> /// <summary>
/// Gibt true zurück, wenn die Deadline verpasst wurde. /// Gibt true zurück, wenn die Deadline verpasst wurde.
/// </summary> /// </summary>

View File

@ -8,3 +8,32 @@
"pitch": -2 "pitch": -2
} }
{
"languageCodes": [
"en-US"
],
"name": "en-US-Studio-Q",
"ssmlGender": "MALE",
"naturalSampleRateHertz": 24000,
"pitch": 1
}
{
"languageCodes": [
"en-AU"
],
"name": "en-AU-Wavenet-D",
"ssmlGender": "MALE",
"naturalSampleRateHertz": 24000,
"pitch": 6
}
{
"languageCodes": [
"en-AU"
],
"name": "en-AU-Neural2-D",
"ssmlGender": "MALE",
"naturalSampleRateHertz": 24000,
"pitch": 2
}

View File

@ -11,7 +11,15 @@ public class Zeitschaltuhr : MonoBehaviour, ISerializationCallbackReceiver
{ {
private TimeSpan _turnOnTimeSpan; private TimeSpan _turnOnTimeSpan;
private TimeSpan _turnOffTimeSpan; private TimeSpan _turnOffTimeSpan;
private float _activeTimeSpanInSeconds;
/// <summary>
/// Die Dauer der Active-Time der Kinder in echten Sekunden
/// </summary>
public float ActiveTimeSpanInSeconds => _activeTimeSpanInSeconds;
/// <summary>
/// Ob die Kinder gerade aktiv sind oder nicht
/// </summary>
public bool IsOn; public bool IsOn;
[SerializeField] private SimpleTime _turnOnTime; [SerializeField] private SimpleTime _turnOnTime;
@ -39,6 +47,7 @@ public class Zeitschaltuhr : MonoBehaviour, ISerializationCallbackReceiver
void Start() void Start()
{ {
CalculateOnTimeInSeconds();
UpdateOn(); UpdateOn();
} }
@ -94,4 +103,23 @@ public class Zeitschaltuhr : MonoBehaviour, ISerializationCallbackReceiver
_turnOnTimeSpan = _turnOnTime.ToTimeSpan(); _turnOnTimeSpan = _turnOnTime.ToTimeSpan();
_turnOffTimeSpan = _turnOffTime.ToTimeSpan(); _turnOffTimeSpan = _turnOffTime.ToTimeSpan();
} }
private void CalculateOnTimeInSeconds()
{
TimeSpan turnOnTimeSpan = _turnOnTime.ToTimeSpan();
TimeSpan turnOffTimeSpan = _turnOffTime.ToTimeSpan();
float onDurationInSeconds;
if (turnOnTimeSpan < turnOffTimeSpan)
{
onDurationInSeconds = (float)(turnOffTimeSpan - turnOnTimeSpan).TotalSeconds;
}
else
{
TimeSpan fullDay = TimeSpan.FromHours(24);
onDurationInSeconds = (float)((fullDay - turnOnTimeSpan) + turnOffTimeSpan).TotalSeconds;
}
_activeTimeSpanInSeconds = onDurationInSeconds * ((float)TimeManager.Instance.SecondsPerDay / 86400f); // 86400 Sekunden pro Tag
}
} }

View File

@ -8,14 +8,17 @@ public class ZombieSpawner : MonoBehaviour
[SerializeField] [SerializeField]
GameObject ZombiePrefab; GameObject ZombiePrefab;
[SerializeField] [SerializeField]
private float _spawnRate = 1.0f; private float _spawnRate = 2.0f;
[SerializeField, ShowOnly] [SerializeField, ShowOnly]
private float _spawnTimer; private float _spawnTimer;
private float _secondsPerAliveTime;
// Start wird aufgerufen, bevor das erste Frame gezeichnet wird // Start wird aufgerufen, bevor das erste Frame gezeichnet wird
void Start() void Start()
{ {
_spawnTimer = 60 / _spawnRate; _secondsPerAliveTime = GetComponentInParent<Zeitschaltuhr>().ActiveTimeSpanInSeconds;
_spawnTimer = Random.Range(0.5f * _secondsPerAliveTime / _spawnRate, _secondsPerAliveTime / _spawnRate);
} }
// Update wird einmal pro Frame aufgerufen // Update wird einmal pro Frame aufgerufen
@ -25,8 +28,33 @@ public class ZombieSpawner : MonoBehaviour
if (_spawnTimer <= 0) if (_spawnTimer <= 0)
{ {
Instantiate(ZombiePrefab, transform.position, Quaternion.identity); Instantiate(ZombiePrefab, transform.position, Quaternion.identity, transform);
_spawnTimer = 60 / _spawnRate; _spawnTimer = _secondsPerAliveTime / _spawnRate;
} }
} }
private void OnEnable()
{
if (GameManager.Instance != null)
{
if (GameManager.Instance.ContextBuffer != null)
GameManager.Instance.AddContext("The Developer informs Gottfried that Zombies appeared outside so Gottfried better not leave the office");
}
}
private void OnDisable()
{
if (GameManager.Instance.ContextBuffer != null)
GameManager.Instance.RemoveContext("The Developer informs Gottfried that Zombies appeared outside so Gottfried better not leave the office");
// Destroy all children (zombies)
for (int i = 0; i < transform.childCount; i++)
{
KillZombiesByDisable();
}
}
private void KillZombiesByDisable()
{
Destroy(transform.GetChild(i).gameObject);
}
} }