Description:
I am very excited about the addition of
VRCTween
in the new SDK update.
However, I have noticed an issue: when trying to tween large integers using
VRCTween.TweenInt
, the values get rounded up or down to specific numbers, leading to inaccurate results.
using System;
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Components;
public class VRCTweenTest : UdonSharpBehaviour
{
[NonSerialized] public int _tweenedInt;
public void PrintCurrentValue()
{
Debug.Log(_tweenedInt);
}
void Start()
{
VRCTween.TweenInt(
1, 15, 2,
this, nameof(_tweenedInt), nameof(PrintCurrentValue), VRCTweenEase.Linear
).SetDelay(1);
VRCTween.TweenInt(
100000001, 100000015, 2,
this, nameof(_tweenedInt), nameof(PrintCurrentValue), VRCTweenEase.Linear
).SetDelay(4);
VRCTween.TweenInt(
2000000001, 2000000015, 2,
this, nameof(_tweenedInt), nameof(PrintCurrentValue), VRCTweenEase.Linear
).SetDelay(7);
}
}
Expected Behavior:
The script should output all intermediate integer values smoothly:
*
1
through
15
*
100000001
through
100000015
*
2000000001
through
2000000015
Actual Behavior:
When running the script, the console outputs the following:
* The first tween correctly prints
1
through
15
.
* The second tween only prints
100000000
,
100000008
, and
100000016
.
* The third tween only prints
2000000000
.
Cause Analysis:
I suspect this happens because
VRCTween.TweenInt
is internally utilizing
DOVirtual.Float
or otherwise casting the values to
float
during interpolation. Since a 32-bit float has a 24-bit significand, it cannot precisely represent all 32-bit integer values (precision loss occurs for integers larger than 2^24, which is 16,777,216).
Thank you for looking into this!