Skip to content

Instantly share code, notes, and snippets.

@FNGgames
Created December 17, 2023 20:19
Show Gist options
  • Save FNGgames/ee74e6259a038d479fc7c7d33783471d to your computer and use it in GitHub Desktop.
Save FNGgames/ee74e6259a038d479fc7c7d33783471d to your computer and use it in GitHub Desktop.
DOTween Extensions
namespace SpiralCircus.DOTween
{
using DG.Tweening;
using SpiralCircus.Mathematics;
using UnityEngine.Rendering.Universal;
public static class DOTweenLight2DExtension
{
public static Tween DOIntensity(this Light2D light, float endValue, float duration)
=> DOTween.To(() => light.intensity, t => light.intensity = t, endValue, duration);
public static Tween DORange(this Light2D light, float innerTarget, float outerTarget, float duration)
{
var sequence = DOTween.Sequence();
sequence.Append(DOTween.To(() => light.pointLightInnerRadius, x => light.pointLightInnerRadius = x, innerTarget,
duration));
sequence.Join(DOTween.To(() => light.pointLightOuterRadius, x => light.pointLightOuterRadius = x, outerTarget,
duration));
return sequence;
}
public static Tween DOFlash(this Light2D light, float frequency, float repeats, float intensity)
{
var duration = repeats / frequency;
return DOVirtual.Float(0, duration, duration,
T => light.Flash(T, frequency, intensity));
}
private static void Flash(this Light2D light, float time, float frequency, float intensity)
=> light.intensity = 0.5f * intensity * -(Maths.Cos(time * frequency * 2 * Maths.PI) - 1);
}
}
namespace SpiralCircus.DOTween
{
using DG.Tweening;
using UnityEngine;
public static class DOTweenParticleSystemExtension
{
public static Tween DOEmissionRateMultiplier(this ParticleSystem particleSystem, float endValue, float duration)
{
var emission = particleSystem.emission;
return DOTween.Sequence()
.Append(DOTween.To(() => emission.rateOverDistanceMultiplier, x => emission.rateOverDistanceMultiplier = x,
endValue, duration)).Join(DOTween.To(() => emission.rateOverTimeMultiplier,
x => emission.rateOverTimeMultiplier = x, endValue, duration));
}
public static Tween DOStartSpeedMultiplier(this ParticleSystem particleSystem, float endValue, float duration)
{
var main = particleSystem.main;
return DOTween.To(() => main.startSpeedMultiplier, x => main.startSpeedMultiplier = x, endValue, duration);
}
public static Tween DOStartSizeMultiplier(this ParticleSystem particleSystem, float endValue, float duration)
{
var main = particleSystem.main;
return DOTween.To(() => main.startSizeMultiplier, x => main.startSizeMultiplier = x, endValue, duration);
}
public static Tween DOStartLifetimeMultipler(this ParticleSystem particleSystem, float endValue, float duration)
{
var main = particleSystem.main;
return DOTween.To(() => main.startLifetimeMultiplier, x => main.startLifetimeMultiplier = x, endValue,
duration);
}
}
}
namespace SpiralCircus.DOTween
{
using DG.Tweening;
using UnityEngine;
public static class DOTweenShaderExtension
{
public static Tween DOGlobalFloat(int propertyId, float endValue, float duration) => DOTween.To(
() => Shader.GetGlobalFloat(propertyId), x => Shader.SetGlobalFloat(propertyId, x), endValue, duration);
public static Tween DOGlobalFloat(string propertyName, float endValue, float duration)
=> DOGlobalFloat(Shader.PropertyToID(propertyName), endValue, duration);
}
}
namespace SpiralCircus.DOTween
{
using DG.Tweening;
using global::Spine;
using global::Spine.Unity;
public static class DOTweenSpineAnimationExtension
{
public static Tween DOTimeScale(this TrackEntry track, float endValue, float duration)
=> DOTween.To(() => track.TimeScale, t => track.TimeScale = t, endValue, duration);
public static Tween DOAlpha(this TrackEntry track, float endValue, float duration)
=> DOTween.To(() => track.Alpha, t => track.Alpha = t, endValue, duration);
public static Tween DOTrackTime(this TrackEntry track, float endValue, float duration)
=> DOTween.To(() => track.TrackTime, t => track.TrackTime = t, endValue, duration);
public static Tween DOOverrideAlpha(this SkeletonUtilityBone bone, float endValue, float duration)
=> DOTween.To(() => bone.overrideAlpha, x => bone.overrideAlpha = x, endValue, duration);
}
}
namespace SpiralCircus.DOTween
{
using System;
using DG.Tweening;
using SpiralCircus.Mathematics;
using SpiralCircus.Unity;
using UnityEngine;
// ReSharper disable InconsistentNaming
public static class DOTweenTMPExtension
{
// Static init
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
private static void IncreaseTweenCapacity() => DOTween.SetTweensCapacity(500, 50);
// Text Crawler
public static Tween DOCrawl(this DOTweenTMPAnimator animator, float letterInterval, float fadeDuration,
float scaleDuration, bool reverseOrder = false)
{
var sequence = DOTween.Sequence();
sequence.AppendInterval(0.1f);
var startIndex = reverseOrder ? animator.textInfo.characterCount - 1 : 0;
Func<float, bool> condition = reverseOrder ? i => i >= 0 : i => i < animator.textInfo.characterCount;
var increment = reverseOrder ? -1 : 1;
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
sequence.Insert(0, animator.DOFadeChar(i, 0, Time.deltaTime));
sequence.Insert(0, animator.DOScaleChar(i, .5f, Time.deltaTime));
}
var j = 1;
for (var i = startIndex; condition(i); i += increment)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
sequence.Insert(j * letterInterval, animator.DOFadeChar(i, 1, fadeDuration));
sequence.Insert(j * letterInterval, animator.DOScaleChar(i, 1, scaleDuration));
j++;
}
return sequence;
}
// Roll Scale
public static Tween DORollScale(this DOTweenTMPAnimator animator, float duration, float interval, float minSize, float maxSize)
{
var sequence = DOTween.Sequence();
var j = 0;
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
sequence
.Insert(j * interval, animator.DOScaleChar(i, minSize, duration))
.Insert(j * interval + duration, animator.DOScaleChar(i, maxSize, duration));
j++;
}
return sequence;
}
// SHORTCUTS
public static Tween DOResetScale(this DOTweenTMPAnimator animator, float duration)
{
var sequence = DOTween.Sequence();
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
sequence.Insert(0, animator.DOScaleChar(i, 1, duration));
}
return sequence;
}
public static DOTweenTMPAnimator SetAllCharsAlpha(this DOTweenTMPAnimator animator, float alpha)
{
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
var color = animator.GetCharColor(i);
color.a = alpha;
animator.SetCharColor(i, color);
}
return animator;
}
public static DOTweenTMPAnimator SetCharAlpha(this DOTweenTMPAnimator animator, int index, float alpha)
{
var color = animator.GetCharColor(index);
color.a = alpha;
animator.SetCharColor(index, color);
return animator;
}
public static DOTweenTMPAnimator SetAllCharOffsets(this DOTweenTMPAnimator animator, Vector2 offset)
{
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
animator.SetCharOffset(i, offset);
}
return animator;
}
public static DOTweenTMPAnimator SetAllCharScales(this DOTweenTMPAnimator animator, float scale)
{
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
animator.SetCharScale(i, Vector3.one * scale);
}
return animator;
}
public static void WobbleChars(this DOTweenTMPAnimator animator, Vector2 sinAmplitude, Vector2 sinFrequency)
{
for (var i = 0; i < animator.textInfo.characterCount; i++)
{
if (!animator.textInfo.characterInfo[i].isVisible) continue;
var times = sinFrequency * ((Time.timeSinceLevelLoad + i) * 2 * Maths.PI);
var offset = sinAmplitude * new Vector2(Maths.Sin(times.x), Maths.Sin(times.y));
animator.SetCharOffset(i, offset.ToVector3());
}
}
}
}
namespace SpiralCircus.DOTween
{
using DG.Tweening;
using SpiralCircus.Unity.BezierCurves;
using SpiralCircus.Unity.Mathematics;
using UnityEngine;
public static class DOTweenTransformExtension
{
// from any given starting position and rotation, tween smoothly toward a target's position and rotation
public static Tween DOMatchPositionAndRotation(this Transform root, Transform child, Transform target, float duration)
{
// cache position and rotation so their initial values are used in the closure
var pInitial = root.position;
var qInitial = root.rotation;
return DOVirtual.Float(0, 1, duration,
t => PositionAndRotationTween(t, pInitial, qInitial, root, child, target));
}
private static void PositionAndRotationTween(float t, Vector3 pInitial, Quaternion qInitial, Transform root, Transform child, Transform target)
{
// find delta rotation between current child rotation and current target rotation
var dQ = target.rotation * Quaternion.Inverse(child.rotation);
// add this to the current root rotation
var qTarget = dQ * root.rotation;
// spherically interpolate between the cached initial rotation and the current target rotation by the tween parameter
root.rotation = Quaternion.Slerp(qInitial, qTarget, t);
// find the delta position between the current child position and current target position
var dP = target.position - child.position;
// add the delta to the current root position
var pTarget = dP + root.position;
// linearly interpolate between the cached initial position and the current target position by the tween parameter
root.position = Vector3.Lerp(pInitial, pTarget, t);
}
// Move a transform along a bezier segment
public static Tween DOCubicBezier(this Transform transform, float duration, Vector2 p0, Vector2 p1, Vector2 p2,
Vector2 p3) => DOVirtual.Float(0, 1, duration, t => BezierTween(transform, t, p0, p1, p2, p3));
private static void BezierTween(Transform transform, float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
var pos = CubicBezier.FindPosition(p0, p1, p2, p3, t);
var dir = CubicBezier.FindTangent(p0, p1, p2, p3, t);
transform.position = pos;
transform.rotation = Quaternion.LookRotation(dir, transform.up);
}
// Move a transform along a bezier path
public static Tween DOCubicBezierCurve(this Transform transform, CubicBezierCurve curve, float duration)
=> DOVirtual.Float(0, 1, duration, t => BezierPathTween(t, transform, curve));
private static void BezierPathTween(float t, Transform transform, CubicBezierCurve curve)
{
var point = curve.FindPointParametric(t);
transform.position = point.Position;
transform.rotation = point.Tangent.ToRotation();
}
// Move a transform along a bezier path
public static Tween DOCubicBezier(this Transform transform, Transform target, float startHandle,
float endHandle, float duration)
=> DOVirtual.Float(0, 1, duration, t => BezierTween(transform, target, startHandle, endHandle, t));
private static void BezierTween(Transform transform, Transform target, float startHandle, float endHandle,
float t)
{
var p0 = transform.position;
var p1 = p0 + transform.right * startHandle;
var p3 = target.position;
var p2 = p3 - target.right * endHandle;
var pos = CubicBezier.FindPosition(p0, p1, p2, p3, t);
var dir = CubicBezier.FindTangent(p0, p1, p2, p3, t);
transform.position = pos;
transform.rotation = Quaternion.LookRotation(dir, transform.up);
}
// dynamic move
public static Tween DOMoveToTarget(this Transform transform, Transform target, float duration)
=> DOVirtual.Float(0, 1, duration, t => DynamicMoveTween(transform, target, transform.position, t));
private static void DynamicMoveTween(Transform transform, Transform target, Vector3 originalPosition, float t)
=> transform.position = Vector3.Lerp(originalPosition, target.position, t);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment