added some stuff

This commit is contained in:
Wong Sui Bin 2023-01-24 21:51:46 +08:00
parent 9b69003715
commit 3dbf2f9010
520 changed files with 176780 additions and 2 deletions

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c6a08cabe03c2464a93d39c1ce56b251
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,530 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//plans for the future:
//create a dictionary driven option
//make it compatible with enums
//use pooling audio channels instead when developing version2.0
//namespace Lemon.GenericLib.Audio {
public class AudioManager2D : MonoBehaviour
{
public static AudioManager2D Instance;
//there are 4 seperate audio streams here, make sure they are assigned
[Header("audio sources")]
[SerializeField] private AudioSource soundAudioSrc;
[SerializeField] private AudioSource bgmAudioSource;
[SerializeField] private AudioSource uiAudioSource;
[SerializeField] private AudioSource ambientAudioSource;
[SerializeField] float masterVolume = 1;
[SerializeField] bool changeOtherSources = false;
[SerializeField] bool playOnStart = false;
[SerializeField] string startingAudio = "";
[SerializeField] AudioSource[] extraAudioThreads; //best for sound effects
[Header("extra effects config")]
[SerializeField] float fadeAudioEffectSpeed = 1;
[Header("audio to play")]
[SerializeField] Audio[] audioArray;
//the index for the audio array to track what is playing
//-1 means nothing is playing in that
private int currentSoundIndex = -1;
private int currentBGMIndex = -1;
private int currentUISoundIndex = -1;
private int currentAmbientIndex = -1;
//singleton pattern
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
if (Instance != this)
{
Destroy(gameObject);
}
}
private void Start()
{
if (playOnStart)
{
Play(startingAudio);
}
}
//does not support extra threads
//called when changed volume
public void SetVolume(float vol)
{
this.masterVolume = vol / 100;
UpdateAudioSrcVolume(currentSoundIndex, Audio.AudioType.Sound);
UpdateAudioSrcVolume(currentBGMIndex, Audio.AudioType.BGM);
UpdateAudioSrcVolume(currentUISoundIndex, Audio.AudioType.UISounds);
UpdateAudioSrcVolume(currentAmbientIndex, Audio.AudioType.Ambient);
//this also needs to change audio in audio sources outside
//not the best method
if (!changeOtherSources) return;
var audioSrcList = FindObjectsOfType<AudioSource>();
foreach (var audioSrc in audioSrcList)
{
if (audioSrc != soundAudioSrc && audioSrc != bgmAudioSource && audioSrc != uiAudioSource && audioSrc != ambientAudioSource)
audioSrc.volume = masterVolume;
}
}
//does not support extra threads
private void UpdateAudioSrcVolume(int audioIndex = 0, Audio.AudioType type = Audio.AudioType.BGM)
{
if (audioIndex >= 0)
{
switch (audioArray[audioIndex].audioType)
{
case Audio.AudioType.Sound:
audioArray[audioIndex].updateVolume(soundAudioSrc, this.masterVolume);
break;
case Audio.AudioType.BGM:
audioArray[audioIndex].updateVolume(bgmAudioSource, this.masterVolume);
break;
case Audio.AudioType.UISounds:
audioArray[audioIndex].updateVolume(uiAudioSource, this.masterVolume);
break;
case Audio.AudioType.Ambient:
audioArray[audioIndex].updateVolume(ambientAudioSource, this.masterVolume);
break;
default:
Debug.LogError($"the audio clip {audioArray[audioIndex].audioName} does not have a audio type assigned \n or there is no update volume option for that type yet");
break;
}
}
else
{
switch (type)
{
case Audio.AudioType.Sound:
soundAudioSrc.volume = masterVolume;
break;
case Audio.AudioType.BGM:
bgmAudioSource.volume = masterVolume;
break;
case Audio.AudioType.UISounds:
uiAudioSource.volume = masterVolume;
break;
case Audio.AudioType.Ambient:
ambientAudioSource.volume = masterVolume;
break;
default:
Debug.LogError($"the audio clip {audioArray[audioIndex].audioName} does not have a audio type assigned \n or there is no update volume option for that type yet");
break;
}
}
}
//force all audio to stop
public void StopAllAudio()
{
//this is the solution to manage fading for now
StopCoroutine("FadeAudioEffect");
soundAudioSrc.Stop();
bgmAudioSource.Stop();
uiAudioSource.Stop();
ambientAudioSource.Stop();
foreach (var audioSrc in extraAudioThreads)
{
audioSrc.Stop();
}
}
public void StopSound()
{
soundAudioSrc.Stop();
}
public void StopBGM()
{
bgmAudioSource.Stop();
}
public void StopUISound()
{
uiAudioSource.Stop();
}
public void StopAmbient()
{
ambientAudioSource.Stop();
}
public void StopExtra()
{
foreach (var audioSrc in extraAudioThreads)
{
audioSrc.Stop();
}
}
public void Stop(int audioTypeIndex)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
soundAudioSrc.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
bgmAudioSource.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
uiAudioSource.Stop();
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
ambientAudioSource.Stop();
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
public void SetFadeEffectSpeed(float newEffectSpeed)
{
fadeAudioEffectSpeed = newEffectSpeed;
}
//does not support extra threads
public void PlayFade(string audioName)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
Debug.LogError($"the audio clip {audioName} cannot be found\n please check that your spelling is correct");
}
//does not support extra threads
public void PlayFade(string audioName, float fadeAudioEffectSpeed)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, audioArray[i].defaultVolume * masterVolume));
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
Debug.LogError($"the audio clip {audioName} cannot be found\n please check that your spelling is correct");
}
//does not support extra threads
//0 = sound, 1 is BGM, 2 is UI, 3 is ambient
public void StopFade(int audioTypeIndex)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, soundAudioSrc.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, bgmAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, uiAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, ambientAudioSource.volume, false));
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
//does not support extra threads
public void StopFade(int audioTypeIndex, float fadeAudioEffectSpeed)
{
if (audioTypeIndex == (int)Audio.AudioType.Sound)
{
StartCoroutine(FadeAudioEffect(soundAudioSrc, fadeAudioEffectSpeed, soundAudioSrc.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.BGM)
{
StartCoroutine(FadeAudioEffect(bgmAudioSource, fadeAudioEffectSpeed, bgmAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.UISounds)
{
StartCoroutine(FadeAudioEffect(uiAudioSource, fadeAudioEffectSpeed, uiAudioSource.volume, false));
}
else if (audioTypeIndex == (int)Audio.AudioType.Ambient)
{
StartCoroutine(FadeAudioEffect(ambientAudioSource, fadeAudioEffectSpeed, ambientAudioSource.volume, false));
}
else
{
Debug.LogError($"the audio index {audioTypeIndex} cis not a valid audio type\nPlease use 1 - 4 ");
}
}
IEnumerator FadeAudioEffect(AudioSource audioSource, float effectSpeed, float MaxVolume, bool increment = true)
{
float currentVolume = 0;
if (increment)
{
currentVolume = 0;
while (currentVolume < MaxVolume)
{
audioSource.volume = currentVolume;
currentVolume += Time.deltaTime * 0.01f * effectSpeed;
yield return null;
}
}
else
{
Debug.Log("fading");
currentVolume = MaxVolume;
while (currentVolume > 0)
{
audioSource.volume = currentVolume;
currentVolume -= Time.deltaTime * 0.01f * effectSpeed;
yield return null;
}
}
}
//use audio name to play audio, I know it is a string but what choice we have, maybe change to scriptable object when we have time
public void Play(string audioName)
{
for (int i = 0; i < audioArray.Length; i++)
{
//Debug.Log(audioName + " " + audioArray[i].audioName);
if (audioArray[i].audioName.ToUpper() == audioName.ToUpper())
{
switch (audioArray[i].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(soundAudioSrc, masterVolume);
currentSoundIndex = i;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(bgmAudioSource, masterVolume);
currentBGMIndex = i;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(uiAudioSource, masterVolume);
currentUISoundIndex = i;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = i;
break;
case Audio.AudioType.Extra:
if (audioArray[i].extraThreadIndex < 0 || audioArray[i].extraThreadIndex >= extraAudioThreads.Length)
{
Debug.LogError($"the audio clip {audioArray[i].audioName} has a invalid extra audio thread index of {audioArray[i].extraThreadIndex}");
}
else
{
StopCoroutine("FadeAudioEffect");
audioArray[i].Play(extraAudioThreads[audioArray[i].extraThreadIndex], masterVolume);
}
break;
default:
Debug.LogError($"the audio clip {audioArray[i].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
return;
}
}
}
public void Play(int index)
{
if (index < 0 || index > audioArray.Length) {
Debug.LogError($"Error: Invalid Audio Index of {index}");
return;
}
switch (audioArray[index].audioType)
{
case Audio.AudioType.Sound:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(soundAudioSrc, masterVolume);
currentSoundIndex = index;
break;
case Audio.AudioType.BGM:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(bgmAudioSource, masterVolume);
currentBGMIndex = index;
break;
case Audio.AudioType.UISounds:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(uiAudioSource, masterVolume);
currentUISoundIndex = index;
break;
case Audio.AudioType.Ambient:
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(ambientAudioSource, masterVolume);
currentAmbientIndex = index;
break;
case Audio.AudioType.Extra:
if (audioArray[index].extraThreadIndex < 0 || audioArray[index].extraThreadIndex >= extraAudioThreads.Length)
{
Debug.LogError($"the audio clip {audioArray[index].audioName} has a invalid extra audio thread index of {audioArray[index].extraThreadIndex}");
}
else
{
StopCoroutine("FadeAudioEffect");
audioArray[index].Play(extraAudioThreads[audioArray[index].extraThreadIndex], masterVolume);
}
break;
default:
Debug.LogError($"the audio clip {audioArray[index].audioName} does not have a audio type assigned \n or there is no play option for that type yet");
break;
}
}
}
//store audio data
[Serializable]
public class Audio
{
public string audioName = "";
public enum AudioType { Sound, BGM, UISounds, Ambient, Extra }
public int extraThreadIndex;
public AudioType audioType = AudioType.Sound;
public AudioClip clip;
public bool loop = false;
public float defaultVolume = 1;
public void Play(AudioSource audioSrc, float volume)
{
audioSrc.clip = clip;
audioSrc.volume = defaultVolume * volume;
audioSrc.loop = loop;
audioSrc.Play();
}
public void updateVolume(AudioSource audioSrc, float volume)
{
Debug.Log("update");
audioSrc.volume = defaultVolume * volume;
}
}
//}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 74d11a8e609d32b4bb6702a8c6852f83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using Lemon.GenericLib.Audio;
public class PlayAudioScript : MonoBehaviour
{
[SerializeField] private string audioName = "";
public void PlayAudio() {
AudioManager2D.Instance.Play(audioName);
}
public void PlayAudio( string audioName)
{
AudioManager2D.Instance.Play(audioName);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7b631eb531e35d048ad89374962e76b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 454ba7a3e1c051a468ce9379c33f09c9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.Utility {
public class DisableOnAwake : MonoBehaviour
{
private void Awake()
{
gameObject.SetActive(false);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dfb25ba3ec4f3b4c9842d81ea238e56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
//future upgrades:
//upgrade this to read specific input without needing to set a unity input
//handle multiple input
//ahndle muliple input variations like left right, get key up, etc.
namespace Lemon.GenericLib.Utility
{
public class InputBasedTestingScript : MonoBehaviour
{
[SerializeField] private string inputKeyName;
public UnityEvent functionsToTest;
// Update is called once per frame
void Update()
{
if (Input.GetButtonDown(inputKeyName))
{
functionsToTest?.Invoke();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69302d519e9f40c4fa9c50e9bb87f438
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,47 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace Lemon.GenericLib.Utility {
public class KeyCodeInputController : MonoBehaviour
{
[Header("controlls list")]
[SerializeField] private KeyCodeControll[] keyCodeControlls;
private void Update()
{
if (Input.anyKeyDown)
{
//CheckInit();
foreach (var controlls in keyCodeControlls)
{
if (Input.GetKeyDown(controlls.KeyCode))
{
controlls.InvokeKeyCodeFunction();
}
}
}
}
[System.Serializable]
private class KeyCodeControll
{
[SerializeField] private KeyCode keyCode;
[SerializeField] private UnityEvent InputFunctions;
public KeyCode KeyCode { get => keyCode; set => keyCode = value; }
public void InvokeKeyCodeFunction()
{
InputFunctions?.Invoke();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 85106e56a76d0094b8198233c973020e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,28 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Lemon.GenericLib.Utility
{
public class RestartAndQuit : MonoBehaviour
{
public bool pressToQuit = false;
public bool pressToRestart = false;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R) && pressToRestart)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
if (Input.GetKeyDown(KeyCode.Escape) && pressToQuit)
{
Application.Quit();
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c58e5fe732daf0144af01eba42dfda38
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 34132cdda7a2a184dbdc84bb76b5224c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,404 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System;
using Lemon.GenericLib.Generics;
//note
//dialouge cannot be started in the start() call because it needs to wait for events
namespace Lemon.GenericLib.Dialogue
{
public class DialogueSystem : MonoBehaviour
{
[Header("dialogue configs")]
[SerializeField] private string[] dialougeTexts;
[SerializeField] private TextMeshProUGUI dialogueTextFeild;
[SerializeField] private static float typingSpeed = 50f;
private static float defaultTypingSpeed;
[SerializeField] Optional<string> interuptInput;
[SerializeField] Optional<string> advancingInput;
[SerializeField] private bool canUseExternalControls = true;
[SerializeField] public Color defaulrColour;
[Space]
[Header("timing configs")]
[SerializeField] private bool startImmediantly;
[SerializeField] public float startDelay;
[SerializeField] public float endDelay;
[Space]
[Header("command parsing configs")]
[SerializeField] private char commandPrefix;
[SerializeField] private bool skipEmpty;
[SerializeField] private char[] ignorePrefix;
[Space]
[Header("extra config ")]
[SerializeField] Optional<GameObject> continueButton;
public int SceneIndex;
public Action<string> dialogueCommandEvents;
public Action dialogueLineEvent;
public Action endDialougeEvents;
public Action dialogueStartEvents;
public Action initDialogueEvents;
public Action requiredEndEvent;
private int currentDialougeIndex = 0;
private bool isInterupt = false;
private bool isTyping = false;
public float waitTime = 0f;
public static bool doneSkipping = false;
//public DialogueLogger dialogueLogger;
// Start is called before the first frame update
IEnumerator Start()
{
dialogueTextFeild.text = "";
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
//dialougeLineEvent += TestEvent;
if (startImmediantly)
{
yield return new WaitForSeconds(0.5f);
StartCoroutine(StartDialogueRoutine());
}
defaultTypingSpeed = typingSpeed;
}
// Update is called once per frame
void Update()
{
if (!canUseExternalControls) return;
HandleInputs();
}
bool isInputInterupt = false;
private void HandleInputs()
{
if (interuptInput.Enabled && isTyping)
{
if (Input.GetButtonDown(interuptInput.Value))
{
//AudioManager2D.audioManager2DInstance.Play("UIClick");
if (!isInterupt)
{
isInterupt = true;
}
return;
}
}
if (advancingInput.Enabled)
{
if (Input.GetButtonDown(advancingInput.Value))
{
//AudioManager2D.audioManager2DInstance.Play("UIClick");
if (!isTyping)
{
//Debug.Log(isTyping);
AdvanceDialogue();
}
//else if (!isInterupt){
// isInputInterupt = true;
// isInterupt = true;
// StartCoroutine(resetInterupt());
//}
return;
}
}
}
public void LoadDialouge(string[] dialoguesToLoad, bool startImmediantly = true)
{
dialougeTexts = dialoguesToLoad;
dialogueStartEvents = null;
//endDialougeEvents = null;
if (startImmediantly)
{
StartDialogue();
}
}
public void StartDialogue()
{
if (dialougeTexts == null) return;
//AudioManager2D.audioManager2DInstance.Play("PageFlipSound");
StartCoroutine(StartDialogueRoutine());
}
IEnumerator StartDialogueRoutine()
{
initDialogueEvents?.Invoke();
dialogueTextFeild.color = defaulrColour;
yield return new WaitForSeconds(startDelay);
dialogueStartEvents?.Invoke();
currentDialougeIndex = 0;
TypeDialouge();
}
public void AdvanceDialogue()
{
//AudioManager2D.audioManager2DInstance.Play("ButtonSound");
if (!canUseExternalControls) return;
StopCoroutine("TypeDialougeRoutine");
if (dialougeTexts == null) return;
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
currentDialougeIndex++;
Debug.LogWarning(currentDialougeIndex + ", " + dialougeTexts.Length);
if (currentDialougeIndex < dialougeTexts.Length)
{
TypeDialouge(dialougeTexts[currentDialougeIndex]);
}
else
{
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
StartCoroutine(EndDialogueRoutine());
}
}
public void SkipDialogue()
{
//isInterupt = true;
//currentDialougeIndex = dialougeTexts.Length;
//currentDialougeIndex++;
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
AdvanceDialogue();
}
IEnumerator EndDialogueRoutine()
{
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
requiredEndEvent?.Invoke();
dialogueTextFeild.text = "";
yield return new WaitForSeconds(endDelay);
//fire events
//endDialougeEvents?.Invoke();
//FindObjectOfType<SceneTransition>().GoToScene(SceneIndex);
}
public void SkipDialougeTyping()
{
StopCoroutine("TypeDialougeRoutine");
dialogueTextFeild.text = "";
AdvanceDialogue();
}
public void TypeDialouge()
{
StopCoroutine("typeDialougeRoutine");
StartCoroutine(TypeDialougeRoutine(dialougeTexts[currentDialougeIndex]));
}
public void TypeDialouge(string dialougeToType)
{
StopCoroutine("typeDialougeRoutine");
StartCoroutine(TypeDialougeRoutine(dialougeToType));
}
public void InteruptDialouge()
{
isInterupt = true;
}
public void SetStartEvents(Action[] events)
{
dialogueStartEvents = null;
foreach (var item in events)
{
dialogueStartEvents += item;
}
}
public void SetEndEvents(Action[] events)
{
endDialougeEvents = null;
foreach (var item in events)
{
endDialougeEvents += item;
}
}
//create a wait time vaiable that is public
IEnumerator TypeDialougeRoutine(string dialougeToType)
{
float t = 0;
int charIndex = 0;
isInterupt = false;
isTyping = true;
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
Debug.Log(dialougeToType);
if (skipEmpty && (string.IsNullOrWhiteSpace(dialougeToType)))
{
SkipDialougeTyping();
}
else
{
dialogueCommandEvents?.Invoke(dialougeToType);
//make sure you can change wait time here woth the command fucntion
bool isSkipPrefix = false;
for (int i = 0; i < ignorePrefix.Length; i++)
{
if (dialougeToType[0].Equals(ignorePrefix[i]))
{
isSkipPrefix = true;
}
}
//Honestly have no idea where to put the wait so
if (waitTime > 0)
{
yield return new WaitForSeconds(waitTime);
}
waitTime = 0;
Debug.Log($"shoud skip?: { dialougeToType[0] } {isSkipPrefix} ");
doneSkipping = false;
if (dialougeToType[0].Equals(commandPrefix) || isSkipPrefix)
{
//wait even if wait time is 0
//reset wait time after wait
SkipDialougeTyping();
}
else
{
//dialougeToType = dialougeTextEffects.UpdateText(dialougeToType);
dialogueTextFeild.text = dialougeToType;
//dialougeTextEffects.UpdateText(dialougeToType);
//typing effect
while (charIndex < dialougeToType.Length)
{
isTyping = true;
//for whatever reason this needs to be in the loop to not show
if (continueButton.Enabled)
{
continueButton.Value.SetActive(false);
}
if (isInterupt)
{
charIndex = dialougeToType.Length;
}
else
{
t += Time.deltaTime * typingSpeed;
charIndex = Mathf.FloorToInt(t);
charIndex = Mathf.Clamp(charIndex, 0, dialougeToType.Length);
}
//process here
dialogueTextFeild.maxVisibleCharacters = charIndex;
//dialogueTextFeild.text = dialougeToType.Substring(0, charIndex);
yield return null;
}
doneSkipping = true;
//dialogueLogger.AddToLog(dialougeToType, false, false);
//dialogueTextFeild.text = dialougeToType;
}
}
isTyping = false;
//Fixes for continue button appearing when holding down skip
if (continueButton.Enabled)
{
if (doneSkipping == false)
{
continueButton.Value.SetActive(false);
}
else
{
continueButton.Value.SetActive(true);
}
}
}
IEnumerator resetInterupt()
{
yield return null;
isInputInterupt = false;
}
public void TestEvent(string testString)
{
Debug.Log(testString);
Debug.Log("Event is working as intended");
}
public static void setTypingSpeed(int newValue)
{
typingSpeed = newValue;
}
public static void setDefaultTypingSpeed()
{
typingSpeed = defaultTypingSpeed;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 98352efe069658d4caae5443f470f550
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1501d425c1bfa664ba75c3d7d4236d87
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7a233e2e3bb5afd40b770f197760dbc4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,454 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using System;
using UnityEngine.UI;
using TMPro;
//things to do (for the authur only):
//check if this class is very reusable
//implement a proper way to destroy grids
//add more debug features and controls
//test this in 3D (using x and z axis)
//remove all mentions of real names in this class and replace them with screen names
//this is Wong Sui Bin's grid class, I advise not to touch this if you are not the authur of this class
//this is a class that greats a 2D grid in the game world that maps with real coordinates
//requires text mesh pro to work
//so far used for
//level editors
//tile based building system
//grid reresentation of positions of game objects
namespace Lemon.GenericLib.Generics
{
public class Grid<TGridObject>
{
public event EventHandler<OnGridObjectChangedArgs> OnGridObjectChanged;
public class OnGridObjectChangedArgs : EventArgs
{
public int x, y;
}
public int width;
public int height;
private float cellSize;
private Vector3 originPosition;
private TGridObject[,] gridArray;
private TextMeshPro[,] gridText;
private Color textColour;
private bool showText;
private int textSize;
private bool spawnText;
private bool debugLine;
#region constructors
//arrangement of y is up and x is right
//grid constructor for custom data types
public Grid(int width, int height, float cellSize, Vector3 originPosition, Transform parent, Func<Grid<TGridObject>, int, int, TGridObject> createGridObject, bool spawnText = true, bool debugLine = true)
{
this.width = width;
this.height = height;
this.cellSize = cellSize;
this.gridArray = new TGridObject[width, height];
this.gridText = new TextMeshPro[width, height];
this.originPosition = originPosition;
this.textColour = Color.white;
this.showText = true;
this.textSize = 5;
this.spawnText = spawnText;
this.debugLine = debugLine;
//construct grid object
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
gridArray[x, y] = createGridObject(this, x, y);
}
}
//set debug visuals
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
if (debugLine)
{
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x, y + 1), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x + 1, y), Color.white, 100f);
}
if (spawnText)
gridText[x, y] = CreateGridText(gridArray[x, y]?.ToString(), parent, x, y, GetWorldPositionCenter(x, y), textSize, textColour, TMPro.TextAlignmentOptions.CenterGeoAligned);
//disable text if configured to not show
gridText[x, y]?.gameObject.SetActive(showText);
}
}
if (debugLine)
{
Debug.DrawLine(GetWorldPosition(0, height), GetWorldPosition(width, height), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(width, 0), GetWorldPosition(width, height), Color.white, 100f);
}
//assign object changed even for debug visuals
OnGridObjectChanged += (object sender, OnGridObjectChangedArgs eventArgs) =>
{
gridText[eventArgs.x, eventArgs.y].text = gridArray[eventArgs.x, eventArgs.y].ToString();
};
}
//grid constructor for non custom data type
public Grid(int width, int height, float cellSize, Vector3 originPosition, Transform parent, bool spawnText = true, bool debugLine = true)
{
this.width = width;
this.height = height;
this.cellSize = cellSize;
this.gridArray = new TGridObject[width, height];
this.gridText = new TextMeshPro[width, height];
this.originPosition = originPosition;
this.textColour = Color.white;
this.showText = true;
this.textSize = 5;
this.spawnText = spawnText;
this.debugLine = debugLine;
//set debug visuals
for (int x = 0; x < gridArray.GetLength(0); x++)
{
for (int y = 0; y < gridArray.GetLength(1); y++)
{
if (debugLine)
{
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x, y + 1), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x + 1, y), Color.white, 100f);
}
if (spawnText)
gridText[x, y] = CreateGridText(gridArray[x, y]?.ToString(), parent, x, y, GetWorldPositionCenter(x, y), textSize, textColour, TMPro.TextAlignmentOptions.CenterGeoAligned);
//disable text if configured to not show
gridText[x, y]?.gameObject.SetActive(showText);
}
}
if (debugLine)
{
Debug.DrawLine(GetWorldPosition(0, height), GetWorldPosition(width, height), Color.white, 100f);
Debug.DrawLine(GetWorldPosition(width, 0), GetWorldPosition(width, height), Color.white, 100f);
}
//assign object changed even for debug visuals
OnGridObjectChanged += (object sender, OnGridObjectChangedArgs eventArgs) =>
{
gridText[eventArgs.x, eventArgs.y].text = gridArray[eventArgs.x, eventArgs.y].ToString();
};
}
#endregion
#region position hash
//the hash index for the grid, start from 0 in the bottom left cell and counting right and upwards
//hash the ridArray position into hash index
public int positionHash(int x, int y)
{
return y * width + x;
}
//hash the index back to gridArray position
public void positionHash(int index, out int x, out int y)
{
y = index / width;
x = index % width;
}
#endregion
#region Get Positions
//get world posisiton of a corner of a cell
private Vector3 GetWorldPosition(int x, int y)
{
return new Vector3(x, y) * cellSize + originPosition;
}
//get world positon of the center of a cell
public Vector3 GetWorldPositionCenter(int x, int y)
{
return GetWorldPosition(x, y) + new Vector3(cellSize, cellSize) * .5f;
}
//convert a vector 3 position to the center of a grid
public Vector3 GetWorldPositionCenter(Vector3 worldPosition)
{
int x, y;
GetXY(worldPosition, out x, out y);
return GetWorldPositionCenter(x, y);
}
//get x and y of grid from world posistion
public void GetXY(Vector3 worldPosition, out int x, out int y)
{
x = Mathf.FloorToInt((worldPosition - originPosition).x / cellSize);
y = Mathf.FloorToInt((worldPosition - originPosition).y / cellSize);
}
public Vector2Int GetXYVector2Int(Vector3 worldPosition)
{
return new Vector2Int(Mathf.FloorToInt((worldPosition - originPosition).x / cellSize), Mathf.FloorToInt((worldPosition - originPosition).y / cellSize));
}
#endregion
#region Grid Object Manipulation
//set value from x and y of the array
public void SetGridObject(int x, int y, TGridObject gridObject)
{
if (x >= 0 && x < width && y >= 0 && y < height)
{
gridArray[x, y] = gridObject;
TriggerGridObjectChanged(x, y);
}
}
//set value from world position
public void SetGridObject(Vector3 worldPosition, TGridObject gridObject)
{
int x, y;
GetXY(worldPosition, out x, out y);
SetGridObject(x, y, gridObject);
}
//get value from x and y of the array
public TGridObject GetGridObject(int x, int y)
{
if (x >= 0 && x < width && y >= 0 && y < height)
{
return gridArray[x, y];
}
else
{
return default(TGridObject);
}
}
public TGridObject GetGridObject(Vector2Int pos)
{
return GetGridObject(pos.x, pos.y);
}
//get value from world position
public TGridObject GetGridObject(Vector3 worldPosition)
{
int x, y;
GetXY(worldPosition, out x, out y);
return GetGridObject(x, y);
}
#endregion
#region get grid object patterns
List<TGridObject> returnObjList = new List<TGridObject>();
public bool CheckWithinGrid(Vector2Int pos) {
if (pos.x >= 0 && pos.x < width) {
if (pos.y >= 0 && pos.y < height)
return true;
}
return false;
}
public bool CheckWithinGrid(Vector3 worldPosition)
{
if (worldPosition.x >= originPosition.x && worldPosition.x < originPosition.x + (cellSize*width))
{
if (worldPosition.y >= originPosition.y && worldPosition.y < originPosition.y + (cellSize * height))
return true;
}
return false;
}
public List<TGridObject> GetAdjacent(Vector2Int originPos, int range = 1, bool includeSelf = false)
{
returnObjList.Clear();
List<Vector2Int> dirList = new List<Vector2Int>() { Vector2Int.up, Vector2Int.down, Vector2Int.left, Vector2Int.right };
if (CheckWithinGrid(originPos) && includeSelf) returnObjList.Add(GetGridObject(originPos));
foreach (var item in dirList)
{
if (CheckWithinGrid(originPos+(item*range))) returnObjList.Add(GetGridObject(originPos+ (item * range)));
}
return returnObjList;
}
public List<TGridObject> GetSurrounding(Vector2Int originPos,int range = 1, bool includeSelf = false)
{
returnObjList.Clear();
List<Vector2Int> dirList = new List<Vector2Int>() { new Vector2Int(-1,1), new Vector2Int(1, 1), new Vector2Int(-1, -1), new Vector2Int(1, -1) };
returnObjList.AddRange(GetAdjacent(originPos, range, includeSelf));
foreach (var item in dirList)
{
if (CheckWithinGrid(originPos + (item * range))) returnObjList.Add(GetGridObject(originPos + (item * range)));
}
return returnObjList;
}
public List<TGridObject> GetArea(Vector2Int originPos, int range = 1, bool includeSelf = false)
{
returnObjList.Clear();
Vector2Int temp;
for (int x = originPos.x- range; x <= originPos.x+range; x++)
{
for (int y = originPos.y - range; y <= originPos.y + range; y++)
{
temp = new Vector2Int(x, y);
if (CheckWithinGrid(temp)) {
if (temp == originPos && !includeSelf) continue;
returnObjList.Add(GetGridObject(temp));
}
}
}
return returnObjList;
}
public List<TGridObject> GetRow(int y)
{
returnObjList.Clear();
for (int x = 0; x < width; x++)
{
returnObjList.Add(gridArray[x, y]);
}
return returnObjList;
}
public List<TGridObject> GetColumn(int x)
{
returnObjList.Clear();
for (int y = 0; y < height; y++)
{
returnObjList.Add(gridArray[x, y]);
}
return returnObjList;
}
#endregion
#region entire grid manipulation
public TGridObject[,] OutputArray()
{
return gridArray;
}
public void DoAllGridObjects(Action<int,int,TGridObject> function) {
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
function(x,y,gridArray[x, y]);
}
}
}
public void DestroyGrid()
{
if (!spawnText) return;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
if (gridText[x, y] != null)
{
MonoBehaviour.Destroy(gridText[x, y].gameObject);
}
}
}
}
#endregion
#region DebugText
//trigger the update debug text event using gridArray Position
public void TriggerGridObjectChanged(int x, int y)
{
if (OnGridObjectChanged != null && spawnText) OnGridObjectChanged(this, new OnGridObjectChangedArgs { x = x, y = y });
}
//trigger the update debug text event using world Position
public void TriggerGridObjectChanged(Vector3 position)
{
int x, y;
GetXY(position, out x, out y);
if (OnGridObjectChanged != null && spawnText) OnGridObjectChanged(this, new OnGridObjectChangedArgs { x = x, y = y });
}
//configure debug text option
//so far no use for this
public void configureDebugText(bool show, Color textColour, int size)
{
this.showText = show;
this.textColour = textColour;
this.textSize = size;
if (!spawnText) return;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
//disable text if configured to not show
gridText[x, y]?.gameObject.SetActive(showText);
if (gridText[x, y] != null)
{
gridText[x, y].color = this.textColour;
gridText[x, y].fontSize = this.textSize;
}
}
}
}
//get if the text is shown
public bool getShowText()
{
return showText;
}
// Create Text in the Grid
private TextMeshPro CreateGridText(string text, Transform parent = null, int x = 0, int y = 0, Vector3 localPosition = default(Vector3), int fontSize = 40, Color? color = null, TextAlignmentOptions textAlignment = TextAlignmentOptions.Left, int sortingOrder = 5000)
{
if (color == null) color = Color.white;
return CreateGridText(parent, text, $"Grid_Text_[{x}, {y}]", localPosition, fontSize, (Color)color, textAlignment, sortingOrder);
}
// Create Text in the Grid
private TextMeshPro CreateGridText(Transform parent, string text, string objectName, Vector3 localPosition, int fontSize, Color color, TextAlignmentOptions textAlignment, int sortingOrder)
{
GameObject gameObject = new GameObject(objectName, typeof(TextMeshPro));
Transform transform = gameObject.transform;
transform.SetParent(parent, false);
transform.localPosition = localPosition;
TextMeshPro textMesh = gameObject.GetComponent<TextMeshPro>();
textMesh.alignment = textAlignment;
//textMesh.anchor = AnchorPositions.Center;
textMesh.text = text;
textMesh.fontSize = fontSize;
textMesh.color = color;
textMesh.GetComponent<MeshRenderer>().sortingOrder = sortingOrder;
return textMesh;
}
#endregion
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 67f78fc7678d30c41a2a7d560cf4bda9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.Generics
{
public class GridHelper<T>
{
private Grid<T> grid;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e422af2af72481844b3dc6e0cd0d8c71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,31 @@
using System;
using UnityEngine;
namespace Lemon.GenericLib.Generics
{
[Serializable]
public struct Optional<T>
{
[SerializeField] private bool enabled;
[SerializeField] private T value;
public bool Enabled => enabled;
public T Value => value;
public Optional(T initialValue)
{
enabled = true;
value = initialValue;
}
public void Set(T initialValue)
{
if (enabled)
{
value = initialValue;
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4d1b9d247f954f4e93b1308c11cccb3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//todo
//use deligates
namespace Lemon.GenericLib.Generics
{
public class TickCounter
{
private float counter = 0;
public float increment = 1;
public bool debugtText = false;
public string debugString = "default counter";
Action callbackAction;
public TickCounter()
{
increment = 1;
counter = 0;
}
public TickCounter(float incrementValue)
{
increment = incrementValue;
counter = 0;
}
public TickCounter(float incrementValue, Action initalAction)
{
increment = incrementValue;
callbackAction += initalAction;
counter = 0;
}
//call this in update
public void AdvanceTick()
{
if (Time.time > counter)
{
if (debugtText) Debug.Log("Tick: " + debugString);
//do something
callbackAction();
counter = Time.time + increment;
}
}
public void addAction(Action newAction)
{
callbackAction += newAction;
}
public void removeAction(Action removedAction)
{
callbackAction -= removedAction;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14acffb5acb0f2345a99c54b6fe45e89
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,78 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Security.Cryptography;
//for Iced_Lemon only, do not modify
//TODO: seperate the functionalities in the future
namespace Lemon.GenericLib.Code.Utilities {
public static class LemonCodeUtilities {
//strings
#region StringUtilities
public static bool CompareTextNonCase(string textA, string textB)
{
return textA.ToUpper() == textB.ToUpper();
}
public static string TrimLastChar(string text)
{
return text.Substring(0, text.Length - 1);
}
#endregion
#region RandomUtilities
//randoms
public static float RandomVectorValue(Vector2 vector) { return UnityEngine.Random.Range(vector.x, vector.y); }
public static int RandomVectorValueInt(Vector2Int vector) { return UnityEngine.Random.Range(vector.x, vector.y + 1); }
public static int RandomArrayIndex(object[] array) { return UnityEngine.Random.Range(0, array.Length); }
public static object RandomArrayItem(object[] array) { return array[UnityEngine.Random.Range(0, array.Length)]; }
public static int RandomListIndex(List<object> list) { return UnityEngine.Random.Range(0, list.Count); }
public static object RandomListItem(List<object> list) { return list[UnityEngine.Random.Range(0, list.Count)]; }
public static bool RandomBool() { return UnityEngine.Random.Range(0, 2) > 0; }
public static void Shuffle<T>(this IList<T> list)
{
//RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
//int n = list.Count;
//while (n > 1)
//{
// byte[] box = new byte[1];
// do provider.GetBytes(box);
// while (!(box[0] < n * (Byte.MaxValue / n)));
// int k = (box[0] % n);
// n--;
// T value = list[k];
// list[k] = list[n];
// list[n] = value;
//}
System.Random rng = new System.Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
#endregion
public static string PrintList<T>(List<T> list) {
string str = "[ ";
foreach (var item in list)
{
str += item.ToString() + ", ";
}
return str + " ]";
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 62610c7ce1754534b8224dad77ba905f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5204d5bab5b4a94ca008991c6328ffe
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,130 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
namespace Lemon.GenericLib.SceneManagement {
public class SceneTransition : MonoBehaviour
{
public static SceneTransition Instance;
//singleton pattern
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
if (Instance != this)
{
Destroy(gameObject);
}
}
[SerializeField] float transitionTime;
//[SerializeField] UITransitionAnimator transitionAnimator;
[SerializeField] bool enableStartingTransition = true;
[SerializeField] UnityEvent transitionEnterFunction;
[SerializeField] UnityEvent transitionExitFunction;
private bool isTransitionAvailable = true;
// Start is called before the first frame update
void Start()
{
if (enableStartingTransition)
{
isTransitionAvailable = false;
transitionEnterFunction?.Invoke();
//transitionAnimator.TransitionIn();
StartCoroutine(EnableTransition());
}
}
public void TransitionScene(int sceneIndex)
{
if (!isTransitionAvailable) return;
isTransitionAvailable = false;
transitionExitFunction?.Invoke();
//transitionAnimator.TransitionOut();
StartCoroutine(LoadScene(sceneIndex));
}
public void TransitionScene(string sceneName)
{
if (!isTransitionAvailable) return;
isTransitionAvailable = false;
transitionExitFunction?.Invoke();
//transitionAnimator.TransitionOut();
StartCoroutine(LoadScene(sceneName));
}
public void RestartScene()
{
TransitionScene(SceneManager.GetActiveScene().buildIndex);
}
public void QuitGame()
{
transitionExitFunction?.Invoke();
StartCoroutine(QuitGameRoutine());
}
public void TransitionNextScene()
{
if (!isTransitionAvailable) return;
isTransitionAvailable = false;
transitionExitFunction?.Invoke();
//transitionAnimator.TransitionOut();
StartCoroutine(LoadScene(SceneManager.GetActiveScene().buildIndex + 1));
}
public void TransitionPreviousScene()
{
if (!isTransitionAvailable) return;
isTransitionAvailable = false;
transitionExitFunction?.Invoke();
//transitionAnimator.TransitionOut();
StartCoroutine(LoadScene(SceneManager.GetActiveScene().buildIndex - 1));
}
public void TransitionScene(int sceneIndex, bool useAnimation = true)
{
transitionExitFunction?.Invoke();
// transitionAnimator.TransitionOut();
StartCoroutine(LoadScene(sceneIndex));
}
IEnumerator LoadScene(int sceneIndex)
{
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(sceneIndex);
}
IEnumerator LoadScene(string sceneName)
{
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(sceneName);
}
IEnumerator EnableTransition()
{
yield return new WaitForSeconds(transitionTime);
isTransitionAvailable = true;
}
IEnumerator QuitGameRoutine()
{
yield return new WaitForSeconds(transitionTime);
Application.Quit();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 76ad778d7bf1bbc41bacdfd410da4a84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace Lemon.GenericLib.SceneManagement
{
public class TransitionUI : MonoBehaviour
{
[SerializeField] private CanvasGroup canvasGroup;
[SerializeField] private bool useDefaultFadeTransition;
[SerializeField] public float effectDuration;
[SerializeField] private LeanTweenType fadeEffectType;
//[SerializeField] float threshold;
//[SerializeField] float rate;
//[SerializeField] GameObject transitionObject;
private float targetAlpha = 1;
public void TransitionAnimationEnter()
{
targetAlpha = 0;
if (useDefaultFadeTransition)
{
canvasGroup.LeanAlpha(targetAlpha, effectDuration).setEase(fadeEffectType).setOnComplete(() => { canvasGroup.blocksRaycasts = false; });
return;
}
}
public void TransitionAnimationExit()
{
targetAlpha = 1;
if (useDefaultFadeTransition)
{
canvasGroup.LeanAlpha(targetAlpha, effectDuration).setEase(fadeEffectType).setOnComplete(() => { canvasGroup.blocksRaycasts = true; });
return;
}
}
//float alpha = 0;
//public void Update() {
// alpha = canvasGroup.alpha;
// alpha = Mathf.Lerp(alpha, targetAlpha, rate * Time.deltaTime);
// canvasGroup.alpha = alpha;
// canvasGroup.blocksRaycasts = (alpha > threshold);
//}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cdf26c62e5d4b2d4490ef743edfbe89b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4954d2b52f51a3d44bc052acbe51c81c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Lemon.GenericLib.Score {
public class ScoreKeeper
{
public string HIGHSCORE_PLAYERPREF = "HighScore";
//score variables
private int score = 0;
private int scoreMultiplier = 1;
public int maxMultiplier = 7;
//score changing event
//mainly used for UI
public Action<int> OnScoreModified;
public Action<int> OnScoreMultiplierModified;
public Action<int> OnNewHighScore;
//getter setters, not advice to set score directly
public int Score { get => score; set => score = value; }
public int ScoreMultiplier { get => scoreMultiplier; set => scoreMultiplier = value; }
public int HighScore { get => PlayerPrefs.GetInt(HIGHSCORE_PLAYERPREF); set => PlayerPrefs.SetInt(HIGHSCORE_PLAYERPREF, score); }
public void ForceUpdate()
{
OnScoreModified?.Invoke(score);
OnScoreMultiplierModified?.Invoke(scoreMultiplier);
}
public void ModifyScore(int value)
{
score += (value * scoreMultiplier);
OnScoreModified?.Invoke(score);
}
public void ResetScore()
{
score = 0;
OnScoreModified?.Invoke(score);
}
public void ModifyMultiplier(int value)
{
scoreMultiplier += value;
scoreMultiplier = Mathf.Clamp(scoreMultiplier, 1, maxMultiplier);
OnScoreMultiplierModified?.Invoke(scoreMultiplier);
}
public void ResetMultiplier()
{
scoreMultiplier = 1;
OnScoreMultiplierModified?.Invoke(scoreMultiplier);
}
public bool CheckHighScore()
{
if (score > PlayerPrefs.GetInt(HIGHSCORE_PLAYERPREF))
{
PlayerPrefs.SetInt(HIGHSCORE_PLAYERPREF, score);
OnNewHighScore?.Invoke(score);
return true;
}
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70caaedb4a6576a4fbb4a7f78ecc4605
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c2eff9b9eb3fb8b49b67c10a697cd927
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 12d0daac2445aa64b89b3cd4c8e6bc59
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,110 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
namespace Lemon.GenericLib.UI
{
public class ImageUIManager : MonoBehaviour
{
public static ImageUIManager Instance;
//singleton pattern
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
if (Instance != this)
{
Destroy(gameObject);
}
}
[SerializeField] ImageUIData[] ImageUIList;
[Serializable]
struct ImageUIData
{
public string UIName;
public Image ImageUI;
public float fillRate;
public float targetFill;
public float snapFillMargin;
public void UpdateFill()
{
if (ImageUI.fillAmount == targetFill) return;
ImageUI.fillAmount = Mathf.Lerp(ImageUI.fillAmount, targetFill, fillRate * Time.deltaTime);
if (Mathf.Abs(targetFill - ImageUI.fillAmount) <= snapFillMargin) ImageUI.fillAmount = targetFill;
}
public void SetFill(float value)
{
targetFill = value;
}
}
private void Update()
{
for (int i = 0; i < ImageUIList.Length; i++)
{
ImageUIList[i].UpdateFill();
}
}
public bool SetFill(string UIName, float fill)
{
for (int i = 0; i < ImageUIList.Length; i++)
{
if (UIName == ImageUIList[i].UIName)
{
ImageUIList[i].SetFill(fill);
return true;
}
}
Debug.LogError(" Image UI of nane " + UIName + " does not exist");
return false;
}
public bool SetFillForce(string UIName, float fill)
{
for (int i = 0; i < ImageUIList.Length; i++)
{
if (UIName == ImageUIList[i].UIName)
{
ImageUIList[i].ImageUI.fillAmount = fill;
return true;
}
}
Debug.LogError(" Image UI of nane " + UIName + " does not exist");
return false;
}
public bool SetImage(string UIName, Sprite image)
{
for (int i = 0; i < ImageUIList.Length; i++)
{
if (UIName == ImageUIList[i].UIName)
{
ImageUIList[i].ImageUI.sprite = image;
return true;
}
}
Debug.LogError(" Image UI of nane " + UIName + " does not exist");
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e6113c552c6f9e94190849ea5044d042
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,112 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using TMPro;
namespace Lemon.GenericLib.UI
{
public class TextUIManager : MonoBehaviour
{
public static TextUIManager Instance;
//singleton pattern
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
if (Instance != this)
{
Destroy(gameObject);
}
InitTextUI();
}
public void InitTextUI()
{
for (int i = 0; i < textUIList.Length; i++)
{
textUIList[i].InitUI();
}
}
[SerializeField] TextUI[] textUIList;
[Serializable]
struct TextUI
{
public string UIName;
public TextMeshProUGUI textMesh;
public bool textGoUp;
public float textGoUpDistance;
public float textEffectTime;
public LeanTweenType easeType;
[SerializeField] private Vector3 originalPos;
private bool canAnimate;
[SerializeField] private bool explixitDefineStartY;
[SerializeField] Vector3 startPos;
public void SetText(string text)
{
textMesh.text = text;
if (textGoUp && canAnimate) LeanTween.moveLocalY(textMesh.gameObject, originalPos.y + textGoUpDistance, textEffectTime).setOnComplete(AnimateEffectBack);
}
public void SetColour(Color colour)
{
textMesh.color = colour;
}
public void InitUI()
{
if (explixitDefineStartY) originalPos = startPos;
else originalPos = textMesh.GetComponent<RectTransform>().localPosition;
canAnimate = true;
}
private void AnimateEffectBack()
{
LeanTween.moveLocalY(textMesh.gameObject, originalPos.y, textEffectTime);
}
}
public bool SetText(string UIName, string text)
{
for (int i = 0; i < textUIList.Length; i++)
{
if (UIName == textUIList[i].UIName)
{
textUIList[i].SetText(text);
return true;
}
}
Debug.LogError("text UI of nane " + UIName + " does not exist");
return false;
}
public bool SetColour(string UIName, Color colour)
{
for (int i = 0; i < textUIList.Length; i++)
{
if (UIName == textUIList[i].UIName)
{
textUIList[i].SetColour(colour);
return true;
}
}
Debug.LogError("text UI of nane " + UIName + " does not exist");
return false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 454e8a3504cc8734c861860dfef3875f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d8a913671c0abc9459f3e8a14d2cc066
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,67 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
namespace Lemon.GenericLib.UI
{
public class TabButtonScript : MonoBehaviour, IPointerEnterHandler, IPointerClickHandler, IPointerExitHandler
{
[SerializeField] TabGroup tabGroup;
[SerializeField] private UnityEvent onTabEnter;
[SerializeField] private UnityEvent onTabExit;
[SerializeField] private UnityEvent onTabSelected;
[SerializeField] private UnityEvent onTabDeselected;
public void OnPointerClick(PointerEventData eventData)
{
tabGroup.OnTabSelected(this);
}
public void OnPointerEnter(PointerEventData eventData)
{
tabGroup.OnTabEnter(this);
}
public void OnPointerExit(PointerEventData eventData)
{
tabGroup.OnTabExit(this);
}
public void OnEnter()
{
onTabEnter?.Invoke();
}
public void OnExit()
{
onTabExit?.Invoke();
}
public void OnSelected()
{
onTabSelected?.Invoke();
}
public void OnDeselected()
{
onTabDeselected?.Invoke();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ccb3057007dfb1541810d434b448bcc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,123 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//TODO: make this system supprts tabs without using tab buttons
// or redo the entire thing
// yeah we need to redo the whole thing
// for now make your own page system
namespace Lemon.GenericLib.UI
{
public class TabGroup : MonoBehaviour
{
[SerializeField] private List<TabSet> tabSets;
[SerializeField] private int defaultTabIndex;
private TabButtonScript selectedButton;
[Serializable]
struct TabSet
{
public TabButtonScript tabButton;
public GameObject tabObject;
public TabSet(TabButtonScript tabButton, GameObject tabObject)
{
this.tabButton = tabButton;
this.tabObject = tabObject;
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
}
private void Start()
{
if (tabSets == null || defaultTabIndex < 0 || defaultTabIndex > tabSets.Count)
{
Debug.LogError("default tab cannot be asisgned, pleace chect the default tab index and make sure the tab list is initialized");
}
else
{
OnTabSelected(tabSets[defaultTabIndex].tabButton);
}
}
public void Subscribe(TabButtonScript button, GameObject tabObject)
{
if (tabSets == null)
{
tabSets = new List<TabSet>();
}
tabSets.Add(new TabSet(button, tabObject));
}
public void OnTabEnter(TabButtonScript button)
{
ResetTabs();
if (selectedButton == null || button != selectedButton)
{
button.OnEnter();
}
}
public void OnTabExit(TabButtonScript button)
{
ResetTabs();
}
public void OnTabSelected(TabButtonScript button)
{
if (selectedButton != null)
{
selectedButton.OnDeselected();
}
selectedButton = button;
button.OnSelected();
UpdateSelectedTab();
ResetTabs();
}
public void ResetTabs()
{
foreach (var item in tabSets)
{
if (selectedButton != null && item.tabButton == selectedButton) { continue; }
item.tabButton.OnExit();
}
}
//can overwite this
public void UpdateSelectedTab()
{
foreach (var tab in tabSets)
{
if (tab.tabButton == selectedButton)
{
tab.tabObject.SetActive(true);
tab.tabObject.transform.SetSiblingIndex(tabSets.Count - 1);
}
else
{
tab.tabObject.SetActive(false);
tab.tabObject.transform.SetSiblingIndex(0);
}
}
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0206a02701fc75c4eb1f54e3113fd697
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 09ee81d16d5d9e642a895942382537d9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,296 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX {
public class CameraController : MonoBehaviour
{
public static CameraController instanceCC;
[SerializeField] Camera cam;
[SerializeField] Transform player;
[SerializeField] float shootshakeDuration = 0.2f;
private Vector2 originalPosition;
Vector3 target, mousePos, refVel, shkeOffset;
float cameraDist = 2.5f;
float smoothTime = 0.2f;
[SerializeField] float shootShakeMagnitude = 2;
Vector3 shootShakeDirection = Vector3.zero;
float shootShakeTimeEnd = 0;
bool shootshake = false;
[SerializeField] float shakePower;
[SerializeField] float smallShakeMultiplier;
[SerializeField] Vector2 screenshakeOffset = Vector2.zero;
//private Game_Manager gameManager;
//singleton pattern
private void Awake()
{
if (instanceCC == null)
{
instanceCC = this;
}
if (instanceCC != this)
{
Destroy(gameObject);
}
}
public void SetPlayer(Transform playerTransform)
{
player = playerTransform;
}
// Start is called before the first frame update
void Start()
{
//cb = GetComponent<CinemachineBrain>();
//gameManager = Game_Manager.instanceGM;
cam = Camera.main;
originalPosition = transform.position;
//player = FindObjectOfType<PlayerController>()?.transform;
screenshakeOffset = Vector2.zero;
//gameManager.ChangeGameStateEvent += HandleGameStateChanges;
}
////not working currently for some reason
//private void HandleGameStateChanges(object sender, Game_Manager.ChangeGameStateArgs e)
//{
// //Debug.Log("finding player");
// if (e.newState == Game_Manager.GameState.gameplay) {
// Invoke("FindPlayer", 0.01f);
// }
//}
void FindPlayer()
{
Debug.Log("finding player");
//player = FindObjectOfType<PlayerController>()?.transform;
}
Vector3 shootShakeOffset = Vector3.zero;
// Update is called once per frame
void Update()
{
Vector3 destinationPos = originalPosition;
//Vector3 destinationPos = transform.position;
//if (player != null)
//{
// mousePos = GetMousePos();
// target = UpdateTargetPos();
// Vector3 tempPos;
// tempPos = Vector3.SmoothDamp(transform.position, target, ref refVel, smoothTime);
// transform.position = tempPos;
// //mouse distance thing
// Vector2 playerPos = Vector3.zero;
// destinationPos = Vector2.Lerp(originalPosition, playerPos, 0.2f);
// Vector2 MousePos = cam.ScreenToWorldPoint(Input.mousePosition);
// Vector3 mouseDistance = MousePos - playerPos;
// mouseDistance = Vector3.Lerp(Vector3.zero, mouseDistance, 0.05f);
// mouseDistance.z = 0;
if (!shootshake || Time.time >= shootShakeTimeEnd)
{
shootshake = false;
//Debug.Log("not shaking");
shootShakeOffset = Vector3.Lerp(shootShakeOffset, Vector3.zero, 15 * Time.deltaTime);
}
else
{
//Debug.Log(" shaking");
shootShakeOffset = Vector3.Lerp(shootShakeOffset, shootShakeDirection * shootShakeMagnitude, 15 * Time.deltaTime);
}
destinationPos.z = -10;
transform.position = destinationPos + (Vector3)screenshakeOffset + shootShakeOffset;
//}
//else
//{
// destinationPos = Vector2.Lerp(transform.position, originalPosition, 0.2f);
// destinationPos.z = -10;
// transform.position = destinationPos + (Vector3)screenshakeOffset;
//}
}
public Vector3 UpdateTargetPos()
{
Vector3 mouseOffset = mousePos * cameraDist;
Vector3 ret = player.position + mouseOffset;
ret.z = -10;
return ret;
}
public Vector3 GetMousePos()
{
Vector2 ret = cam.ScreenToViewportPoint(Input.mousePosition);
ret *= 2;
ret -= Vector2.one;
float max = 0.9f;
if (Mathf.Abs(ret.x) > max || Mathf.Abs(ret.y) > max)
{
ret = ret.normalized;
}
return ret;
}
public void ApplyShootShake(float duration, Vector3 direction)
{
shootshake = true;
shootShakeDirection = direction;
//yield return new WaitForSeconds(duration);
shootShakeTimeEnd = Time.time + duration;
}
public void ApplyShootShake(float angle, float power)
{
shootshake = true;
shootShakeDirection = (new Vector3((float)Mathf.Cos(angle * Mathf.Deg2Rad), (float)Mathf.Sin(angle * Mathf.Deg2Rad))).normalized;
//yield return new WaitForSeconds(duration);
shootShakeTimeEnd = Time.time + shootshakeDuration;
}
public void ApplyShootShake(float angle)
{
shootshake = true;
shootShakeDirection = (new Vector3((float)Mathf.Cos(angle * Mathf.Deg2Rad), (float)Mathf.Sin(angle * Mathf.Deg2Rad))).normalized;
//yield return new WaitForSeconds(duration);
shootShakeTimeEnd = Time.time + shootshakeDuration;
}
public void ApplyShootShake(Vector3 direction)
{
shootshake = true;
shootShakeDirection = direction;
//yield return new WaitForSeconds(duration);
shootShakeTimeEnd = Time.time + shootshakeDuration;
}
public void ApplyScreenShake(float duration = 0.1f, bool isSmall = false)
{
StopCoroutine("Screenshake");
StartCoroutine(Screenshake(duration, isSmall));
}
public void ApplyScreenShake(float duration, float newShakePower, bool isSmall = false)
{
//cb.enabled = false;
StopCoroutine("Screenshake");
StartCoroutine(Screenshake(duration, newShakePower, isSmall));
}
IEnumerator Screenshake(float duration, bool isSmall = false)
{
screenshakeOffset = Vector2.zero;
//originalPosition = transform.position;
//cb.enabled = false;
//Debug.Log("shake " + cb.enabled);
float currentShakePower = shakePower;
if (isSmall) currentShakePower *= smallShakeMultiplier;
float shakeFadeTime = currentShakePower / duration;
while (duration > 0)
{
float xOffset = Random.Range(-1f, 1f) * currentShakePower;
float yOffset = Random.Range(-1f, 1f) * currentShakePower;
screenshakeOffset.x = xOffset;
screenshakeOffset.y = yOffset;
duration -= Time.deltaTime;
currentShakePower = Mathf.MoveTowards(shakePower, 0f, shakeFadeTime * Time.deltaTime);
yield return null;
}
screenshakeOffset = Vector2.zero;
// cb.enabled = true;
}
IEnumerator Screenshake(float duration, float thisShakePower, bool isSmall = false)
{
screenshakeOffset = Vector2.zero;
float currentShakePower = thisShakePower;
if (isSmall) currentShakePower *= smallShakeMultiplier;
float shakeFadeTime = currentShakePower / duration;
while (duration > 0)
{
float xOffset = Random.Range(-1f, 1f) * currentShakePower;
float yOffset = Random.Range(-1f, 1f) * currentShakePower;
screenshakeOffset.x = xOffset;
screenshakeOffset.y = yOffset;
duration -= Time.deltaTime;
currentShakePower = Mathf.MoveTowards(shakePower, 0f, shakeFadeTime * Time.deltaTime);
yield return null;
}
screenshakeOffset = Vector2.zero;
}
public void HitPause(float duration = 0.05f)
{
Time.timeScale = 1;
StopCoroutine("HitPauseRoutine");
StartCoroutine(HitPauseRoutine(duration));
}
IEnumerator HitPauseRoutine(float duration)
{
// Debug.LogError("FUCK");
Time.timeScale = 0;
yield return new WaitForSecondsRealtime(duration);
Time.timeScale = 1;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb19143cd46ff7641a1522d7318b29dd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX {
public class ConstantRotation : MonoBehaviour
{
public Vector3 rotationVector;
private void FixedUpdate()
{
transform.Rotate(rotationVector * Time.deltaTime);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14b9658d15552084d841ba0dd6a818ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX
{
public class FixedRotation : MonoBehaviour
{
// Update is called once per frame
void Update()
{
transform.rotation = Quaternion.identity;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9fb2c212857fc924cb0ce6c1e6fbd4a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,65 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//TODO: make this object pool compatible
namespace Lemon.GenericLib.VFX
{
public class GhostManager : MonoBehaviour
{
public float ghostInterval = 0.1f;
public float ghostLifeTime = 0.5f;
private float currentInterval = 0;
public GameObject ghost;
public bool createGhost = false;
public bool recolourGhost;
public Color ghostColor;
private SpriteRenderer sr;
// Start is called before the first frame update
void Start()
{
sr = GetComponent<SpriteRenderer>();
currentInterval = 0;
}
// Update is called once per frame
void Update()
{
if (currentInterval >= ghostInterval)
{
if (!createGhost) return;
GameObject currentGhost = Instantiate(ghost, transform.position, transform.rotation);
currentGhost.transform.localScale = transform.localScale;
currentGhost.GetComponent<SpriteRenderer>().sprite = sr.sprite;
if (recolourGhost)
{
currentGhost.GetComponent<SpriteRenderer>().color = ghostColor;
}
Destroy(currentGhost, ghostLifeTime);
currentInterval = 0;
}
else
{
currentInterval += Time.deltaTime;
}
}
public void CreateGhostTemp(float time)
{
StartCoroutine(CreateGhostTempRoutine(time));
}
IEnumerator CreateGhostTempRoutine(float time)
{
createGhost = true;
yield return new WaitForSeconds(time);
createGhost = false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 171af91b161e0b644b33be9f2fae0831
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,77 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
//use lean tween next time
namespace Lemon.GenericLib.VFX
{
public class Popup_Text : MonoBehaviour
{
TextMeshPro PopupText;
public string text;
public float lifetime = 2;
public float startSpeed;
public float speed;
private float targetSpeed;
private float size;
private float targetSize;
public Transform parent;
// Start is called before the first frame update
void Start()
{
PopupText = GetComponent<TextMeshPro>();
PopupText.text = text;
targetSpeed = startSpeed;
size = 0;
targetSize = 1;
StartCoroutine(LifeTime());
parent = transform.parent;
}
// Update is called once per frame
void Update()
{
transform.localPosition += Vector3.up * targetSpeed * Time.deltaTime;
transform.localScale = new Vector3(transform.localScale.x, size);
targetSpeed = Mathf.Lerp(targetSpeed, speed, 5 * Time.deltaTime);
size = Mathf.Lerp(size, targetSize, 20 * Time.deltaTime);
if (parent != null)
{
if (parent.localRotation.y != 0)
{
transform.localRotation = Quaternion.Euler(0, parent.rotation.y - 180, 0);
}
else
{
transform.localRotation = Quaternion.Euler(0, 0, 0);
}
}
}
public void SetText(string text)
{
this.text = text;
PopupText.text = this.text;
}
IEnumerator LifeTime()
{
yield return new WaitForSeconds(lifetime);
targetSize = 0;
Destroy(gameObject, 0.25f);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e358931fe625ddc46a3f28d6d716833b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX
{
//this only works for sprite objects
public class SineWaveHover : MonoBehaviour
{
[SerializeField] float effectSpeed = 1;
[SerializeField] float effectMultiplier = 1;
[SerializeField] public float effectOffset = 1;
float yPos;
Vector3 originalPos;
private void Start()
{
originalPos = transform.localPosition;
}
// Update is called once per frame
void Update()
{
yPos = Mathf.Sin((Time.time + effectOffset) * effectSpeed) * effectMultiplier;
transform.localPosition = originalPos + new Vector3(0, yPos, 0);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2343e432efd75d94a9261bbeed7a17b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX
{
//need to be further developed
public class SpriteFlicker : MonoBehaviour
{
private SpriteRenderer sr;
// Start is called before the first frame update
void Start()
{
sr = GetComponent<SpriteRenderer>();
}
public void FlickerSprite(float duration, int intervals)
{
StopCoroutine("FlickerSpriteRoutine");
StartCoroutine(FlickerSpriteRoutine(duration, intervals));
}
IEnumerator FlickerSpriteRoutine(float duration, int intervals)
{
for (int i = 0; i < intervals; i++)
{
if (i > 0)
{
//if (i == 1) Camera_Controller.instanceCC.ApplyScreenShake(0.05f);
if (sr.maskInteraction == SpriteMaskInteraction.None)
{
sr.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
}
else
{
sr.maskInteraction = SpriteMaskInteraction.None;
}
}
yield return new WaitForSeconds(duration / intervals);
}
sr.maskInteraction = SpriteMaskInteraction.None;
}
public void StopFlicker()
{
StopCoroutine("FlickerSpriteRoutine");
sr.maskInteraction = SpriteMaskInteraction.None;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c233fa6ef7660324c9ded9a1e63c1836
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,59 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Lemon.GenericLib.VFX
{
public class SpriteFrameSetter : MonoBehaviour
{
private SpriteRenderer sr;
[SerializeField] private SpriteFrame[] spriteFrames;
private void Start()
{
sr = GetComponent<SpriteRenderer>();
}
public void SetFrame(string spriteName)
{
foreach (var item in spriteFrames)
{
if (item.spriteName == spriteName)
{
sr.sprite = item.sprite;
return;
}
}
Debug.LogError("Sprite frame requiested is not available.\nPlease check the spelling error");
}
public void SetFrame(int index)
{
if (index >= 0 && index < spriteFrames.Length)
{
sr.sprite = spriteFrames[index].sprite;
return;
}
Debug.LogError($"Sprite frame requiested {index} is not available.\nPlease check the spelling error");
}
[Serializable]
private class SpriteFrame
{
public string spriteName;
public Sprite sprite;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4dfb673b5ecacd542ad64f5665b1e237
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX
{
public class SpriteVibration : MonoBehaviour
{
[SerializeField] Vector2 vibrationRange;
private Vector2 originalPos;
private bool isVibrating = false;
// Start is called before the first frame update
void Start()
{
originalPos = transform.localPosition;
StartCoroutine(Viberate());
}
IEnumerator Viberate()
{
while (true)
{
if (isVibrating)
transform.localPosition = originalPos + new Vector2(Random.Range(-vibrationRange.x, vibrationRange.x), Random.Range(-vibrationRange.y, vibrationRange.y));
//else transform.localPosition = originalPos;
yield return null;
}
}
public void SetVibration(bool value) {
isVibrating = value;
if (!isVibrating) transform.localPosition = originalPos;
}
public void SetTempVibration(float duration) {
StartCoroutine(SetTempVibrationRoutine(duration));
}
IEnumerator SetTempVibrationRoutine(float duration) {
SetVibration(true);
yield return new WaitForSeconds(duration);
SetVibration(false);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ee76a7080bc41504ca743d99f8842420
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,213 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Lemon.GenericLib.VFX
{
//to do: build linear lerping that can change duration
public class SquashAndStretch : MonoBehaviour
{
[SerializeField] private Vector3 squashSize;
[SerializeField] private Vector3 stretchSize;
[SerializeField] private float transformRate = 10;
[SerializeField] private bool useRealative;
[SerializeField] private bool forceSnap = false;
[SerializeField] private Vector3 snapingMargin = new Vector3(0.001f, 0.001f, 0.001f);
public enum SquashMode { lerp, linear, addition }
[SerializeField] SquashMode squashMode;
[SerializeField] float linearLerpDuration;
//if useRealative is enabled the squash size will be the ratio of the original size
//rather than the exact size it's self
private Vector3 originalSize;
private Vector3 targetSize;
private float timeElapsed = 0;
private Vector3 startSize;
// Start is called before the first frame update
void Start()
{
originalSize = transform.localScale;
targetSize = originalSize;
startSize = originalSize;
}
Vector3 vectorToLerp = Vector3.zero;
// Update is called once per frame
void FixedUpdate()
{
//squash and stretch
//if (transform.localScale != targetSize) {
if (squashMode == SquashMode.lerp)
{
transform.localScale = Vector3.Lerp(transform.localScale, targetSize, transformRate * Time.deltaTime);
//Debug.Log("squashing " + targetSize);
if (forceSnap)
{
if (targetSize.x - transform.localScale.x <= snapingMargin.x && targetSize.y - transform.localScale.y <= snapingMargin.y && targetSize.z - transform.localScale.z <= snapingMargin.z)
{
transform.localScale = targetSize;
}
}
}
else if (squashMode == SquashMode.linear)
{
if (timeElapsed < linearLerpDuration)
{
transform.localScale = Vector3.Lerp(startSize, targetSize, timeElapsed / linearLerpDuration);
timeElapsed += Time.deltaTime;
}
else
{
if (forceSnap) transform.localScale = targetSize;
}
}
else if (squashMode == SquashMode.addition)
{
vectorToLerp.x = (transform.localScale.x - targetSize.x) * transformRate * Time.deltaTime;
vectorToLerp.y = (transform.localScale.y - targetSize.y) * transformRate * Time.deltaTime;
vectorToLerp.z = (transform.localScale.z - targetSize.z) * transformRate * Time.deltaTime;
transform.localScale += vectorToLerp;
vectorToLerp = transform.localScale;
if (vectorToLerp.x >= targetSize.x || vectorToLerp.x <= targetSize.x)
{
vectorToLerp.x = targetSize.x;
}
if (vectorToLerp.y >= targetSize.y || vectorToLerp.y <= targetSize.y)
{
vectorToLerp.y = targetSize.y;
}
if (vectorToLerp.z >= targetSize.z || vectorToLerp.z <= targetSize.z)
{
vectorToLerp.z = targetSize.z;
}
transform.localScale = vectorToLerp;
}
//}
}
public void ChnageOriginalSize(Vector3 newSize)
{
originalSize = newSize;
}
public void SetToSquash()
{
if (useRealative)
{
targetSize = new Vector3(originalSize.x * squashSize.x, originalSize.y * squashSize.y, originalSize.z * squashSize.z);
}
else
{
targetSize = squashSize;
}
//if (squashMode == SquashMode.linear || squashMode == SquashMode.addition) {
// timeElapsed = 0;
// startSize = transform.localScale;
//}
}
//returns to original size once it is done
public void SetToSquash(float duration)
{
StartCoroutine(SquashTimer(duration));
}
public void SetToStretch()
{
if (useRealative)
{
targetSize = new Vector3(originalSize.x * stretchSize.x, originalSize.y * stretchSize.y, originalSize.z * stretchSize.z);
}
else
{
targetSize = stretchSize;
}
if (squashMode == SquashMode.linear || squashMode == SquashMode.addition)
{
timeElapsed = 0;
startSize = transform.localScale;
}
}
//returns to original size once it is done
public void SetToStretch(float duration)
{
StartCoroutine(StretchTimer(duration));
}
public void customSquish(Vector3 newSize, bool useRealitive = false)
{
if (useRealitive)
{
targetSize = new Vector3(originalSize.x * newSize.x, originalSize.y * newSize.y, originalSize.z * newSize.z);
}
else
{
//Debug.Log("set target size " + targetSize);
targetSize = newSize;
}
if (squashMode == SquashMode.linear || squashMode == SquashMode.addition)
{
timeElapsed = 0;
startSize = transform.localScale;
}
}
//returns to original size once it is done
public void customSquish(Vector3 newSize, float duration, bool useRealitive = false)
{
StartCoroutine(SquishTimer(newSize, duration, useRealitive));
}
//resets back to the original size
public void ResetScale()
{
targetSize = originalSize;
}
//couroutine used
IEnumerator SquashTimer(float duration)
{
SetToSquash();
yield return new WaitForSeconds(duration);
ResetScale();
}
IEnumerator StretchTimer(float duration)
{
SetToStretch();
yield return new WaitForSeconds(duration);
ResetScale();
}
IEnumerator SquishTimer(Vector3 newSize, float duration, bool useRealitive)
{
customSquish(newSize, useRealitive);
yield return new WaitForSeconds(duration);
ResetScale();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c6f09ae9992d5484ba1b730e07b37a5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,60 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Lemon.GenericLib.Generics;
namespace Lemon.GenericLib.VFX
{
public class SquashTimer : MonoBehaviour
{
[SerializeField] float interval = 1.5f;
[SerializeField] SquashAndStretch sns;
public bool interupt = false;
TickCounter tick = new TickCounter();
private bool isSquash = false;
// Start is called before the first frame update
void Start()
{
tick.addAction(SquashingCycle);
}
// Update is called once per frame
void Update()
{
tick.AdvanceTick();
}
void SquashingCycle()
{
if (isSquash)
{
if (!interupt) sns.SetToSquash();
isSquash = false;
}
else
{
if (!interupt) sns.SetToStretch();
isSquash = true;
}
}
public void InteruptTimer(float duration)
{
StartCoroutine(InteruptTimerCooutine(duration));
}
IEnumerator InteruptTimerCooutine(float duration)
{
interupt = true;
yield return new WaitForSeconds(duration);
interupt = false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 116b225e4135df94088980a52d42678f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,69 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
//namespace Lemon.GenericLib.VFX
//{
public class VFX_Manager : MonoBehaviour
{
public static VFX_Manager insatnceVFXM;
private void Awake()
{
if (insatnceVFXM == null)
{
insatnceVFXM = this;
}
if (insatnceVFXM != this)
{
Destroy(gameObject);
}
}
[SerializeField] vfxData[] allVFXData;
private Dictionary<string, vfxData> vfxDictionary;
[Serializable]
struct vfxData
{
public string vfxName;
public GameObject vfxObject;
public bool shouldKill;
public float lifeTime;
}
private void Start()
{
vfxDictionary = new Dictionary<string, vfxData>();
foreach (var item in allVFXData)
{
vfxDictionary.Add(item.vfxName, item);
}
}
public GameObject spawnVFX(string vfxname, Vector3 position)
{
if (vfxDictionary.ContainsKey(vfxname))
{
GameObject newVFX = Instantiate(vfxDictionary[vfxname].vfxObject, position, Quaternion.identity);
if (vfxDictionary[vfxname].shouldKill)
{
Destroy(newVFX, vfxDictionary[vfxname].lifeTime);
}
return newVFX;
}
else
{
Debug.LogError($"vfx with name {vfxname} does not exist.\nPlease check if the spelling is correct.");
return null;
}
}
}
//}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a8703975ea06f84e94a7026a3dd532e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: