Add focused word scale-down and smooth camera shake + unfocus words scribble
This commit is contained in:
+74
-5
@@ -57,18 +57,23 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
private int _originalSortingOrder;
|
||||
private Vector3 _startLocalPos;
|
||||
private float _originalScale;
|
||||
private float _originalTextScale = 1f;
|
||||
private int _textScaleTweenId = -1;
|
||||
private bool _positionCaptured = false;
|
||||
|
||||
private Vector3 _shakeOffset = Vector3.zero;
|
||||
private Vector3 _shakeTarget = Vector3.zero;
|
||||
private float _shakeTimer = 0f;
|
||||
private bool _isShaking = false;
|
||||
private float _shakeSpeedMultiplier = 1f;
|
||||
|
||||
private bool _disableFloatingEffects = false;
|
||||
|
||||
private Queue<Vector3> _positionHistory = new Queue<Vector3>();
|
||||
private float _historyTimer = 0f;
|
||||
private const float HISTORY_SAMPLE_RATE = 0.016f;
|
||||
|
||||
private SketchFadeEffect _sketchFadeEffect;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
@@ -169,7 +174,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
if (!GetEnableOrganicShake())
|
||||
return;
|
||||
|
||||
_shakeTimer += Time.deltaTime * GetShakeSpeed();
|
||||
_shakeTimer += Time.deltaTime * GetShakeSpeed() * _shakeSpeedMultiplier;
|
||||
|
||||
if (_shakeTimer >= 1f)
|
||||
{
|
||||
@@ -204,6 +209,29 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
_shakeOffset = Vector3.zero;
|
||||
}
|
||||
|
||||
public void SetShakeSpeedMultiplier(float multiplier)
|
||||
{
|
||||
_shakeSpeedMultiplier = Mathf.Max(0f, multiplier);
|
||||
}
|
||||
|
||||
public void SetTextScale(float targetScale, float duration = 0.3f)
|
||||
{
|
||||
if (_choiceTextComponent == null)
|
||||
return;
|
||||
|
||||
if (_textScaleTweenId >= 0)
|
||||
LeanTween.cancel(_textScaleTweenId);
|
||||
|
||||
_textScaleTweenId = LeanTween.scale(_choiceTextComponent.gameObject, Vector3.one * targetScale, duration)
|
||||
.setEase(LeanTweenType.easeOutQuad)
|
||||
.id;
|
||||
}
|
||||
|
||||
public void ResetTextScale(float duration = 0.3f)
|
||||
{
|
||||
SetTextScale(_originalTextScale, duration);
|
||||
}
|
||||
|
||||
public void HideGhostTrail()
|
||||
{
|
||||
if (_ghostTextComponent != null)
|
||||
@@ -230,6 +258,11 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
|
||||
LeanTween.cancel(gameObject);
|
||||
StopOrganicShake();
|
||||
|
||||
DialogueAnimationSettings settings = GetAnimationSettings();
|
||||
float textScaleMultiplier = settings != null ? settings.FocusedTextScaleMultiplier : 0.9f;
|
||||
float textScaleDuration = settings != null ? settings.FocusedTextScaleDuration : 0.3f;
|
||||
SetTextScale(textScaleMultiplier, textScaleDuration);
|
||||
}
|
||||
|
||||
transform.localScale = Vector3.one * Mathf.Lerp(_originalScale, MAX_FOCUS_SCALE, progress);
|
||||
@@ -374,7 +407,10 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
}
|
||||
|
||||
_startLocalPos = transform.localPosition;
|
||||
_originalScale = transform.localScale.x;
|
||||
_originalScale = transform.localScale.x;
|
||||
|
||||
if (_choiceTextComponent != null)
|
||||
_originalTextScale = _choiceTextComponent.transform.localScale.x;
|
||||
|
||||
LeanTween.cancel(gameObject);
|
||||
|
||||
@@ -383,6 +419,13 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
if (_ghostTextComponent != null)
|
||||
_ghostTextComponent.text = GetChoiceText();
|
||||
|
||||
DialogueAnimationSettings settings = GetAnimationSettings();
|
||||
if (settings != null && settings.EnableSketchFadeOnFocus && settings.SketchMaterial != null)
|
||||
{
|
||||
_sketchFadeEffect = gameObject.AddComponent<SketchFadeEffect>();
|
||||
_sketchFadeEffect.Initialize(_choiceTextComponent, _ghostTextComponent, settings.SketchMaterial);
|
||||
}
|
||||
|
||||
StartOrganicShake();
|
||||
}
|
||||
|
||||
@@ -465,8 +508,14 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
/// </summary>
|
||||
public void ResetFeedback(float duration)
|
||||
{
|
||||
LeanTween.cancel(gameObject);
|
||||
LeanTween.cancel(gameObject);
|
||||
|
||||
if (_textScaleTweenId >= 0)
|
||||
LeanTween.cancel(_textScaleTweenId);
|
||||
|
||||
StopOrganicShake();
|
||||
|
||||
ResetSketchFade();
|
||||
|
||||
LeanTween.moveLocal(gameObject, _startLocalPos, duration)
|
||||
.setEase(LeanTweenType.easeOutQuad)
|
||||
@@ -479,10 +528,11 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
StartOrganicShake();
|
||||
});
|
||||
|
||||
transform.localScale = Vector3.one;
|
||||
|
||||
transform.localScale = Vector3.one * _originalScale;
|
||||
|
||||
if (_choiceTextComponent != null)
|
||||
{
|
||||
_choiceTextComponent.transform.localScale = Vector3.one * _originalTextScale;
|
||||
_choiceTextComponent.color = Color.white;
|
||||
|
||||
if (_ghostTextComponent != null)
|
||||
@@ -497,5 +547,24 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
if (_canvas != null)
|
||||
_canvas.sortingOrder = _originalSortingOrder;
|
||||
}
|
||||
|
||||
public void ApplySketchFade()
|
||||
{
|
||||
DialogueAnimationSettings settings = GetAnimationSettings();
|
||||
if (settings == null || !settings.EnableSketchFadeOnFocus || _sketchFadeEffect == null)
|
||||
return;
|
||||
|
||||
_sketchFadeEffect.PlaySketchFadeEffect(
|
||||
settings.SketchDuration,
|
||||
settings.FadeOutDuration,
|
||||
settings.FinalFadeAlpha
|
||||
);
|
||||
}
|
||||
|
||||
public void ResetSketchFade()
|
||||
{
|
||||
if (_sketchFadeEffect != null)
|
||||
_sketchFadeEffect.ResetEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -41,6 +41,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
public bool MoveTowardPlayerOnFocus;
|
||||
public float FocusDistanceFromPlayer;
|
||||
public bool DisableFloatingEffects;
|
||||
public float DefaultScaleMultiplier;
|
||||
}
|
||||
|
||||
private static SpawnConfig GetConfig(ObjectDescriptionSettings settings)
|
||||
@@ -68,7 +69,8 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
ShakeSmoothness = settings.ShakeSmoothness,
|
||||
MoveTowardPlayerOnFocus = false,
|
||||
FocusDistanceFromPlayer = 1f,
|
||||
DisableFloatingEffects = true
|
||||
DisableFloatingEffects = true,
|
||||
DefaultScaleMultiplier = 1f
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,7 +99,8 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
ShakeSmoothness = settings.ShakeSmoothness,
|
||||
MoveTowardPlayerOnFocus = settings.MoveTowardPlayerOnFocus,
|
||||
FocusDistanceFromPlayer = settings.FocusDistanceFromPlayer,
|
||||
DisableFloatingEffects = false
|
||||
DisableFloatingEffects = false,
|
||||
DefaultScaleMultiplier = settings.DefaultScaleMultiplier
|
||||
};
|
||||
}
|
||||
|
||||
@@ -145,6 +148,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
ChoiceFocusHandler word = Object.Instantiate(wordPrefab, parent);
|
||||
word.transform.localPosition = localOffset;
|
||||
word.transform.localRotation = Quaternion.identity;
|
||||
word.transform.localScale = Vector3.one * config.DefaultScaleMultiplier;
|
||||
|
||||
CanvasGroup canvasGroup = word.GetComponent<CanvasGroup>();
|
||||
if (canvasGroup == null)
|
||||
@@ -170,6 +174,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
ChoiceFocusHandler word = Object.Instantiate(prefab, parent);
|
||||
word.transform.localPosition = Vector3.up * i * 50f;
|
||||
word.transform.localRotation = Quaternion.identity;
|
||||
word.transform.localScale = Vector3.one * config.DefaultScaleMultiplier;
|
||||
word.Setup(choices[i], config);
|
||||
words.Add(word);
|
||||
}
|
||||
@@ -188,6 +193,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
Vector3 offset = playerForward * 2f + Vector3.up * (i - choices.Count / 2f) * (config.SpawnRadius / choices.Count / 100f);
|
||||
word.transform.position = Player.Instance.transform.position + offset;
|
||||
word.transform.LookAt(Player.Instance.transform);
|
||||
word.transform.localScale = Vector3.one * config.DefaultScaleMultiplier;
|
||||
word.Setup(choices[i], config);
|
||||
words.Add(word);
|
||||
}
|
||||
@@ -213,6 +219,7 @@ namespace Unheimlich.Interactions.FloatingWords
|
||||
ChoiceFocusHandler word = Object.Instantiate(prefab, parent);
|
||||
word.transform.localPosition = localOffset;
|
||||
word.transform.LookAt(Player.Instance.transform);
|
||||
word.transform.localScale = Vector3.one * config.DefaultScaleMultiplier;
|
||||
word.Setup(choices[i], config);
|
||||
words.Add(word);
|
||||
}
|
||||
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
namespace Unheimlich.Interactions.FloatingWords
|
||||
{
|
||||
public class SketchFadeEffect : MonoBehaviour
|
||||
{
|
||||
private TextMeshProUGUI _textComponent;
|
||||
private TextMeshProUGUI _ghostTextComponent;
|
||||
private Image _scribbleOverlay;
|
||||
private Material _scribbleMaterialInstance;
|
||||
private Material _scribbleMaterialTemplate;
|
||||
|
||||
private static readonly int ProgressID = Shader.PropertyToID("_Progress");
|
||||
|
||||
private bool _isEffectActive = false;
|
||||
private bool _overlayCreated = false;
|
||||
private Color _originalTextColor;
|
||||
private Color _originalGhostColor;
|
||||
|
||||
private int _scribbleTweenId = -1;
|
||||
private int _fadeTweenId = -1;
|
||||
|
||||
public void Initialize(TextMeshProUGUI textComponent, TextMeshProUGUI ghostComponent, Material scribbleMaterial)
|
||||
{
|
||||
_textComponent = textComponent;
|
||||
_ghostTextComponent = ghostComponent;
|
||||
_scribbleMaterialTemplate = scribbleMaterial;
|
||||
_originalTextColor = _textComponent.color;
|
||||
|
||||
if (_ghostTextComponent != null)
|
||||
_originalGhostColor = _ghostTextComponent.color;
|
||||
}
|
||||
|
||||
private void CreateScribbleOverlay()
|
||||
{
|
||||
if (_overlayCreated || _scribbleMaterialTemplate == null || _textComponent == null)
|
||||
return;
|
||||
|
||||
GameObject overlayObject = new GameObject("ScribbleOverlay");
|
||||
overlayObject.transform.SetParent(_textComponent.transform, false);
|
||||
|
||||
_scribbleOverlay = overlayObject.AddComponent<Image>();
|
||||
_scribbleOverlay.raycastTarget = false;
|
||||
|
||||
RectTransform overlayRect = overlayObject.GetComponent<RectTransform>();
|
||||
RectTransform textRect = _textComponent.GetComponent<RectTransform>();
|
||||
|
||||
_textComponent.ForceMeshUpdate();
|
||||
|
||||
Vector2 textSize = _textComponent.GetRenderedValues(false);
|
||||
|
||||
float horizontalPadding = 1.2f;
|
||||
float verticalPadding = 0.8f;
|
||||
Vector2 paddedSize = new Vector2(
|
||||
textSize.x + horizontalPadding,
|
||||
textSize.y + verticalPadding
|
||||
);
|
||||
|
||||
overlayRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
overlayRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
overlayRect.pivot = new Vector2(0.5f, 0.5f);
|
||||
|
||||
float leftOffset = -horizontalPadding * 0.9f;
|
||||
overlayRect.anchoredPosition = new Vector2(leftOffset, 0f);
|
||||
overlayRect.sizeDelta = paddedSize;
|
||||
|
||||
overlayRect.localScale = Vector3.one;
|
||||
|
||||
_scribbleMaterialInstance = new Material(_scribbleMaterialTemplate);
|
||||
_scribbleMaterialInstance.SetFloat(ProgressID, 0f);
|
||||
_scribbleOverlay.material = _scribbleMaterialInstance;
|
||||
|
||||
_scribbleOverlay.gameObject.SetActive(false);
|
||||
|
||||
_overlayCreated = true;
|
||||
}
|
||||
|
||||
public void PlaySketchFadeEffect(float scribbleDuration, float fadeDuration, float finalAlpha)
|
||||
{
|
||||
if (_isEffectActive || _textComponent == null)
|
||||
return;
|
||||
|
||||
CancelActiveTweens();
|
||||
|
||||
CreateScribbleOverlay();
|
||||
|
||||
if (_scribbleOverlay == null || _scribbleMaterialInstance == null)
|
||||
return;
|
||||
|
||||
_scribbleOverlay.gameObject.SetActive(true);
|
||||
|
||||
_isEffectActive = true;
|
||||
|
||||
_scribbleTweenId = LeanTween.value(gameObject, 0f, 1f, scribbleDuration)
|
||||
.setEase(LeanTweenType.easeInOutQuad)
|
||||
.setOnUpdate((float val) => {
|
||||
if (_scribbleMaterialInstance != null)
|
||||
_scribbleMaterialInstance.SetFloat(ProgressID, val);
|
||||
})
|
||||
.setOnComplete(() => {
|
||||
_scribbleTweenId = -1;
|
||||
_fadeTweenId = LeanTween.value(gameObject, _originalTextColor.a, finalAlpha, fadeDuration)
|
||||
.setEase(LeanTweenType.easeInQuad)
|
||||
.setOnUpdate((float val) => {
|
||||
if (_textComponent != null)
|
||||
{
|
||||
Color textColor = _textComponent.color;
|
||||
textColor.a = val;
|
||||
_textComponent.color = textColor;
|
||||
}
|
||||
|
||||
if (_ghostTextComponent != null)
|
||||
{
|
||||
Color ghostColor = _ghostTextComponent.color;
|
||||
ghostColor.a = val * (_originalGhostColor.a / _originalTextColor.a);
|
||||
_ghostTextComponent.color = ghostColor;
|
||||
}
|
||||
|
||||
if (_scribbleOverlay != null)
|
||||
{
|
||||
Color scribbleColor = _scribbleOverlay.color;
|
||||
scribbleColor.a = val;
|
||||
_scribbleOverlay.color = scribbleColor;
|
||||
}
|
||||
})
|
||||
.setOnComplete(() => {
|
||||
_fadeTweenId = -1;
|
||||
}).id;
|
||||
}).id;
|
||||
}
|
||||
|
||||
public void ResetEffect()
|
||||
{
|
||||
CancelActiveTweens();
|
||||
|
||||
if (_scribbleMaterialInstance != null)
|
||||
{
|
||||
float currentProgress = _scribbleMaterialInstance.GetFloat(ProgressID);
|
||||
|
||||
if (currentProgress > 0f)
|
||||
{
|
||||
_scribbleTweenId = LeanTween.value(gameObject, currentProgress, 0f, 0.3f)
|
||||
.setEase(LeanTweenType.easeOutQuad)
|
||||
.setOnUpdate((float val) => {
|
||||
if (_scribbleMaterialInstance != null)
|
||||
_scribbleMaterialInstance.SetFloat(ProgressID, val);
|
||||
})
|
||||
.setOnComplete(() => {
|
||||
_scribbleTweenId = -1;
|
||||
if (_scribbleOverlay != null)
|
||||
_scribbleOverlay.gameObject.SetActive(false);
|
||||
}).id;
|
||||
}
|
||||
}
|
||||
|
||||
if (_textComponent != null)
|
||||
{
|
||||
float currentAlpha = _textComponent.color.a;
|
||||
|
||||
if (currentAlpha < _originalTextColor.a)
|
||||
{
|
||||
_fadeTweenId = LeanTween.value(gameObject, currentAlpha, _originalTextColor.a, 0.3f)
|
||||
.setEase(LeanTweenType.easeOutQuad)
|
||||
.setOnUpdate((float val) => {
|
||||
if (_textComponent != null)
|
||||
{
|
||||
Color c = _textComponent.color;
|
||||
c.a = val;
|
||||
_textComponent.color = c;
|
||||
}
|
||||
|
||||
if (_ghostTextComponent != null)
|
||||
{
|
||||
Color c = _ghostTextComponent.color;
|
||||
c.a = val * (_originalGhostColor.a / _originalTextColor.a);
|
||||
_ghostTextComponent.color = c;
|
||||
}
|
||||
})
|
||||
.setOnComplete(() => {
|
||||
_fadeTweenId = -1;
|
||||
}).id;
|
||||
}
|
||||
}
|
||||
|
||||
if (_scribbleOverlay != null)
|
||||
{
|
||||
Color c = _scribbleOverlay.color;
|
||||
c.a = 1f;
|
||||
_scribbleOverlay.color = c;
|
||||
}
|
||||
|
||||
_isEffectActive = false;
|
||||
}
|
||||
|
||||
private void CancelActiveTweens()
|
||||
{
|
||||
if (_scribbleTweenId != -1)
|
||||
{
|
||||
LeanTween.cancel(_scribbleTweenId);
|
||||
_scribbleTweenId = -1;
|
||||
}
|
||||
|
||||
if (_fadeTweenId != -1)
|
||||
{
|
||||
LeanTween.cancel(_fadeTweenId);
|
||||
_fadeTweenId = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CancelActiveTweens();
|
||||
|
||||
if (_scribbleMaterialInstance != null)
|
||||
Destroy(_scribbleMaterialInstance);
|
||||
|
||||
if (_scribbleOverlay != null)
|
||||
Destroy(_scribbleOverlay.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ee81e39cd832e34d9219099af39f4bb
|
||||
Reference in New Issue
Block a user