added some stuff
This commit is contained in:
parent
9b69003715
commit
3dbf2f9010
520 changed files with 176780 additions and 2 deletions
8
Assets/Scripts/LemonGenericLib/Audio.meta
Normal file
8
Assets/Scripts/LemonGenericLib/Audio.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c6a08cabe03c2464a93d39c1ce56b251
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
530
Assets/Scripts/LemonGenericLib/Audio/AudioManager2D.cs
Normal file
530
Assets/Scripts/LemonGenericLib/Audio/AudioManager2D.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
|
11
Assets/Scripts/LemonGenericLib/Audio/AudioManager2D.cs.meta
Normal file
11
Assets/Scripts/LemonGenericLib/Audio/AudioManager2D.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 74d11a8e609d32b4bb6702a8c6852f83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
18
Assets/Scripts/LemonGenericLib/Audio/PlayAudioScript.cs
Normal file
18
Assets/Scripts/LemonGenericLib/Audio/PlayAudioScript.cs
Normal 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);
|
||||
}
|
||||
}
|
11
Assets/Scripts/LemonGenericLib/Audio/PlayAudioScript.cs.meta
Normal file
11
Assets/Scripts/LemonGenericLib/Audio/PlayAudioScript.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7b631eb531e35d048ad89374962e76b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/DebugUtilities.meta
Normal file
8
Assets/Scripts/LemonGenericLib/DebugUtilities.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 454ba7a3e1c051a468ce9379c33f09c9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5dfb25ba3ec4f3b4c9842d81ea238e56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 69302d519e9f40c4fa9c50e9bb87f438
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 85106e56a76d0094b8198233c973020e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c58e5fe732daf0144af01eba42dfda38
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/DialogueSystem.meta
Normal file
8
Assets/Scripts/LemonGenericLib/DialogueSystem.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 34132cdda7a2a184dbdc84bb76b5224c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
404
Assets/Scripts/LemonGenericLib/DialogueSystem/DialogueSystem.cs
Normal file
404
Assets/Scripts/LemonGenericLib/DialogueSystem/DialogueSystem.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 98352efe069658d4caae5443f470f550
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/Generic Classes.meta
Normal file
8
Assets/Scripts/LemonGenericLib/Generic Classes.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1501d425c1bfa664ba75c3d7d4236d87
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/Generic Classes/Grid.meta
Normal file
8
Assets/Scripts/LemonGenericLib/Generic Classes/Grid.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7a233e2e3bb5afd40b770f197760dbc4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
454
Assets/Scripts/LemonGenericLib/Generic Classes/Grid/GridClass.cs
Normal file
454
Assets/Scripts/LemonGenericLib/Generic Classes/Grid/GridClass.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 67f78fc7678d30c41a2a7d560cf4bda9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e422af2af72481844b3dc6e0cd0d8c71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
31
Assets/Scripts/LemonGenericLib/Generic Classes/Optional.cs
Normal file
31
Assets/Scripts/LemonGenericLib/Generic Classes/Optional.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b4d1b9d247f954f4e93b1308c11cccb3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 14acffb5acb0f2345a99c54b6fe45e89
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
78
Assets/Scripts/LemonGenericLib/LemonCodeUtilities.cs
Normal file
78
Assets/Scripts/LemonGenericLib/LemonCodeUtilities.cs
Normal 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 + " ]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
11
Assets/Scripts/LemonGenericLib/LemonCodeUtilities.cs.meta
Normal file
11
Assets/Scripts/LemonGenericLib/LemonCodeUtilities.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 62610c7ce1754534b8224dad77ba905f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/SceneManagement.meta
Normal file
8
Assets/Scripts/LemonGenericLib/SceneManagement.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e5204d5bab5b4a94ca008991c6328ffe
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 76ad778d7bf1bbc41bacdfd410da4a84
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cdf26c62e5d4b2d4490ef743edfbe89b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/Scoring System.meta
Normal file
8
Assets/Scripts/LemonGenericLib/Scoring System.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4954d2b52f51a3d44bc052acbe51c81c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
72
Assets/Scripts/LemonGenericLib/Scoring System/ScoreKeeper.cs
Normal file
72
Assets/Scripts/LemonGenericLib/Scoring System/ScoreKeeper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70caaedb4a6576a4fbb4a7f78ecc4605
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/UI.meta
Normal file
8
Assets/Scripts/LemonGenericLib/UI.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c2eff9b9eb3fb8b49b67c10a697cd927
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/UI/QuickUIManagers.meta
Normal file
8
Assets/Scripts/LemonGenericLib/UI/QuickUIManagers.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 12d0daac2445aa64b89b3cd4c8e6bc59
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e6113c552c6f9e94190849ea5044d042
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 454e8a3504cc8734c861860dfef3875f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/UI/Tabs.meta
Normal file
8
Assets/Scripts/LemonGenericLib/UI/Tabs.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d8a913671c0abc9459f3e8a14d2cc066
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
67
Assets/Scripts/LemonGenericLib/UI/Tabs/TabButtonScript.cs
Normal file
67
Assets/Scripts/LemonGenericLib/UI/Tabs/TabButtonScript.cs
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ccb3057007dfb1541810d434b448bcc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
123
Assets/Scripts/LemonGenericLib/UI/Tabs/TabGroup.cs
Normal file
123
Assets/Scripts/LemonGenericLib/UI/Tabs/TabGroup.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/LemonGenericLib/UI/Tabs/TabGroup.cs.meta
Normal file
11
Assets/Scripts/LemonGenericLib/UI/Tabs/TabGroup.cs.meta
Normal file
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0206a02701fc75c4eb1f54e3113fd697
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/LemonGenericLib/Visual Effects.meta
Normal file
8
Assets/Scripts/LemonGenericLib/Visual Effects.meta
Normal file
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 09ee81d16d5d9e642a895942382537d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: eb19143cd46ff7641a1522d7318b29dd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 14b9658d15552084d841ba0dd6a818ba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9fb2c212857fc924cb0ce6c1e6fbd4a2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 171af91b161e0b644b33be9f2fae0831
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
77
Assets/Scripts/LemonGenericLib/Visual Effects/Popup_Text.cs
Normal file
77
Assets/Scripts/LemonGenericLib/Visual Effects/Popup_Text.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e358931fe625ddc46a3f28d6d716833b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2343e432efd75d94a9261bbeed7a17b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c233fa6ef7660324c9ded9a1e63c1836
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4dfb673b5ecacd542ad64f5665b1e237
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ee76a7080bc41504ca743d99f8842420
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c6f09ae9992d5484ba1b730e07b37a5b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
60
Assets/Scripts/LemonGenericLib/Visual Effects/SquashTimer.cs
Normal file
60
Assets/Scripts/LemonGenericLib/Visual Effects/SquashTimer.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 116b225e4135df94088980a52d42678f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
69
Assets/Scripts/LemonGenericLib/Visual Effects/VFX_Manager.cs
Normal file
69
Assets/Scripts/LemonGenericLib/Visual Effects/VFX_Manager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2a8703975ea06f84e94a7026a3dd532e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue