For anyone who’s familiar with ‘DOTween’ and/or UIElements, I’m trying to tween the opacity of a VisualElement from 0 → 1, 1 → 0 and it doesn’t seem to be working. Is this because of my code, DOTween, or because this is not yet supported in UIElements? This is the function I made:
void MenuTransition(VisualElement menu, float t)
{
float opacity = menu.style.opacity.value;
if(menu.style.opacity.value == 0)
{
DOTween.To(() => opacity, x => opacity = x, 1f, t);
menu.focusable = true;
}
else if(menu.style.opacity.value == 1)
{
menu.focusable = false;
DOTween.To(() => opacity, x => opacity = x, 0f, t);
}
}
UI Toolkit ships with a dedicated tweening api
(experimental but works fine at the time of writing this post)

using UnityEngine;
using UnityEngine.UIElements;
public class RuntimeUiAnimator : MonoBehaviour
{
[SerializeField] UIDocument _uiDocument = null;
void OnEnable ()
{
var ROOT = _uiDocument.rootVisualElement;
ROOT.Query("animated").ForEach( (next) => {
var zeroToOne = next.experimental.animation
.Start( 0f , 1f , 1000 , (ve,value) => ve.style.opacity = value )
.Ease( UnityEngine.UIElements.Experimental.Easing.InOutQuad )
.KeepAlive();
var oneToZero = next.experimental.animation
.Start( 1f , 0f , 1000 , (ve,value) => ve.style.opacity = value )
.Ease( UnityEngine.UIElements.Experimental.Easing.InOutQuad )
.KeepAlive();
var idle = next.experimental.animation
.Start( 1f , 1f , 1000 , (ve,value) => {} )
.KeepAlive();
zeroToOne.OnCompleted( ()=> idle.Start() );
idle.OnCompleted( ()=> oneToZero.Start() );
oneToZero.OnCompleted( ()=> zeroToOne.Start() );
zeroToOne.Start();
} );
}
}
UIElements/UIToolkit supports all kinds of tweens. Just the ones that work.
float opacity = menu.style.opacity.value;
float opacity is a stack-level copy that becomes captured by value into these lambda expression objects (completely separate heap allocations). So reading and changing it’s value in a lambda is futile. In other words this:
DOTween.To(() => opacity, x => opacity = x, 1f, t);
Will be converted into ± this:
class lambda_getter_123456
{
public float field1;
public float Get => this.field1;
}
class lambda_setter_342738
{
public float field1;
public float Set => this.field1 = value;
}
DOTween.To(
new lambda_getter_123456{field1=opacity} ,
new lambda_setter_342738{field1=opacity} ,
1f , t
);
_
What you may want to do instead is something like this:
var style = menu.style;
DOTween.To( () => style.opacity , x => style.opacity = x , 1f , t );
where style references a memory location that this ui system actually reads.