Skip to content

Commit 5e54720

Browse files
authored
feat: sdk tween 'continuous' modes (#5641)
* Implemented support for the 3 new "continuous" modes of the PBTween component * Reimplemented all the Tween component test coverage + added test coverage for the new modes.
1 parent bb1d537 commit 5e54720

File tree

13 files changed

+1587
-287
lines changed

13 files changed

+1587
-287
lines changed

Explorer/Assets/DCL/Infrastructure/CrdtEcsBridge/Components/ResetExtensions/PrimitivesConversionExtensions.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using UnityEngine;
33
using Quaternion = UnityEngine.Quaternion;
44
using Vector3 = UnityEngine.Vector3;
5+
using Vector2 = UnityEngine.Vector2;
56

67
namespace CrdtEcsBridge.Components.Conversion
78
{
@@ -10,7 +11,7 @@ namespace CrdtEcsBridge.Components.Conversion
1011
/// </summary>
1112
public static class PrimitivesConversionExtensions
1213
{
13-
public static Vector3 PBVectorToUnityVector(Decentraland.Common.Vector3 protoVector) =>
14+
public static Vector3 ToUnityVector(this Decentraland.Common.Vector3 protoVector) =>
1415
new ()
1516
{
1617
x = protoVector.X,
@@ -26,7 +27,7 @@ public static Decentraland.Common.Vector3 ToProtoVector(this Vector3 unityVector
2627
Z = unityVector.z,
2728
};
2829

29-
public static Quaternion PBQuaternionToUnityQuaternion(Decentraland.Common.Quaternion protoQuaternion) =>
30+
public static Quaternion ToUnityQuaternion(this Decentraland.Common.Quaternion protoQuaternion) =>
3031
new ()
3132
{
3233
x = protoQuaternion.X,
@@ -35,6 +36,13 @@ public static Quaternion PBQuaternionToUnityQuaternion(Decentraland.Common.Quate
3536
w = protoQuaternion.W,
3637
};
3738

39+
public static Vector2 ToUnityVector(this Decentraland.Common.Vector2 protoVector) =>
40+
new ()
41+
{
42+
x = protoVector.X,
43+
y = protoVector.Y,
44+
};
45+
3846
public static Decentraland.Common.Quaternion ToProtoQuaternion(this Quaternion unityQuaternion) =>
3947
new ()
4048
{
@@ -44,7 +52,7 @@ public static Decentraland.Common.Quaternion ToProtoQuaternion(this Quaternion u
4452
W = unityQuaternion.w,
4553
};
4654

47-
public static Color PBColorToUnityColor(Color3 protoColor, float alphaValue = 1) =>
55+
public static Color ToUnityColor(this Color3 protoColor, float alphaValue = 1) =>
4856
new ()
4957
{
5058
r = protoColor.R,
@@ -53,7 +61,7 @@ public static Color PBColorToUnityColor(Color3 protoColor, float alphaValue = 1)
5361
a = alphaValue,
5462
};
5563

56-
public static Color PBColorToUnityColor(Color4 protoColor) =>
64+
public static Color ToUnityColor(this Color4 protoColor) =>
5765
new ()
5866
{
5967
r = protoColor.R,

Explorer/Assets/DCL/PluginSystem/World/TweenPlugin.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Arch.SystemGroups;
22
using DCL.ECSComponents;
33
using DCL.PluginSystem.World.Dependencies;
4-
using DCL.SDKComponents.Tween.Systems;
54
using ECS.LifeCycle;
65
using ECS.LifeCycle.Systems;
76
using System.Collections.Generic;

Explorer/Assets/DCL/SDKComponents/Tween/Components/CustomTweener/CustomTweener.cs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using DG.Tweening;
2-
using DG.Tweening.Core;
1+
using DCL.Diagnostics;
2+
using DG.Tweening;
33
using DG.Tweening.Plugins.Options;
4+
using System;
45

56
namespace DCL.SDKComponents.Tween.Components
67
{
@@ -11,7 +12,7 @@ public abstract class CustomTweener<T, TU> : ITweener
1112
private readonly TweenCallback onCompleteCallback;
1213

1314
private bool finished;
14-
private TweenerCore<T, T, TU> core;
15+
private DG.Tweening.Tween? core;
1516
private ITweener customTweenerImplementation;
1617

1718
public T CurrentValue { get; set; }
@@ -28,29 +29,51 @@ public void Initialize(T startValue, T endValue, float durationInSeconds)
2829
core = CreateTweener(startValue, endValue, durationInSeconds);
2930
}
3031

31-
protected abstract TweenerCore<T, T, TU> CreateTweener(T start, T end, float duration);
32+
protected abstract DG.Tweening.Tween CreateTweener(T start, T end, float duration);
33+
34+
public void InitializeContinuous(T startValue, T directionOrEnd, float speed)
35+
{
36+
core?.Kill();
37+
finished = false;
38+
core = CreateContinuousTweener(startValue, directionOrEnd, speed);
39+
}
40+
41+
protected virtual DG.Tweening.Tween CreateContinuousTweener(T start, T directionOrEnd, float speed)
42+
{
43+
ReportHub.LogError(ReportCategory.TWEEN, $"Continuous tweener is not supported for type {typeof(T).Name}");
44+
throw new NotSupportedException($"Continuous tweener is not supported for type {typeof(T).Name}");
45+
}
3246

3347
public void Play() =>
34-
core.Play();
48+
core?.Play();
3549

3650
public void Pause() =>
37-
core.Pause();
51+
core?.Pause();
3852

3953
public void Rewind() =>
40-
core.Rewind();
54+
core?.Rewind();
55+
56+
public void Kill(bool complete)
57+
{
58+
core?.Kill(complete);
59+
finished = complete;
60+
}
4161

4262
public bool IsPaused() =>
43-
!core.IsPlaying();
63+
!core?.IsPlaying() ?? false;
4464

4565
public bool IsFinished() =>
4666
finished;
4767

4868
public bool IsActive() =>
49-
!core.IsPlaying() && !finished;
69+
!IsFinished() && (!core?.IsPlaying() ?? false);
70+
71+
public float GetElapsedTime() =>
72+
core?.Elapsed() ?? 0f;
5073

5174
public void DoTween(Ease ease, float tweenModelCurrentTime, bool isPlaying)
5275
{
53-
core.SetEase(ease).SetAutoKill(false).OnComplete(onCompleteCallback).Goto(tweenModelCurrentTime, isPlaying);
76+
core?.SetEase(ease).SetAutoKill(false).OnComplete(onCompleteCallback).Goto(tweenModelCurrentTime, isPlaying);
5477
}
5578

5679
private void OnTweenComplete()

Explorer/Assets/DCL/SDKComponents/Tween/Components/CustomTweener/CustomTweenerImpl.cs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,23 @@ public Vector3Tweener()
2020
private Vector3 GetCurrentValue() => CurrentValue;
2121
private void SetCurrentValue(Vector3 value) => CurrentValue = value;
2222

23-
protected sealed override TweenerCore<Vector3, Vector3, VectorOptions> CreateTweener(Vector3 start, Vector3 end, float duration)
23+
protected sealed override DG.Tweening.Tween CreateTweener(Vector3 start, Vector3 end, float duration)
2424
{
2525
CurrentValue = start;
2626
return DOTween.To(getValue, setValue, end, duration);
2727
}
28+
29+
protected override DG.Tweening.Tween CreateContinuousTweener(Vector3 start, Vector3 direction, float speed)
30+
{
31+
Vector3 dir = direction.normalized;
32+
float absSpeed = Mathf.Abs(speed);
33+
float sign = speed >= 0 ? 1f : -1f;
34+
35+
return DOVirtual.Float(0f, 1f, 1f, v =>
36+
{
37+
CurrentValue = start + dir * (sign * absSpeed * v);
38+
}).SetLoops(-1, LoopType.Incremental);
39+
}
2840
}
2941

3042
public class QuaternionTweener : CustomTweener<Quaternion, NoOptions>
@@ -41,11 +53,32 @@ public QuaternionTweener()
4153
private Quaternion GetCurrentValue() => CurrentValue;
4254
private void SetCurrentValue(Quaternion value) => CurrentValue = value;
4355

44-
protected override TweenerCore<Quaternion, Quaternion, NoOptions> CreateTweener(Quaternion start, Quaternion end, float duration)
56+
protected override DG.Tweening.Tween CreateTweener(Quaternion start, Quaternion end, float duration)
4557
{
4658
CurrentValue = start;
4759
return DOTween.To(PureQuaternionPlugin.Plug(), getValue, setValue, end, duration);
4860
}
61+
62+
protected override DG.Tweening.Tween CreateContinuousTweener(Quaternion start, Quaternion direction, float speed)
63+
{
64+
// Derive rotation axis from given orientation
65+
Vector3 axis = (direction * Vector3.up).normalized;
66+
if (axis.sqrMagnitude < 1e-6f)
67+
axis = Vector3.up;
68+
69+
float absSpeed = Mathf.Abs(speed);
70+
float secondsPerRevolution = 360f / Mathf.Max(absSpeed, 0.0001f);
71+
float sign = speed >= 0 ? 1f : -1f;
72+
73+
DG.Tweening.Tween t = DOVirtual.Float(
74+
0f,
75+
360f,
76+
secondsPerRevolution,
77+
v => { CurrentValue = Quaternion.AngleAxis(sign * v, axis) * start; }
78+
).SetLoops(-1, LoopType.Restart);
79+
80+
return t;
81+
}
4982
}
5083

5184
public class Vector2Tweener : CustomTweener<Vector2, VectorOptions>
@@ -62,10 +95,22 @@ public Vector2Tweener()
6295
private Vector2 GetCurrentValue() => CurrentValue;
6396
private void SetCurrentValue(Vector2 value) => CurrentValue = value;
6497

65-
protected sealed override TweenerCore<Vector2, Vector2, VectorOptions> CreateTweener(Vector2 start, Vector2 end, float duration)
98+
protected sealed override DG.Tweening.Tween CreateTweener(Vector2 start, Vector2 end, float duration)
6699
{
67100
CurrentValue = start;
68101
return DOTween.To(getValue, setValue, end, duration);
69102
}
103+
104+
protected override DG.Tweening.Tween CreateContinuousTweener(Vector2 start, Vector2 direction, float speed)
105+
{
106+
Vector2 dir = direction.normalized;
107+
float absSpeed = Mathf.Abs(speed);
108+
float sign = speed >= 0 ? 1f : -1f;
109+
110+
return DOVirtual.Float(0f, 1f, 1f, v =>
111+
{
112+
CurrentValue = start + dir * (sign * absSpeed * v);
113+
}).SetLoops(-1, LoopType.Incremental);
114+
}
70115
}
71116
}

Explorer/Assets/DCL/SDKComponents/Tween/Components/CustomTweener/ICustomTweener.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@ public interface ITweener
1212

1313
void Rewind();
1414

15+
void Kill(bool complete);
16+
1517
bool IsPaused();
1618

1719
bool IsFinished();
1820

1921
bool IsActive();
22+
23+
public float GetElapsedTime();
2024
}
2125
}

Explorer/Assets/DCL/SDKComponents/Tween/Components/CustomTweener/TweenerPool.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,24 @@ public class TweenerPool
1212
private readonly IObjectPool<QuaternionTweener> quaternionTweenerPool = new ObjectPool<QuaternionTweener>(() => new QuaternionTweener());
1313
private readonly IObjectPool<Vector2Tweener> vector2TweenerPool = new ObjectPool<Vector2Tweener>(() => new Vector2Tweener());
1414

15-
public ITweener GetTweener(PBTween pbTween, float durationInSeconds)
15+
public ITweener GetTweener(PBTween pbTween, float durationInSeconds, Transform? transform = null, Vector2? textureStart = null)
1616
{
1717
switch (pbTween.ModeCase)
1818
{
1919
case PBTween.ModeOneofCase.Move:
2020
return GetVector3Tweener(pbTween.Move.Start, pbTween.Move.End, durationInSeconds);
2121
case PBTween.ModeOneofCase.Rotate:
22-
// These conversions are needed because the Decentraland.Common.Quaternion type from the protobuf file
23-
// is not directly compatible with the UnityEngine.Quaternion
24-
Quaternion start = PrimitivesConversionExtensions.PBQuaternionToUnityQuaternion(pbTween.Rotate.Start);
25-
Quaternion end = PrimitivesConversionExtensions.PBQuaternionToUnityQuaternion(pbTween.Rotate.End);
26-
return GetQuaternionTweener(start, end, durationInSeconds);
22+
return GetQuaternionTweener(pbTween.Rotate.Start.ToUnityQuaternion(), pbTween.Rotate.End.ToUnityQuaternion(), durationInSeconds);
2723
case PBTween.ModeOneofCase.Scale:
2824
return GetVector3Tweener(pbTween.Scale.Start, pbTween.Scale.End, durationInSeconds);
2925
case PBTween.ModeOneofCase.TextureMove:
3026
return GetVector2Tweener(pbTween.TextureMove.Start, pbTween.TextureMove.End, durationInSeconds);
27+
case PBTween.ModeOneofCase.RotateContinuous:
28+
return GetContinuousQuaternionTweener(transform ? transform.localRotation : Quaternion.identity, pbTween.RotateContinuous.Direction.ToUnityQuaternion(), pbTween.RotateContinuous.Speed);
29+
case PBTween.ModeOneofCase.MoveContinuous:
30+
return GetContinuousVector3Tweener(transform ? transform.localPosition : Vector3.zero, pbTween.MoveContinuous.Direction.ToUnityVector(), pbTween.MoveContinuous.Speed);
31+
case PBTween.ModeOneofCase.TextureMoveContinuous:
32+
return GetContinuousVector2Tweener(textureStart ?? Vector2.zero, pbTween.TextureMoveContinuous.Direction.ToUnityVector(), pbTween.TextureMoveContinuous.Speed);
3133
case PBTween.ModeOneofCase.None:
3234
default:
3335
throw new ArgumentException($"No Tweener defined for tween mode: {pbTween.ModeCase}");
@@ -48,6 +50,27 @@ private QuaternionTweener GetQuaternionTweener(Quaternion start, Quaternion end,
4850
return tweener;
4951
}
5052

53+
private QuaternionTweener GetContinuousQuaternionTweener(Quaternion start, Quaternion direction, float speed)
54+
{
55+
QuaternionTweener tweener = quaternionTweenerPool.Get();
56+
tweener.InitializeContinuous(start, direction, speed);
57+
return tweener;
58+
}
59+
60+
private Vector3Tweener GetContinuousVector3Tweener(Vector3 start, Vector3 direction, float speed)
61+
{
62+
Vector3Tweener tweener = vector3TweenerPool.Get();
63+
tweener.InitializeContinuous(start, direction, speed);
64+
return tweener;
65+
}
66+
67+
private Vector2Tweener GetContinuousVector2Tweener(Vector2 start, Vector2 direction, float speed)
68+
{
69+
Vector2Tweener tweener = vector2TweenerPool.Get();
70+
tweener.InitializeContinuous(start, direction, speed);
71+
return tweener;
72+
}
73+
5174
private Vector2Tweener GetVector2Tweener(Vector2 start, Vector2 end, float durationInSeconds)
5275
{
5376
Vector2Tweener tweener = vector2TweenerPool.Get();
@@ -71,6 +94,7 @@ public void ReleaseCustomTweenerFrom(SDKTweenComponent sdkTweenComponent)
7194
case QuaternionTweener quaternionTweener:
7295
quaternionTweenerPool.Release(quaternionTweener);
7396
break;
97+
7498
}
7599

76100
sdkTweenComponent.CustomTweener = null;

Explorer/Assets/DCL/SDKComponents/Tween/Systems/CustomTweenerExtensions.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ public static void UpdateMaterial(this ITweener self, Material material, Texture
1414
{
1515
if (self is not Vector2Tweener vector2Tweener) return;
1616

17+
var value = vector2Tweener.CurrentValue;
18+
1719
switch (movementType)
1820
{
1921
case TextureMovementType.TmtOffset:
20-
material.SetTextureOffset(TextureArrayConstants.BASE_MAP_ORIGINAL_TEXTURE, vector2Tweener.CurrentValue);
22+
material.SetTextureOffset(TextureArrayConstants.BASE_MAP_ORIGINAL_TEXTURE, value);
2123
break;
2224
case TextureMovementType.TmtTiling:
23-
material.SetTextureScale(TextureArrayConstants.BASE_MAP_ORIGINAL_TEXTURE, vector2Tweener.CurrentValue);
25+
material.SetTextureScale(TextureArrayConstants.BASE_MAP_ORIGINAL_TEXTURE, value);
2426
break;
2527
}
2628
}
@@ -32,13 +34,16 @@ public static void UpdateTransform(this ITweener self, Transform transform, PBTw
3234
{
3335
case PBTween.ModeOneofCase.Move:
3436
case PBTween.ModeOneofCase.Scale:
37+
case PBTween.ModeOneofCase.MoveContinuous:
3538
if (self is not Vector3Tweener vector3Tweener) return;
36-
if (updateType == PBTween.ModeOneofCase.Move)
37-
transform.localPosition = vector3Tweener.CurrentValue;
39+
var value3 = vector3Tweener.CurrentValue;
40+
if (updateType == PBTween.ModeOneofCase.Move || updateType == PBTween.ModeOneofCase.MoveContinuous)
41+
transform.localPosition = value3;
3842
else
39-
transform.localScale = vector3Tweener.CurrentValue;
43+
transform.localScale = value3;
4044
break;
4145
case PBTween.ModeOneofCase.Rotate:
46+
case PBTween.ModeOneofCase.RotateContinuous:
4247
if (self is not QuaternionTweener quaternionTweener) return;
4348
transform.localRotation = quaternionTweener.CurrentValue;
4449
break;
@@ -52,13 +57,16 @@ public static void UpdateSDKTransform(this ITweener self, ref SDKTransform sdkTr
5257
{
5358
case PBTween.ModeOneofCase.Move:
5459
case PBTween.ModeOneofCase.Scale:
60+
case PBTween.ModeOneofCase.MoveContinuous:
5561
if (self is not Vector3Tweener vector3Tweener) return;
56-
if (updateType == PBTween.ModeOneofCase.Move)
57-
sdkTransform.Position.Value = vector3Tweener.CurrentValue;
62+
var value3 = vector3Tweener.CurrentValue;
63+
if (updateType == PBTween.ModeOneofCase.Move || updateType == PBTween.ModeOneofCase.MoveContinuous)
64+
sdkTransform.Position.Value = value3;
5865
else
59-
sdkTransform.Scale = vector3Tweener.CurrentValue;
66+
sdkTransform.Scale = value3;
6067
break;
6168
case PBTween.ModeOneofCase.Rotate:
69+
case PBTween.ModeOneofCase.RotateContinuous:
6270
if (self is not QuaternionTweener quaternionTweener) return;
6371
sdkTransform.Rotation.Value = quaternionTweener.CurrentValue;
6472
break;

Explorer/Assets/DCL/SDKComponents/Tween/Systems/TweenSDKComponentHelper.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public static void UpdateTweenResult(ref SDKTransform sdkTransform, ref Transfor
2727
if (shouldUpdateTransform)
2828
{
2929
sdkTweenComponent.CustomTweener.UpdateTransform(transformComponent.Transform, sdkTweenComponent.TweenMode);
30-
3130
transformComponent.UpdateCache();
3231
}
3332
else

0 commit comments

Comments
 (0)