From b866c2ef9ec7280c4bf35575c0a09ab0bc6db47a Mon Sep 17 00:00:00 2001 From: Josef Date: Sat, 18 Jan 2025 21:02:20 +0100 Subject: [PATCH] Outlines --- Runtime/Animation/Flash/Flash.cs | 4 +- Runtime/Animation/Highlight/Highlight.cs | 2 +- .../Animation/Highlight/HighlightEffect.cs | 226 +++++++++++++++++- Runtime/Animation/Highlight/Highlighter.cs | 65 ----- .../Presets/White Outline - Highlight.tres | 20 ++ Runtime/Colors/ColorX.cs | 11 + Runtime/Godot/CachedResource.cs | 2 +- Runtime/Interactions/Interactor.cs | 17 ++ Runtime/Interactions/Pointable.cs | 2 +- Runtime/Interactions/Pointer.cs | 16 +- Runtime/Sensors/SensorRunner.cs | 3 +- .../Outline/Outline Bold Yellow.material | Bin 0 -> 416 bytes .../Outline/Outline Thin White.material | Bin 0 -> 412 bytes .../Shaders/Effects/Outline/Outline.cs | 50 ++++ .../Shaders/Effects/Outline/Outline.gdshader | 27 +++ .../Shaders/Effects/Outline/Outline.tres | 31 --- .../Outline/White-Outline.material.depren | Bin 0 -> 421 bytes Runtime/Time/TimeLineManager.cs | 19 ++ 18 files changed, 376 insertions(+), 119 deletions(-) delete mode 100644 Runtime/Animation/Highlight/Highlighter.cs create mode 100644 Runtime/Animation/Highlight/Presets/White Outline - Highlight.tres create mode 100644 Runtime/Shading/Shaders/Effects/Outline/Outline Bold Yellow.material create mode 100644 Runtime/Shading/Shaders/Effects/Outline/Outline Thin White.material create mode 100644 Runtime/Shading/Shaders/Effects/Outline/Outline.cs create mode 100644 Runtime/Shading/Shaders/Effects/Outline/Outline.gdshader delete mode 100644 Runtime/Shading/Shaders/Effects/Outline/Outline.tres create mode 100644 Runtime/Shading/Shaders/Effects/Outline/White-Outline.material.depren diff --git a/Runtime/Animation/Flash/Flash.cs b/Runtime/Animation/Flash/Flash.cs index d2a62af..4f1ef0a 100644 --- a/Runtime/Animation/Flash/Flash.cs +++ b/Runtime/Animation/Flash/Flash.cs @@ -51,9 +51,7 @@ namespace Rokojori actionID = DispatchStart(); - var random = LCG.Randomized(); - - var networkSeed = random.GetSeed(); + var random = LCG.WithSeed( networkSeed ); // RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() ); diff --git a/Runtime/Animation/Highlight/Highlight.cs b/Runtime/Animation/Highlight/Highlight.cs index 78d44cc..e5878e8 100644 --- a/Runtime/Animation/Highlight/Highlight.cs +++ b/Runtime/Animation/Highlight/Highlight.cs @@ -15,7 +15,7 @@ namespace Rokojori public HighlightActionType type; [Export] - public Highlighter highlighter; + public HighlightEffect highlighter; [Export] public Node3D[] targets; diff --git a/Runtime/Animation/Highlight/HighlightEffect.cs b/Runtime/Animation/Highlight/HighlightEffect.cs index 964682b..a1a4cc9 100644 --- a/Runtime/Animation/Highlight/HighlightEffect.cs +++ b/Runtime/Animation/Highlight/HighlightEffect.cs @@ -6,10 +6,234 @@ using Godot; namespace Rokojori { + + public enum HighlightActionType + { + Start, + End + } + + public class HighlightAnimation + { + public Node3D[] targets; + public int tweenID = -1; + + public List materials = new List(); + public float phase; + + + } + [Tool] [GlobalClass] public partial class HighlightEffect:Resource { - + [Export] + public TimeLine timeline; + + [Export] + public float inDuration; + + [Export] + public Curve inCurve = MathX.Curve( 0, 1 ); + + [Export] + public float outDuration; + + [Export] + public Curve outCurve = MathX.Curve( 0, 1 ); + + [Export] + public HDRColor color; + + public enum MaterialMode + { + Flat_Outline, + Custom_Material + } + + [Export] + public MaterialMode materialMode; + + [Export] + public Material customMaterial; + + [Export] + public ColorPropertyName customColorProperty; + + List _active = new List(); + + public void Highlight( HighlightActionType type, Node3D[] targets ) + { + if ( HighlightActionType.Start == type ) + { + StartHighlight( targets ); + } + else if ( HighlightActionType.End == type ) + { + EndHighlight( targets ); + } + } + + void StartHighlight( Node3D[] targets ) + { + var animation = _active.Find( a => Arrays.AreEntriesEqual( a.targets, targets ) ); + + var hdrColor = color.GetHDRColor(); + var colorTransparent = ColorX.Fade( hdrColor, 0 ); + + + if ( animation == null ) + { + animation = new HighlightAnimation(); + animation.targets = targets; + + _active.Add( animation ); + + Material material = null; + + if ( MaterialMode.Flat_Outline == materialMode ) + { + var outlineMaterial = new OutlineMaterial(); + outlineMaterial.albedo.Set( colorTransparent ); + material = outlineMaterial; + } + else if ( MaterialMode.Custom_Material == materialMode ) + { + material = (Material) customMaterial.Duplicate(); + customColorProperty.Set( material, colorTransparent ); + } + + Arrays.ForEach( targets, + t => + { + var m = (Material) material.Duplicate( true ); + + animation.materials.Add( m ); + Materials.AddOverlay( t, m ); + } + ); + + } + + var startPhase = animation.phase; + + animation.tweenID = TimeLineManager.Tween( timeline, inDuration, + ( id, type, phase )=> + { + // RJLog.Log( "Start Highlight: ", id, "Active:",animation.tweenID, "Phase:", phase ); + if ( animation.tweenID != id ) + { + return; + } + + animation.phase = MathX.Map( phase, 0, 1, startPhase, 1 ); + + var p = animation.phase; + + if ( inCurve != null ) + { + p = inCurve.Sample( p ); + } + + var tweenColor = ColorX.Fade( hdrColor, p ); + + if ( TimeLineSpanUpdateType.End == type ) + { + tweenColor = hdrColor; + animation.phase = 1; + } + + animation.materials.ForEach( + ( m )=> + { + if ( MaterialMode.Flat_Outline == materialMode ) + { + var outlineMaterial = ( OutlineMaterial ) m; + outlineMaterial.albedo.Set( tweenColor ); + } + else if ( MaterialMode.Custom_Material == materialMode ) + { + customColorProperty.Set( m, tweenColor); + } + + + } + ); + } + ); + } + + void EndHighlight( Node3D[] targets ) + { + var animation = _active.Find( a => Arrays.AreEntriesEqual( a.targets, targets ) ); + + if ( animation == null ) + { + // RJLog.Log( "No animation found:", targets ); + return; + } + + var startPhase = animation.phase; + var hdrColor = ColorX.Fade( color.GetHDRColor(), startPhase ); + var colorTransparent = ColorX.Fade( hdrColor, 0 ); + + animation.tweenID = TimeLineManager.Tween( timeline, outDuration, + ( id, type, phase )=> + { + // RJLog.Log( "End Highlight: ", id, "Active:",animation.tweenID, "Phase:", phase ); + + if ( animation.tweenID != id ) + { + return; + } + + animation.phase = MathX.Map( phase, 0, 1, startPhase, 0 ); + + var p = animation.phase; + + if ( outCurve != null ) + { + p = outCurve.Sample( p ); + } + + var tweenColor = ColorX.Fade( hdrColor, p ); + + if ( TimeLineSpanUpdateType.End == type ) + { + tweenColor = colorTransparent; + animation.phase = 0; + + for ( int i = 0; i < animation.targets.Length; i ++ ) + { + Materials.RemoveOverlay( targets[ i ], animation.materials[ i ] ); + } + + _active.Remove( animation ); + } + else + { + animation.materials.ForEach( + ( m )=> + { + if ( MaterialMode.Flat_Outline == materialMode ) + { + var outlineMaterial = ( OutlineMaterial ) m; + outlineMaterial.albedo.Set( tweenColor ); + } + else if ( MaterialMode.Custom_Material == materialMode ) + { + customColorProperty.Set( m, tweenColor ); + } + } + ); + } + + } + ); + + + } + } } \ No newline at end of file diff --git a/Runtime/Animation/Highlight/Highlighter.cs b/Runtime/Animation/Highlight/Highlighter.cs deleted file mode 100644 index 43c5c66..0000000 --- a/Runtime/Animation/Highlight/Highlighter.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using System.Text; -using Godot; - -namespace Rokojori -{ - - public enum HighlightActionType - { - Start, - End - } - - public class HighlightTargets - { - public Node3D[] targets; - public int activeAnimationTarget = -1; - - public List originalMaterial; - public List animationMaterial; - - } - - [Tool] - [GlobalClass] - public partial class Highlighter:Node - { - [Export] - public HighlightFlag flag; - - [Export] - public Material material; - - List _activeTargets = new List(); - - public void Highlight( HighlightActionType type, Node3D[] targets ) - { - if ( HighlightActionType.End == type ) - { - var t = _activeTargets.Find( a => a.targets == targets ); - - if ( t == null ) - { - return; - } - - // Get materials - // Animate - // Swap Original Material; - // Remove Materials; - - } - else if ( HighlightActionType.Start == type ) - { - // Create target - // Create materials - // Swap animation materials - // Animate - } - } - - } -} \ No newline at end of file diff --git a/Runtime/Animation/Highlight/Presets/White Outline - Highlight.tres b/Runtime/Animation/Highlight/Presets/White Outline - Highlight.tres new file mode 100644 index 0000000..27ae624 --- /dev/null +++ b/Runtime/Animation/Highlight/Presets/White Outline - Highlight.tres @@ -0,0 +1,20 @@ +[gd_resource type="Resource" script_class="HighlightEffect" load_steps=5 format=3 uid="uid://dadr1kd14m7g3"] + +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_sk831"] +[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Highlight/HighlightEffect.cs" id="2_pq63c"] +[ext_resource type="Resource" uid="uid://h6oi6vkj4c2m" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/RealTime.tres" id="3_8mahg"] + +[sub_resource type="Resource" id="Resource_27v41"] +script = ExtResource("1_sk831") +color = Color(1, 1, 1, 1) +colorMultiply = 1.0 +rgbMultiply = 1.0 +alphaMultiply = 1.0 + +[resource] +script = ExtResource("2_pq63c") +timeline = ExtResource("3_8mahg") +inDuration = 0.1 +outDuration = 0.1 +color = SubResource("Resource_27v41") +materialMode = 0 diff --git a/Runtime/Colors/ColorX.cs b/Runtime/Colors/ColorX.cs index 1e7f504..8f4e0ef 100644 --- a/Runtime/Colors/ColorX.cs +++ b/Runtime/Colors/ColorX.cs @@ -34,6 +34,17 @@ namespace Rokojori return new Color( c.X, c.Y, c.Z, c.W ); } + public static Color Fade( Color color, float fade ) + { + color.A = color.A * fade; + return color; + } + + public static Color SetAlpha( Color color, float alpha ) + { + color.A = alpha; + return color; + } } } \ No newline at end of file diff --git a/Runtime/Godot/CachedResource.cs b/Runtime/Godot/CachedResource.cs index 4720d85..5394ff2 100644 --- a/Runtime/Godot/CachedResource.cs +++ b/Runtime/Godot/CachedResource.cs @@ -27,7 +27,7 @@ namespace Rokojori ResourceLoader.Load( _path ) : _converter( ResourceLoader.Load( _path ) ); - RJLog.Log( _path, _resource ); + // RJLog.Log( _path, _resource ); } diff --git a/Runtime/Interactions/Interactor.cs b/Runtime/Interactions/Interactor.cs index d322f40..911ed1d 100644 --- a/Runtime/Interactions/Interactor.cs +++ b/Runtime/Interactions/Interactor.cs @@ -15,17 +15,34 @@ namespace Rokojori [Export] public Sensor button; + public override void _Ready() + { + SensorManager.Register( this, button ); + } + + public override void _ExitTree() + { + SensorManager.Unregister( this, button ); + } + public void _OnSensor( SensorEvent se ) { + if ( pointer == null || pointer.pointable == null ) { return; } + if ( ! se.isDown ) + { + return; + } + var interactable = Nodes.Find( pointer.pointable.GetParent() ); if ( interactable == null ) { + return; } diff --git a/Runtime/Interactions/Pointable.cs b/Runtime/Interactions/Pointable.cs index 1e9ad9f..0dc1701 100644 --- a/Runtime/Interactions/Pointable.cs +++ b/Runtime/Interactions/Pointable.cs @@ -26,7 +26,7 @@ namespace Rokojori [ExportGroup("Highlighting")] [Export] - public HighlightFlag highlightFlag; + public HighlightEffect highlightEffect; [Export] public Node3D[] highlightTargets; diff --git a/Runtime/Interactions/Pointer.cs b/Runtime/Interactions/Pointer.cs index ac17d1f..2741536 100644 --- a/Runtime/Interactions/Pointer.cs +++ b/Runtime/Interactions/Pointer.cs @@ -15,9 +15,6 @@ namespace Rokojori [Export] public Caster caster; - [Export] - public Highlighter[] highlighters; - public override void _Process( double delta ) { if ( caster == null ) @@ -55,21 +52,12 @@ namespace Rokojori void Highlight( HighlightActionType type, Pointable p ) { - if ( p.highlightFlag == null || p.highlightTargets == null || p.highlightTargets.Length == 0 ) - { - return; - } - - var highlighterIndex = Arrays.FindIndex( highlighters, ( h )=> h.flag == pointable.highlightFlag ); - - if ( highlighterIndex == -1 ) + if ( p.highlightEffect == null || p.highlightTargets == null || p.highlightTargets.Length == 0 ) { return; } - var highlighter = highlighters[ highlighterIndex ]; - - highlighter.Highlight( type, p.highlightTargets ); + p.highlightEffect.Highlight( type, p.highlightTargets ); } } diff --git a/Runtime/Sensors/SensorRunner.cs b/Runtime/Sensors/SensorRunner.cs index e18b51d..5fd86ae 100644 --- a/Runtime/Sensors/SensorRunner.cs +++ b/Runtime/Sensors/SensorRunner.cs @@ -20,8 +20,7 @@ namespace Rokojori } public void Update( float delta ) - { - + { sensor.ProcessSensor( this, delta ); if ( ! sensor.continous && sensor.value == _lastValue ) diff --git a/Runtime/Shading/Shaders/Effects/Outline/Outline Bold Yellow.material b/Runtime/Shading/Shaders/Effects/Outline/Outline Bold Yellow.material new file mode 100644 index 0000000000000000000000000000000000000000..ad4db5e920a88338586e2262da613bf7cc35808b GIT binary patch literal 416 zcmV;R0bl-7Q$s@n000005C8xt0{{Ss0RR9fwJ-f(Cj#{g0Or#}HehYi0Wb^$QxrG} zLX(6{kDPi++a)7=v)_xhN!n$RLOKYJp^KIZu3Lo{`9%-A-Zr&?(>78u05SkI00?Jn zrNLS9qi$9g_s!_|b!k%W|C|4sQ3S@MVv&eEE^Mxw(R^)(_5a}iz<N+p-ON=Gmj5$1RoD}D=9(`VC5=YwW0C07 zX!A(I#u%)!1Zt+<4#DW;g!Qe1JxSAJcB67$*S0o6IsOB@X0YF-SF~_`G9Hix`U^T# z#-fCvI_6UGUvmP1^8cYa{S*#=^^tgWO876Z*;pzg80TZg$Q#rZXNMxC{2Fms!dL?> zAaH`2s}c{93C%L9%&+@~K;80lHd8fyM&?RU_9!kCM|)S8Qvx3t77DyWlZxi z7KQ!XHkejuYr>-y`?fBrHjoe&VGop*W9|&nCJ4V!^Km`aY*fgrTqSSZD*|xJ1~v?F KgTn$+Q$s^i|Ghx~ literal 0 HcmV?d00001 diff --git a/Runtime/Shading/Shaders/Effects/Outline/Outline Thin White.material b/Runtime/Shading/Shaders/Effects/Outline/Outline Thin White.material new file mode 100644 index 0000000000000000000000000000000000000000..6bd4ff728bbf1491e8f1eb9fc6547d5706f2cfde GIT binary patch literal 412 zcmV;N0b~ABQ$s@n000005C8xs0{{So0RR9fwJ-f(CIZz909F%1H&DeU9Tb=f-L-Rd1-P-?yL1yaNz+P3SltWD}v0{ z;t5F|R%&e!zXl^ur;R&$#E;la!dO+x7=`TkAMkl`yQwww@O4n907B5jn$u0!-zeA}i7k zkO_SmSLUue3qd;OH=`Av@mP_;fx&H|747s8VF1olPAPa`S3*3+I?TgbFk>3W$Q0&t z+hbaxTN4(o*w=N*w1EU+0ehyb5OaqhZ9({fnvLtlW}~{i+Ew!6UMB#hY_{Qu8x$5& GQ$s_ZM7d}H literal 0 HcmV?d00001 diff --git a/Runtime/Shading/Shaders/Effects/Outline/Outline.cs b/Runtime/Shading/Shaders/Effects/Outline/Outline.cs new file mode 100644 index 0000000..89e2d05 --- /dev/null +++ b/Runtime/Shading/Shaders/Effects/Outline/Outline.cs @@ -0,0 +1,50 @@ +using Godot; + +namespace Rokojori +{ + public class Outline + { + public static readonly CachedResource shader = new CachedResource( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Effects/Outline/Outline.gdshader" + ); + + public static readonly ColorPropertyName albedo = ColorPropertyName.Create( "albedo" ); + public static readonly FloatPropertyName size = FloatPropertyName.Create( "size" ); + public static readonly FloatPropertyName sizeCloseScale = FloatPropertyName.Create( "sizeCloseScale" ); + public static readonly FloatPropertyName sizeFarScale = FloatPropertyName.Create( "sizeFarScale" ); + public static readonly FloatPropertyName closeDistance = FloatPropertyName.Create( "closeDistance" ); + public static readonly FloatPropertyName farDistance = FloatPropertyName.Create( "farDistance" ); + + } + + public partial class OutlineMaterial:CustomMaterial + { + public static readonly CachedResource BoldYellow = CustomMaterial.Cached( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Effects/Outline/Outline Bold Yellow.material" + ); + public static readonly CachedResource ThinWhite = CustomMaterial.Cached( + "res://addons/rokojori_action_library/Runtime/Shading/Shaders/Effects/Outline/Outline Thin White.material" + ); + + public readonly CustomMaterialProperty albedo; + public readonly CustomMaterialProperty size; + public readonly CustomMaterialProperty sizeCloseScale; + public readonly CustomMaterialProperty sizeFarScale; + public readonly CustomMaterialProperty closeDistance; + public readonly CustomMaterialProperty farDistance; + + public OutlineMaterial() + { + Shader = Outline.shader.Get(); + + albedo = new CustomMaterialProperty( this, Outline.albedo ); + size = new CustomMaterialProperty( this, Outline.size ); + sizeCloseScale = new CustomMaterialProperty( this, Outline.sizeCloseScale ); + sizeFarScale = new CustomMaterialProperty( this, Outline.sizeFarScale ); + closeDistance = new CustomMaterialProperty( this, Outline.closeDistance ); + farDistance = new CustomMaterialProperty( this, Outline.farDistance ); + } + + } + +} \ No newline at end of file diff --git a/Runtime/Shading/Shaders/Effects/Outline/Outline.gdshader b/Runtime/Shading/Shaders/Effects/Outline/Outline.gdshader new file mode 100644 index 0000000..9a1655d --- /dev/null +++ b/Runtime/Shading/Shaders/Effects/Outline/Outline.gdshader @@ -0,0 +1,27 @@ +shader_type spatial; +render_mode blend_mix, world_vertex_coords, depth_draw_opaque, cull_front, diffuse_burley, specular_schlick_ggx, unshaded; + +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" +#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Noise.gdshaderinc" + +uniform vec4 albedo : source_color; +uniform float size:hint_range(0,10) = 1; +uniform float sizeCloseScale : hint_range(0,10) = 1; +uniform float sizeFarScale : hint_range(0,10) = 0.5; +uniform float closeDistance = 20; +uniform float farDistance = 40; + + +void vertex() +{ + float cameraDistance = distance( VERTEX, CAMERA_POSITION_WORLD ); + float outlineSize = size * mapClamped( cameraDistance, closeDistance, farDistance, sizeCloseScale, sizeFarScale ); + VERTEX += NORMAL * outlineSize/500.0 * cameraDistance; +} + +void fragment() +{ + ALBEDO = albedo.rgb; + ALPHA = albedo.a; +} diff --git a/Runtime/Shading/Shaders/Effects/Outline/Outline.tres b/Runtime/Shading/Shaders/Effects/Outline/Outline.tres deleted file mode 100644 index a014e34..0000000 --- a/Runtime/Shading/Shaders/Effects/Outline/Outline.tres +++ /dev/null @@ -1,31 +0,0 @@ -[gd_resource type="Shader" format=3 uid="uid://bmgpmbthlfon3"] - -[resource] -code = "// NOTE: Shader automatically converted from Godot Engine 4.3.stable.mono's StandardMaterial3D. - -shader_type spatial; -render_mode blend_mix, world_vertex_coords, depth_draw_opaque, cull_front, diffuse_burley, specular_schlick_ggx, unshaded; - -#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc\" -#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc\" -#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/Noise.gdshaderinc\" - -uniform vec4 albedo : source_color; -uniform float sizeClose : hint_range(0,100) = 1; -uniform float sizeFar : hint_range(0,100) =1; -uniform float closeDistance = 5; -uniform float farDistance = 100; - - -void vertex() -{ - float cameraDistance = distance( VERTEX, CAMERA_POSITION_WORLD ); - float size = mapClamped( cameraDistance, closeDistance, farDistance, sizeClose, sizeFar ); - VERTEX += NORMAL * size/500.0 * cameraDistance; -} - -void fragment() -{ - ALBEDO = albedo.rgb; -} -" diff --git a/Runtime/Shading/Shaders/Effects/Outline/White-Outline.material.depren b/Runtime/Shading/Shaders/Effects/Outline/White-Outline.material.depren new file mode 100644 index 0000000000000000000000000000000000000000..b65cd0eee77d20b2366ed1052cea1a093b605c5f GIT binary patch literal 421 zcmV;W0b2f2Q$s@n000005C8z=0ssJw0RR9fwJ-f(;4?Gc@x`=VKC(CaA!e8Fp6h`)wFNjbP#$ovWkBrZNCB05kxV z!i6tfCtIBDsf(|zYf_Zk|1tkBw;%v~2z*RBSAjp}-l-kEl#V?A8U7#qC-`6R2fX1X zT00Wor_Qr7K2GLK!t&vfTF_J0JGatStI7YBOQ}|yBMbjqUYgvI+iJZOZ1@Ipx($Um znCulnW?S)uq=}VU8^o`{$kS=#jv-MbHj^+?lrokfLH<)dEpAt74Mlt%)F}g;$us?@ z{8!M(ST-jKnj=&+1O7_@3jzNtG$juI4KSF2O?9!8M;~nDT37DWD6Z=|CBj(9Z<0J% zFCcJ&p)wK=l;JW*-DwC;C4UiF;TXH=FS0cZ*)z}r3@rp$P{j%`NFcxlRw!Zg35Z#O z*O+bGOY-RFPM_N}jj} PvNJD`;Wq#*Qd2`i^A)#b literal 0 HcmV?d00001 diff --git a/Runtime/Time/TimeLineManager.cs b/Runtime/Time/TimeLineManager.cs index 455452a..d12764b 100644 --- a/Runtime/Time/TimeLineManager.cs +++ b/Runtime/Time/TimeLineManager.cs @@ -72,6 +72,25 @@ namespace Rokojori runner.Modulate( c, onReady ); } + public static int Tween( TimeLine timeline, float duration, Action callback ) + { + timeline = TimeLine.IfNull_ReplaceByGameTime( timeline ); + var startTime = GetPosition( timeline ); + + var spanID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, + ( int id, TimeLineSpanUpdateType type )=> + { + var timeNow = GetPosition( timeline ); + var elapsed = timeNow - startTime; + var phase = Mathf.Clamp( elapsed / duration, 0, 1 ); + + callback( id, type, phase ); + } + ); + + return spanID; + } + void UpdateRealTime( double engineDelta ) { var now = DateTime.Now;