Since I made a knockback effect, I figured showing a damage color or flash on that object worked hand-in-hand. Hopefully, someone will find it as useful. I'm not sure if it belongs in the Color or GameObject category though...
// (c) Copyright HutongGames, LLC 2010-2018. All rights reserved.
// author : ransomink
// Keywords: color, damage
/*--- __ECO__ __PLAYMAKER__ __ACTION__ ---*/
using UnityEngine;
namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Color)]
[Tooltip("Apply a damage color to the GameObject.")]
public class ShowDamageColor : FsmStateAction
{
[RequiredField]
[UIHint(UIHint.Variable)]
[Tooltip("Show damage color on this GameObject.")]
[CheckForComponent(typeof(Renderer))]
public FsmOwnerDefault gameObject;
[RequiredField]
[Tooltip("Color used for damage effect.")]
public FsmColor damageColor;
[RequiredField]
[Tooltip("Duration of color change effect.")]
[HasFloatSlider(0, 1)]
public FsmFloat duration;
[Tooltip("Use unscaled time. Not affected by Time.timeScale (slow motion effects).")]
public bool realTime;
/// <summary>
/// Renderer of the GameObject.
/// </summary>
private Renderer _renderer;
/// <summary>
/// Default material color of the GameObject.
/// </summary>
private Color _defaultColor = Color.clear;
/// <summary>
/// Current material color of the GameObject.
/// </summary>
private Color _currentColor = Color.black;
/// <summary>
/// Duration of the damage color.
/// </summary>
private float _colorDuration;
/// <summary>
/// Beginning of color change.
/// </summary>
private float _startTime;
/// <summary>
/// End of color change.
/// </summary>
private float _endTime;
/// <summary>
/// Change GameObject color?
/// </summary>
private bool _damageColor;
/// <summary>
/// Get the current time.
/// </summary>
private float CurrentTime
{
get { return realTime ? Time.unscaledTime : Time.time; }
}
public override void Reset()
{
gameObject = null;
damageColor = Color.red;
duration = 0.5f;
realTime = false;
}
public override void OnEnter()
{
var go = Fsm.GetOwnerDefaultTarget( gameObject );
_renderer = go.GetComponent<Renderer>();
_defaultColor = _renderer.material.color;
_colorDuration = duration.Value / 2;
DoDamageColor();
}
public override void OnUpdate()
{
if ( _damageColor )
{
if ( CurrentTime >= _endTime )
{
_damageColor = false;
SetTimer( _colorDuration );
}
ChangeColor( _damageColor );
}
else
{
if ( CurrentTime >= _endTime )
{
Finish();
}
ChangeColor( _damageColor );
}
}
void DoDamageColor()
{
_currentColor = _renderer.material.color;
// reset color?
if ( _currentColor != _defaultColor )
{
ResetColor();
}
SetTimer( _colorDuration );
_damageColor = true;
}
void ResetColor()
{
if ( _defaultColor == Color.clear )
{
LogError( "Default Color not set on GameObject." );
return;
}
_renderer.material.color = _defaultColor;
}
void ChangeColor( bool on )
{
if ( on )
{
_renderer.material.color = Color.Lerp( _currentColor, damageColor.Value, Mathf.InverseLerp( _startTime, _endTime, CurrentTime ) );
}
else
{
_renderer.material.color = Color.Lerp( damageColor.Value, _currentColor, Mathf.InverseLerp( _startTime, _endTime, CurrentTime ) );
}
}
void SetTimer( float timer )
{
_startTime = CurrentTime;
_endTime = _startTime + timer;
}
}
}