I'm fading out the colour of a material block, but am unsure how to use SetPropertyBlock

Hi, here’s another DoTween Question…

I’m fading the colour of a material, but am unsure of how to set the property block correctly.

This works fine:

    public void FadeOut()
    {
        materialBlock.SetFloat("LerpToFadeOut", 1);
        spriteRenderer.SetPropertyBlock(materialBlock);
    }

But if I want to fade it using DoTween, I’m unsure how to implement the SetPropertyBlock?

    public void FadeOut()
    {
        if (fadeTween != null) fadeTween.Kill();
        fadeTween = DOVirtual.Float(materialBlock.GetFloat("LerpToFadeOut"), 0, fadeOutDuration, (float val) => {
            materialBlock.SetFloat("LerpToFadeOut", val);
        }).OnComplete(() => {
            fadeTween = null;
            Removed?.Invoke(this);
        });

        spriteRenderer.SetPropertyBlock(materialBlock);
    }

Here’s my full script if that helps:

using Murton.Extensions.Midi.Api;
using UnityEngine;
using UnityEngine.Events;
using DG.Tweening;
using Murton.ParticipationTable.Const;

public class Note : MonoBehaviour
{
    public MidiNote NoteData { get; private set; }
    public string SongKey { get; private set; }
    public NoteHitZoneState HitZoneState { get; private set; }
    public bool HasBeenHit { get; private set; }
    public float SecondsToThisNote { get; private set; }

    private float timeFromTriggerToStartHitZone;
    private float timeFromTriggerToEndHitZone;
    private Tweener colourTween;
    private Tweener fadeTween;


    public bool IsRemovingItself { get; private set; }
    public UnityEvent<Note> EnteredHitZone = new UnityEvent<Note>();
    public UnityEvent<Note> ExitedHitZone = new UnityEvent<Note>();
    public UnityEvent<Note> Hit = new UnityEvent<Note>();
    public UnityEvent<Note> Removed = new UnityEvent<Note>();

    [HideInInspector]
    public Color note_MainColour;
   // private NoteColours noteColours;
   
    private float colourTweenDuration = 0.4f;
    private float fadeOutDuration = 0.4f;

    private MaterialPropertyBlock materialBlock;
    private SpriteRenderer spriteRenderer;

    public void Init()
    {
        materialBlock = new MaterialPropertyBlock();
        spriteRenderer = GetComponentInChildren<SpriteRenderer>();
    }

    public void AssignNoteData(MidiNote noteData, string songKey, float timeFromTriggerToStartHitZone, float timeFromTriggerToEndHitZone)
    {
        this.NoteData = noteData;
        this.SongKey = songKey;
        this.timeFromTriggerToStartHitZone = timeFromTriggerToStartHitZone;
        this.timeFromTriggerToEndHitZone = timeFromTriggerToEndHitZone;
        this.HitZoneState = NoteHitZoneState.PreHitZone;

        materialBlock.SetFloat("LerpToFinish", 0f);
        materialBlock.SetFloat("LerpToFadeOut", 0f);
        materialBlock.SetFloat("Intensity", 1f);
        spriteRenderer.SetPropertyBlock(materialBlock);

        //need to set properly when this is integrated
       // note_MainColour = noteColours.col_default;

        HasBeenHit = false;
    }

    public void ClearNoteData()
    {
        this.NoteData = null;
        HasBeenHit = false;
        if (colourTween != null) colourTween.Kill();
        if (fadeTween != null) fadeTween.Kill();
    }


    public void ResetForPool()
    {
        HitZoneState = NoteHitZoneState.None;
        HasBeenHit = false;
    }


    public void SetTimeToThisNote(float secondsToThisNote)
    {
        SecondsToThisNote = secondsToThisNote;
        if (HitZoneState == NoteHitZoneState.PreHitZone && SecondsToThisNote >= -timeFromTriggerToStartHitZone)
            HitZoneEnter();
        else if (HitZoneState == NoteHitZoneState.InHitZone && secondsToThisNote >= timeFromTriggerToEndHitZone)
            HitZoneExit();
    }

    public void HitZoneEnter()
    {
        if (HitZoneState == NoteHitZoneState.PreHitZone)
        {
            HitZoneState = NoteHitZoneState.InHitZone;
            FadeColour();
        }
    }

    public void PlayerHit()
    {
        if(HitZoneState == NoteHitZoneState.InHitZone)
        {
            HasBeenHit = true;
            gameObject.SetActive(false);
            Hit?.Invoke(this);
        }
    }

    public void HitZoneExit()
    {
        if (HitZoneState == NoteHitZoneState.InHitZone)
        {
            HitZoneState = NoteHitZoneState.PostHitZone;
            FadeOut();
        }
    }

    private void FadeColour()
    {
        if (colourTween != null) colourTween.Kill();
          colourTween = DOVirtual.Float(materialBlock.GetFloat("LerpToFinish"), 0, colourTweenDuration, (float val) => {
              materialBlock.SetFloat("LerpToFinish", val);
          }).OnComplete(() => {
              colourTween = null;
          });

        spriteRenderer.SetPropertyBlock(materialBlock);
    }

    public void FadeOut()
    {
        if (fadeTween != null) fadeTween.Kill();
        fadeTween = DOVirtual.Float(materialBlock.GetFloat("LerpToFadeOut"), 0, fadeOutDuration, (float val) => {
            materialBlock.SetFloat("LerpToFadeOut", val);
        }).OnComplete(() => {
            fadeTween = null;
            Removed?.Invoke(this);
        });

        spriteRenderer.SetPropertyBlock(materialBlock);
    }
}

Thanks!!

Sorry for the necro, but if anybody else is looking for the solution - I had a similar problem with a SpriteRenderer’s property block which I solved by including the SetPropertyBlock() funtion inside the tween’s callback.

            DOVirtual.Float(1f, 0f, 2f, (float value) => {
                propertyBlock.SetFloat("_EffectAmount", value);
                spriteRenderer.SetPropertyBlock(propertyBlock);
            });
7 Likes