C# Only Update
This commit is contained in:
parent
b852e63bf0
commit
73df307cef
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
|
@ -7,15 +8,154 @@ namespace Rokojori
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class Action : NetworkNode
|
public partial class Action : NetworkNode
|
||||||
{
|
{
|
||||||
public void Trigger()
|
NetworkNodeSlot _seedSlot = new NetworkNodeSlot();
|
||||||
|
NetworkNodeSlot _dataSlot = new NetworkNodeSlot();
|
||||||
|
NetworkNodeSlot _seedAndDataSlot = new NetworkNodeSlot();
|
||||||
|
|
||||||
|
protected override List<NetworkNodeMember> CreateNetworkNodeMembers()
|
||||||
{
|
{
|
||||||
_OnTrigger();
|
return new List<NetworkNodeMember>()
|
||||||
|
{
|
||||||
|
_networkNodeSlot,
|
||||||
|
_seedSlot,
|
||||||
|
_dataSlot,
|
||||||
|
_seedAndDataSlot
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void _OnTrigger()
|
public Action()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Trigger()
|
||||||
|
{
|
||||||
|
_isNetworkedTrigger = false;
|
||||||
|
_sendsSeed = false;
|
||||||
|
_sendsData = false;
|
||||||
|
_OnTrigger();
|
||||||
|
|
||||||
|
SendOverNetwork();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SendOverNetwork()
|
||||||
|
{
|
||||||
|
// check which type
|
||||||
|
// 0 0 => vanilla
|
||||||
|
// 1 0 => with seed
|
||||||
|
// 0 1 => with data
|
||||||
|
// 1 1 => with seed + data
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void _OnNetworkTrigger( int seed, BitView data )
|
||||||
|
{
|
||||||
|
_isNetworkedTrigger = true;
|
||||||
|
_receivedNetworkSeed = seed;
|
||||||
|
_receivedNetworkData = data;
|
||||||
|
|
||||||
|
_OnTrigger();
|
||||||
|
|
||||||
|
_isNetworkedTrigger = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isNetworkedTrigger = false;
|
||||||
|
int _receivedNetworkSeed = -1;
|
||||||
|
int _sendingNetworkSeed = -1;
|
||||||
|
|
||||||
|
bool _sendsSeed = false;
|
||||||
|
bool _sendsData = false;
|
||||||
|
|
||||||
|
BitView _sendingNetworkData;
|
||||||
|
BitView _receivedNetworkData;
|
||||||
|
|
||||||
|
protected bool isNetworkedTrigger => _isNetworkedTrigger;
|
||||||
|
|
||||||
|
static readonly int maxNetworkSeed = Mathf.RoundToInt( Mathf.Pow( 2, 30 ) );
|
||||||
|
|
||||||
|
protected int networkSeed
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ( _isNetworkedTrigger )
|
||||||
|
{
|
||||||
|
return _receivedNetworkSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _sendsSeed )
|
||||||
|
{
|
||||||
|
return _sendingNetworkSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendingNetworkSeed = GodotRandom.Get().IntegerExclusive( 0, maxNetworkSeed );
|
||||||
|
_sendsSeed = true;
|
||||||
|
|
||||||
|
return _sendingNetworkSeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BitView GetNetworkData( BitView view )
|
||||||
|
{
|
||||||
|
if ( _isNetworkedTrigger )
|
||||||
|
{
|
||||||
|
return _receivedNetworkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sendingNetworkData = view;
|
||||||
|
_sendsData = true;
|
||||||
|
return _sendingNetworkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void _OnTrigger()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static void Trigger( Action action )
|
||||||
|
{
|
||||||
|
if ( action == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
action.Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TriggerAll( Action[] actions, Node target, bool triggerDirectChildren )
|
||||||
|
{
|
||||||
|
if ( actions != null )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < actions.Length; i++ )
|
||||||
|
{
|
||||||
|
Action.Trigger( actions[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! triggerDirectChildren )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nodes.ForEachDirectChild<Action>( target, a => Action.Trigger( a ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TriggerAll( Action action, Node target, bool triggerDirectChildren )
|
||||||
|
{
|
||||||
|
if ( action != null )
|
||||||
|
{
|
||||||
|
Action.Trigger( action );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! triggerDirectChildren )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nodes.ForEachDirectChild<Action>( target, a => Action.Trigger( a ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,33 +7,33 @@ namespace Rokojori
|
||||||
/** <summary for="class ActionList">
|
/** <summary for="class ActionList">
|
||||||
|
|
||||||
<title>
|
<title>
|
||||||
Executes multiple actions (RJAction) at once.
|
Executes multiple actions (Action) at once.
|
||||||
</title>
|
</title>
|
||||||
|
|
||||||
<description>
|
<description>
|
||||||
The ActionList, which is an RJAction itself, executes all actions stored in the member 'actions' and also child nodes
|
The ActionList, which is an Action itself, executes all actions stored in the member 'actions' and also child nodes
|
||||||
that extend RJAction, when 'triggerDirectChildren' is checked.
|
that extend Action, when 'triggerDirectChildren' is checked.
|
||||||
|
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
</summary>
|
</summary>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RJActionList.svg") ]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ActionList.svg") ]
|
||||||
public partial class ActionList : RJAction
|
public partial class ActionList : Action
|
||||||
{
|
{
|
||||||
|
|
||||||
/** <summary for="field actions">Actions to execute</summary>*/
|
/** <summary for="field actions">Actions to execute</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction[] actions;
|
public Action[] actions;
|
||||||
|
|
||||||
/** <summary for="field triggerDirectChildren">Whether to execute RJAction child nodes</summary>*/
|
/** <summary for="field triggerDirectChildren">Whether to execute Action child nodes</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public bool triggerDirectChildren = true;
|
public bool triggerDirectChildren = true;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
Actions.TriggerAll( actions, this, triggerDirectChildren );
|
Action.TriggerAll( actions, this, triggerDirectChildren );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,14 +5,14 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class ActionReference : RJAction
|
public partial class ActionReference : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction referencedAction;
|
public Action referencedAction;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
Actions.Trigger( referencedAction );
|
Action.Trigger( referencedAction );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,15 +11,15 @@ namespace Rokojori
|
||||||
public class ActionSequenceRunner
|
public class ActionSequenceRunner
|
||||||
{
|
{
|
||||||
public ActionSequence sequence;
|
public ActionSequence sequence;
|
||||||
public List<RJAction> actions;
|
public List<Action> actions;
|
||||||
public List<RJSequenceAction> sequencables;
|
public List<SequenceAction> sequencables;
|
||||||
public int sequencablesIndex = 0;
|
public int sequencablesIndex = 0;
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
bool cancelledSequence = false;
|
bool cancelledSequence = false;
|
||||||
|
|
||||||
int _runID = -1;
|
int _runID = -1;
|
||||||
|
|
||||||
RJSequenceAction _runningAction;
|
SequenceAction _runningAction;
|
||||||
int _runningActionID = -1;
|
int _runningActionID = -1;
|
||||||
|
|
||||||
public void Cancel()
|
public void Cancel()
|
||||||
|
@ -61,7 +61,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( sequencables.Count == 0 )
|
if ( sequencables.Count == 0 )
|
||||||
{
|
{
|
||||||
actions.ForEach( a => Actions.Trigger( a ) );
|
actions.ForEach( a => Action.Trigger( a ) );
|
||||||
sequence.DispatchEnd( _runID );
|
sequence.DispatchEnd( _runID );
|
||||||
sequence.ClearRun( this );
|
sequence.ClearRun( this );
|
||||||
return;
|
return;
|
||||||
|
@ -87,20 +87,21 @@ namespace Rokojori
|
||||||
StartAction( sequenceAction );
|
StartAction( sequenceAction );
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<RJSequenceAction,RJSequenceAction.OnSequenceDoneEventHandler> callbacks =
|
Dictionary<SequenceAction,System.Action<SequenceActionFinishedEvent>> callbacks =
|
||||||
new Dictionary<RJSequenceAction, RJSequenceAction.OnSequenceDoneEventHandler>();
|
new Dictionary<SequenceAction, System.Action<SequenceActionFinishedEvent>>();
|
||||||
|
|
||||||
void StartAction( RJSequenceAction action )
|
void StartAction( SequenceAction action )
|
||||||
{
|
{
|
||||||
var capturedAction = action;
|
var capturedAction = action;
|
||||||
|
|
||||||
RJSequenceAction.OnSequenceDoneEventHandler callback =
|
System.Action<SequenceActionFinishedEvent> callback =
|
||||||
( long id, bool success ) =>
|
( SequenceActionFinishedEvent ev ) =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
//RJLog.Log( "On Done", id, success );
|
//RJLog.Log( "On Done", id, success );
|
||||||
|
|
||||||
if ( id != _runningActionID )
|
if ( ev.id != _runningActionID )
|
||||||
{
|
{
|
||||||
// RJLog.Error( "Invalid ID", id, "!=", _runningActionID );
|
// RJLog.Error( "Invalid ID", id, "!=", _runningActionID );
|
||||||
return;
|
return;
|
||||||
|
@ -108,7 +109,7 @@ namespace Rokojori
|
||||||
|
|
||||||
_runningActionID = -1;
|
_runningActionID = -1;
|
||||||
|
|
||||||
if ( success )
|
if ( ev.success )
|
||||||
{
|
{
|
||||||
sequencablesIndex ++;
|
sequencablesIndex ++;
|
||||||
ProcessNext();
|
ProcessNext();
|
||||||
|
@ -120,7 +121,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
var callbackReference = callbacks[ capturedAction ];
|
var callbackReference = callbacks[ capturedAction ];
|
||||||
capturedAction.OnSequenceDone -= callbackReference;
|
capturedAction.onSequenceDone.RemoveAction( callbackReference );
|
||||||
|
|
||||||
callbacks.Remove( capturedAction );
|
callbacks.Remove( capturedAction );
|
||||||
};
|
};
|
||||||
|
@ -132,54 +133,54 @@ namespace Rokojori
|
||||||
callbacks[ _runningAction ] = callback;
|
callbacks[ _runningAction ] = callback;
|
||||||
_runningAction.OnSequenceDone += callback;
|
_runningAction.OnSequenceDone += callback;
|
||||||
TriggerAllBefore( _runningAction );
|
TriggerAllBefore( _runningAction );
|
||||||
Actions.Trigger( _runningAction );
|
Action.Trigger( _runningAction );
|
||||||
_runningActionID = _runningAction.GetLastSequenceActionID();
|
_runningActionID = _runningAction.GetLastSequenceActionID();
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunNext( RJSequenceAction action, RJSequenceAction.OnSequenceDoneEventHandler callback )
|
void RunNext( SequenceAction action, System.Action<SequenceActionFinishedEvent> callback )
|
||||||
{
|
{
|
||||||
_runningAction = action;
|
_runningAction = action;
|
||||||
callbacks[ _runningAction ] = callback;
|
callbacks[ _runningAction ] = callback;
|
||||||
_runningAction.OnSequenceDone += callback;
|
_runningAction.onSequenceDone.AddAction( callback );
|
||||||
|
|
||||||
|
|
||||||
TriggerAllBefore( _runningAction );
|
TriggerAllBefore( _runningAction );
|
||||||
Actions.Trigger( _runningAction );
|
Action.Trigger( _runningAction );
|
||||||
_runningActionID = _runningAction.GetLastSequenceActionID();
|
_runningActionID = _runningAction.GetLastSequenceActionID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriggerAllBefore( RJSequenceAction action )
|
void TriggerAllBefore( SequenceAction action )
|
||||||
{
|
{
|
||||||
var actionIndex = actions.IndexOf( action );
|
var actionIndex = actions.IndexOf( action );
|
||||||
|
|
||||||
for ( int i = actionIndex - 1; i >= 0; i -- )
|
for ( int i = actionIndex - 1; i >= 0; i -- )
|
||||||
{
|
{
|
||||||
if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
||||||
|
|
||||||
Actions.Trigger( actions[ i ] );
|
Action.Trigger( actions[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriggerAllAfter( RJSequenceAction action )
|
void TriggerAllAfter( SequenceAction action )
|
||||||
{
|
{
|
||||||
var actionIndex = actions.IndexOf( action );
|
var actionIndex = actions.IndexOf( action );
|
||||||
|
|
||||||
for ( int i = actionIndex + 1; i < actions.Count; i ++ )
|
for ( int i = actionIndex + 1; i < actions.Count; i ++ )
|
||||||
{
|
{
|
||||||
if ( typeof( RJSequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
if ( typeof( SequenceAction ).IsAssignableFrom( actions[ i ].GetType() ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
RJLog.Log( "Triggering Action", actions[ i ].Name );
|
||||||
Actions.Trigger( actions[ i ] );
|
Action.Trigger( actions[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -187,30 +188,30 @@ namespace Rokojori
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/RJActionSequence.svg") ]
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/ActionSequence.svg") ]
|
||||||
public partial class ActionSequence:RJSequenceAction
|
public partial class ActionSequence:SequenceAction
|
||||||
{
|
{
|
||||||
/** <summary for="field actions">Actions to execute</summary>*/
|
/** <summary for="field actions">Actions to execute</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction[] actions;
|
public Action[] actions;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool triggerDirectChildren = true;
|
public bool triggerDirectChildren = true;
|
||||||
|
|
||||||
List<ActionSequenceRunner> running = new List<ActionSequenceRunner>();
|
List<ActionSequenceRunner> running = new List<ActionSequenceRunner>();
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
var run = new ActionSequenceRunner();
|
var run = new ActionSequenceRunner();
|
||||||
run.sequence = this;
|
run.sequence = this;
|
||||||
run.actions = new List<RJAction>( actions );
|
run.actions = new List<Action>( actions );
|
||||||
|
|
||||||
if ( triggerDirectChildren )
|
if ( triggerDirectChildren )
|
||||||
{
|
{
|
||||||
Nodes.ForEachDirectChild<RJAction>( this, a => run.actions.Add( a ) );
|
Nodes.ForEachDirectChild<Action>( this, a => run.actions.Add( a ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
run.sequencables = Lists.FilterType<RJAction,RJSequenceAction>( run.actions );
|
run.sequencables = Lists.FilterType<Action,SequenceAction>( run.actions );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Rokojori
|
|
||||||
{
|
|
||||||
public class Actions
|
|
||||||
{
|
|
||||||
public static void Trigger( RJAction action )
|
|
||||||
{
|
|
||||||
if ( action == null )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
action.Trigger();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TriggerAll( RJAction[] actions, Node target, bool triggerDirectChildren )
|
|
||||||
{
|
|
||||||
if ( actions != null )
|
|
||||||
{
|
|
||||||
for ( int i = 0; i < actions.Length; i++ )
|
|
||||||
{
|
|
||||||
Actions.Trigger( actions[ i ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! triggerDirectChildren )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nodes.ForEachDirectChild<RJAction>( target, a => Actions.Trigger( a ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void TriggerAll( RJAction action, Node target, bool triggerDirectChildren )
|
|
||||||
{
|
|
||||||
if ( action != null )
|
|
||||||
{
|
|
||||||
Actions.Trigger( action );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! triggerDirectChildren )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Nodes.ForEachDirectChild<RJAction>( target, a => Actions.Trigger( a ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Delay : RJSequenceAction
|
public partial class Delay : SequenceAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public float duration;
|
public float duration;
|
||||||
|
@ -14,10 +14,10 @@ namespace Rokojori
|
||||||
public string message;
|
public string message;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJTimeLine timeLine;
|
public TimeLine timeLine;
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
var sequenceID = DispatchStart();
|
var sequenceID = DispatchStart();
|
||||||
|
|
||||||
|
|
|
@ -5,15 +5,15 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class IterateActions : RJAction
|
public partial class IterateActions : Action
|
||||||
{
|
{
|
||||||
[ExportGroup( "Read Only")]
|
[ExportGroup( "Read Only")]
|
||||||
[Export]
|
[Export]
|
||||||
public int iterationIndex = 0;
|
public int iterationIndex = 0;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
var num = this.NumDirectChildrenOf<RJAction>();
|
var num = this.NumDirectChildrenOf<Action>();
|
||||||
|
|
||||||
if ( num == 0 )
|
if ( num == 0 )
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ namespace Rokojori
|
||||||
|
|
||||||
iterationIndex = MathX.Repeat( iterationIndex, num );
|
iterationIndex = MathX.Repeat( iterationIndex, num );
|
||||||
|
|
||||||
Actions.Trigger( this.GetNthDirectChild<RJAction>( iterationIndex ) );
|
Action.Trigger( this.GetNthDirectChild<Action>( iterationIndex ) );
|
||||||
|
|
||||||
iterationIndex++;
|
iterationIndex++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class LoadScene : RJSequenceAction
|
public partial class LoadScene : SequenceAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public string scenePath;
|
public string scenePath;
|
||||||
|
@ -14,13 +14,13 @@ namespace Rokojori
|
||||||
public Node target;
|
public Node target;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onLoaded;
|
public Action onLoaded;
|
||||||
|
|
||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
int _id = -1;
|
int _id = -1;
|
||||||
List<int> _cached = new List<int>();
|
List<int> _cached = new List<int>();
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( _loading )
|
if ( _loading )
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,7 @@ namespace Rokojori
|
||||||
var packedScene = (PackedScene) ResourceLoader.LoadThreadedGet( scenePath );
|
var packedScene = (PackedScene) ResourceLoader.LoadThreadedGet( scenePath );
|
||||||
var node = packedScene.Instantiate();
|
var node = packedScene.Instantiate();
|
||||||
target.AddChild( node );
|
target.AddChild( node );
|
||||||
Actions.Trigger( onLoaded );
|
Action.Trigger( onLoaded );
|
||||||
DispatchEnd( _id );
|
DispatchEnd( _id );
|
||||||
_id = -1;
|
_id = -1;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ namespace Rokojori
|
||||||
( c )=>
|
( c )=>
|
||||||
{
|
{
|
||||||
target.AddChild( packedScene.Instantiate() );
|
target.AddChild( packedScene.Instantiate() );
|
||||||
Actions.Trigger( onLoaded );
|
Action.Trigger( onLoaded );
|
||||||
DispatchEnd( c );
|
DispatchEnd( c );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class SetNodeState : RJAction
|
public partial class SetNodeState : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node[] enable;
|
public Node[] enable;
|
||||||
|
@ -14,7 +14,7 @@ namespace Rokojori
|
||||||
public Node[] disable;
|
public Node[] disable;
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
Arrays.ForEach( enable, n => NodeState.Enable( n ) );
|
Arrays.ForEach( enable, n => NodeState.Enable( n ) );
|
||||||
Arrays.ForEach( disable, n => NodeState.Disable( n ) );
|
Arrays.ForEach( disable, n => NodeState.Disable( n ) );
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class CopyMousePosition : RJAction
|
public partial class CopyMousePosition : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Camera3D camera;
|
public Camera3D camera;
|
||||||
|
@ -17,7 +17,7 @@ namespace Rokojori
|
||||||
public Node3D target;
|
public Node3D target;
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( camera == null || target == null )
|
if ( camera == null || target == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass, Tool ]
|
[GlobalClass, Tool ]
|
||||||
public partial class CopyPose : RJAction
|
public partial class CopyPose : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D source;
|
public Node3D source;
|
||||||
|
@ -20,7 +20,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( source == null || target == null )
|
if ( source == null || target == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass, Tool ]
|
[GlobalClass, Tool ]
|
||||||
public partial class CopyPosition : RJAction
|
public partial class CopyPosition : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D source;
|
public Node3D source;
|
||||||
|
@ -20,7 +20,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( source == null || target == null )
|
if ( source == null || target == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass, Tool ]
|
[GlobalClass, Tool ]
|
||||||
public partial class DistributeChildren : RJAction
|
public partial class DistributeChildren : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D target;
|
public Node3D target;
|
||||||
|
@ -23,7 +23,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( start == null || end == null || target == null )
|
if ( start == null || end == null || target == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class LerpPosition : RJAction
|
public partial class LerpPosition : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D sourceA;
|
public Node3D sourceA;
|
||||||
|
@ -18,7 +18,7 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D target;
|
public Node3D target;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( sourceA == null || sourceB == null || target == null )
|
if ( sourceA == null || sourceB == null || target == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass, Tool ]
|
[GlobalClass, Tool ]
|
||||||
public partial class LookAt : RJAction
|
public partial class LookAt : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D lookTarget;
|
public Node3D lookTarget;
|
||||||
|
@ -17,7 +17,7 @@ namespace Rokojori
|
||||||
_OnTrigger();
|
_OnTrigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( lookFrom == null || lookTarget == null )
|
if ( lookFrom == null || lookTarget == null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,15 +9,15 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
/** <summary for="field actions">Actions to execute</summary>*/
|
/** <summary for="field actions">Actions to execute</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction[] actions;
|
public Action[] actions;
|
||||||
|
|
||||||
/** <summary for="field triggerDirectChildren">Whether to execute RJAction child nodes</summary>*/
|
/** <summary for="field triggerDirectChildren">Whether to execute Action child nodes</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public bool triggerDirectChildren = true;
|
public bool triggerDirectChildren = true;
|
||||||
|
|
||||||
public override void _PhysicsProcess( double delta )
|
public override void _PhysicsProcess( double delta )
|
||||||
{
|
{
|
||||||
Actions.TriggerAll( actions, this, triggerDirectChildren );
|
Action.TriggerAll( actions, this, triggerDirectChildren );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,9 +9,9 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
/** <summary for="field actions">Actions to execute</summary>*/
|
/** <summary for="field actions">Actions to execute</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction[] actions;
|
public Action[] actions;
|
||||||
|
|
||||||
/** <summary for="field triggerDirectChildren">Whether to execute RJAction child nodes</summary>*/
|
/** <summary for="field triggerDirectChildren">Whether to execute Action child nodes</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public bool triggerDirectChildren = true;
|
public bool triggerDirectChildren = true;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Actions.TriggerAll( actions, this, triggerDirectChildren );
|
Action.TriggerAll( actions, this, triggerDirectChildren );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,15 +9,15 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
/** <summary for="field actions">Actions to execute</summary>*/
|
/** <summary for="field actions">Actions to execute</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction[] actions;
|
public Action[] actions;
|
||||||
|
|
||||||
/** <summary for="field triggerDirectChildren">Whether to execute RJAction child nodes</summary>*/
|
/** <summary for="field triggerDirectChildren">Whether to execute Action child nodes</summary>*/
|
||||||
[Export]
|
[Export]
|
||||||
public bool triggerDirectChildren = true;
|
public bool triggerDirectChildren = true;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
Actions.TriggerAll( actions, this, triggerDirectChildren );
|
Action.TriggerAll( actions, this, triggerDirectChildren );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,12 +5,12 @@ using Godot;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass ]
|
[GlobalClass ]
|
||||||
public partial class RJLogMessage : RJAction
|
public partial class RJLogMessage : Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public string message;
|
public string message;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
RJLog.Log( message );
|
RJLog.Log( message );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public class SequenceActionFinishedEvent
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
public bool success;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalClass ]
|
||||||
|
public partial class SequenceAction : Action
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
int dispatchStart();
|
||||||
|
void dispatchCancelled( int id );
|
||||||
|
void dispatchEnd( int id );
|
||||||
|
|
||||||
|
int getLastSequenceActionID();
|
||||||
|
GDVIRTUAL1( cancelAction, int );
|
||||||
|
|
||||||
|
/* signal onSequenceDone * /
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int _dispatchCounter = 0;
|
||||||
|
|
||||||
|
public int GetLastSequenceActionID()
|
||||||
|
{
|
||||||
|
return _dispatchCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly EventSlot<SequenceActionFinishedEvent> onSequenceDone = new EventSlot<SequenceActionFinishedEvent>();
|
||||||
|
|
||||||
|
public int DispatchStart()
|
||||||
|
{
|
||||||
|
_dispatchCounter ++;
|
||||||
|
return _dispatchCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DispatchEnd( int id )
|
||||||
|
{
|
||||||
|
onSequenceDone.DispatchEvent( new SequenceActionFinishedEvent{ id = id, success = true } );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DispatchCancelled( int id )
|
||||||
|
{
|
||||||
|
onSequenceDone.DispatchEvent( new SequenceActionFinishedEvent{ id = id, success = false } );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void CancelAction( int id )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ namespace Rokojori
|
||||||
public partial class TriggerActionInEditor : Node
|
public partial class TriggerActionInEditor : Node
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction action;
|
public Action action;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool execute;
|
public bool execute;
|
||||||
|
|
|
@ -21,6 +21,15 @@ namespace Rokojori
|
||||||
|
|
||||||
public class AnimationMember
|
public class AnimationMember
|
||||||
{
|
{
|
||||||
|
public static readonly AnimationMember Position = new AnimationMember( "position" );
|
||||||
|
public static readonly AnimationMember Rotation = new AnimationMember( "rotation" );
|
||||||
|
public static readonly AnimationMember Scale = new AnimationMember( "scale" );
|
||||||
|
|
||||||
|
public static readonly AnimationMember[] Transform = new AnimationMember[]
|
||||||
|
{
|
||||||
|
AnimationMember.Position, AnimationMember.Rotation, AnimationMember.Scale
|
||||||
|
};
|
||||||
|
|
||||||
string _name;
|
string _name;
|
||||||
public string name => _name;
|
public string name => _name;
|
||||||
|
|
||||||
|
@ -34,13 +43,11 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
static MultiMap<Node,string,Animator> _animating = new MultiMap<Node,string,Animator>();
|
static MultiMap<Node,string,Animator> _animating = new MultiMap<Node,string,Animator>();
|
||||||
|
|
||||||
public static AnimationMember position = new AnimationMember( "position" );
|
|
||||||
public static AnimationMember rotation = new AnimationMember( "rotation" );
|
|
||||||
public static AnimationMember scale = new AnimationMember( "scale" );
|
|
||||||
|
|
||||||
public static Animator GetAnimator( Node node, AnimationMember member )
|
public static Animator GetAnimator( Node node, AnimationMember member )
|
||||||
{
|
{
|
||||||
return _animating[ node ][ member.name ];
|
return _animating.Get( node, member.name );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsAnimating( Animator animator, Node node, AnimationMember member )
|
public static bool IsAnimating( Animator animator, Node node, AnimationMember member )
|
||||||
|
@ -48,6 +55,32 @@ namespace Rokojori
|
||||||
return GetAnimator( node, member ) == animator;
|
return GetAnimator( node, member ) == animator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsAnimating( Animator animator, Node node, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < members.Length; i++ )
|
||||||
|
{
|
||||||
|
if ( ! IsAnimating( animator, node, members[ i ] ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return members.Length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsAnimating( Animator animator, Node[] nodes, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < nodes.Length; i++ )
|
||||||
|
{
|
||||||
|
if ( ! IsAnimating( animator, nodes[ i ], members ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes.Length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static void StartAnimation( Animator animator, Node node, AnimationMember member )
|
public static void StartAnimation( Animator animator, Node node, AnimationMember member )
|
||||||
{
|
{
|
||||||
var activeAnimator = GetAnimator( node, member );
|
var activeAnimator = GetAnimator( node, member );
|
||||||
|
@ -61,6 +94,22 @@ namespace Rokojori
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void StartAnimation( Animator animator, Node node, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < members.Length; i++ )
|
||||||
|
{
|
||||||
|
StartAnimation( animator, node, members[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartAnimation( Animator animator, Node[] nodes, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < nodes.Length; i++ )
|
||||||
|
{
|
||||||
|
StartAnimation( animator, nodes[ i ], members );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void EndAnimation( Animator animator, Node node, AnimationMember member )
|
public static void EndAnimation( Animator animator, Node node, AnimationMember member )
|
||||||
{
|
{
|
||||||
var activeAnimator = GetAnimator( node, member );
|
var activeAnimator = GetAnimator( node, member );
|
||||||
|
@ -70,5 +119,21 @@ namespace Rokojori
|
||||||
activeAnimator.OnAnimatorCancel();
|
activeAnimator.OnAnimatorCancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void EndAnimation( Animator animator, Node node, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < members.Length; i++ )
|
||||||
|
{
|
||||||
|
EndAnimation( animator, node, members[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void EndAnimation( Animator animator, Node[] nodes, params AnimationMember[] members )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < nodes.Length; i++ )
|
||||||
|
{
|
||||||
|
EndAnimation( animator, nodes[ i ], members );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Flash:RJSequenceAction
|
public partial class Flash:SequenceAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public FlashEffect flashEffect;
|
public FlashEffect flashEffect;
|
||||||
|
@ -41,22 +41,27 @@ namespace Rokojori
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( actionID != -1 )
|
if ( actionID != -1 )
|
||||||
{
|
{
|
||||||
CancelAction( actionID );
|
CancelAction( actionID );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
actionID = DispatchStart();
|
actionID = DispatchStart();
|
||||||
|
|
||||||
// RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() );
|
var random = LCG.Randomized();
|
||||||
|
|
||||||
|
var networkSeed = random.GetSeed();
|
||||||
|
|
||||||
|
RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() );
|
||||||
|
|
||||||
var flashCurve = flashEffect.flashCurve;
|
var flashCurve = flashEffect.flashCurve;
|
||||||
var color = flashEffect.color.GetHDRColor();
|
var color = flashEffect.color.GetHDRColor();
|
||||||
var timeline = flashEffect.timeline;
|
var timeline = flashEffect.timeline;
|
||||||
|
|
||||||
randomization = flashCurve.Randomize();
|
randomization = flashCurve.Randomize( random );
|
||||||
var duration = flashCurve.GetRandomizedDuration( randomization );
|
var duration = flashCurve.GetRandomizedDuration( randomization );
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +144,7 @@ namespace Rokojori
|
||||||
var end = start + duration;
|
var end = start + duration;
|
||||||
|
|
||||||
animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
||||||
( int id, int type )=>
|
( int id, TimeLineSpanUpdateType type )=>
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( animationID != id )
|
if ( animationID != id )
|
||||||
|
@ -196,7 +201,7 @@ namespace Rokojori
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if ( type == TimeLineSpan.End )
|
if ( type == TimeLineSpanUpdateType.End )
|
||||||
{
|
{
|
||||||
if ( light != null )
|
if ( light != null )
|
||||||
{
|
{
|
|
@ -15,6 +15,10 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public AnimationCurve flashCurve;
|
public AnimationCurve flashCurve;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public TimeLine timeline;
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public HDRColor color;
|
public HDRColor color;
|
||||||
|
|
||||||
|
@ -61,8 +65,7 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public ColorPropertyName customFlashColorProperty;
|
public ColorPropertyName customFlashColorProperty;
|
||||||
|
|
||||||
[Export]
|
|
||||||
public RJTimeLine timeline;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_ejko8"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_ejko8"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_3i2og"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_3i2og"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_65ipm"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_65ipm"]
|
||||||
[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_urqjo"]
|
[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_nyaof"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_54hj8"]
|
[sub_resource type="Resource" id="Resource_54hj8"]
|
||||||
script = ExtResource("1_ejko8")
|
script = ExtResource("1_ejko8")
|
||||||
|
@ -29,10 +29,10 @@ scaleRandomRange = 0.0
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_65ipm")
|
script = ExtResource("3_65ipm")
|
||||||
flashCurve = SubResource("Resource_pwp07")
|
flashCurve = SubResource("Resource_pwp07")
|
||||||
|
timeline = ExtResource("4_nyaof")
|
||||||
color = SubResource("Resource_54hj8")
|
color = SubResource("Resource_54hj8")
|
||||||
lightMode = 1
|
lightMode = 1
|
||||||
lightRange = 5.0
|
lightRange = 5.0
|
||||||
lightFlashCurveScale = 5.0
|
lightFlashCurveScale = 5.0
|
||||||
lightHasShadows = true
|
lightHasShadows = true
|
||||||
materialMode = 3
|
materialMode = 3
|
||||||
timeline = ExtResource("4_urqjo")
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_yrhv1"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_yrhv1"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_cdv3p"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_cdv3p"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_87ql1"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_87ql1"]
|
||||||
[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_t20yf"]
|
[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_2na64"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_54hj8"]
|
[sub_resource type="Resource" id="Resource_54hj8"]
|
||||||
script = ExtResource("1_yrhv1")
|
script = ExtResource("1_yrhv1")
|
||||||
|
@ -29,10 +29,10 @@ scaleRandomRange = 0.0
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_87ql1")
|
script = ExtResource("3_87ql1")
|
||||||
flashCurve = SubResource("Resource_pwp07")
|
flashCurve = SubResource("Resource_pwp07")
|
||||||
|
timeline = ExtResource("4_2na64")
|
||||||
color = SubResource("Resource_54hj8")
|
color = SubResource("Resource_54hj8")
|
||||||
lightMode = 1
|
lightMode = 1
|
||||||
lightRange = 5.0
|
lightRange = 5.0
|
||||||
lightFlashCurveScale = 2.0
|
lightFlashCurveScale = 2.0
|
||||||
lightHasShadows = true
|
lightHasShadows = true
|
||||||
materialMode = 2
|
materialMode = 2
|
||||||
timeline = ExtResource("4_t20yf")
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_c8lnw"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_c8lnw"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_w323b"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_w323b"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_eqd4c"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_eqd4c"]
|
||||||
[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_03b60"]
|
[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_cs6ks"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ny3sx"]
|
[sub_resource type="Resource" id="Resource_ny3sx"]
|
||||||
script = ExtResource("1_c8lnw")
|
script = ExtResource("1_c8lnw")
|
||||||
|
@ -29,10 +29,10 @@ scaleRandomRange = 0.0
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_eqd4c")
|
script = ExtResource("3_eqd4c")
|
||||||
flashCurve = SubResource("Resource_pwp07")
|
flashCurve = SubResource("Resource_pwp07")
|
||||||
|
timeline = ExtResource("4_cs6ks")
|
||||||
color = SubResource("Resource_ny3sx")
|
color = SubResource("Resource_ny3sx")
|
||||||
lightMode = 1
|
lightMode = 1
|
||||||
lightRange = 4.0
|
lightRange = 4.0
|
||||||
lightFlashCurveScale = 1.0
|
lightFlashCurveScale = 1.0
|
||||||
lightHasShadows = false
|
lightHasShadows = false
|
||||||
materialMode = 1
|
materialMode = 1
|
||||||
timeline = ExtResource("4_03b60")
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_nmdum"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_nmdum"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_0sgd7"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_0sgd7"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_7qcuh"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_7qcuh"]
|
||||||
[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_8oykd"]
|
[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_rkq1j"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_54hj8"]
|
[sub_resource type="Resource" id="Resource_54hj8"]
|
||||||
script = ExtResource("1_nmdum")
|
script = ExtResource("1_nmdum")
|
||||||
|
@ -29,6 +29,10 @@ scaleRandomRange = 0.0
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_7qcuh")
|
script = ExtResource("3_7qcuh")
|
||||||
flashCurve = SubResource("Resource_pwp07")
|
flashCurve = SubResource("Resource_pwp07")
|
||||||
|
timeline = ExtResource("4_rkq1j")
|
||||||
color = SubResource("Resource_54hj8")
|
color = SubResource("Resource_54hj8")
|
||||||
|
lightMode = 0
|
||||||
|
lightRange = 2.0
|
||||||
|
lightFlashCurveScale = 2.0
|
||||||
|
lightHasShadows = false
|
||||||
materialMode = 0
|
materialMode = 0
|
||||||
timeline = ExtResource("4_8oykd")
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_pp4qy"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/HDRColor.cs" id="1_pp4qy"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_f6f0o"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_f6f0o"]
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/FlashEffect.cs" id="3_dq1j1"]
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Flash/FlashEffect.cs" id="3_dq1j1"]
|
||||||
[ext_resource type="RJTimeLine" uid="uid://frruktikky46" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_v17wj"]
|
[ext_resource type="Resource" uid="uid://ch5nsa6yafs5l" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/GameTime.tres" id="4_d6hj6"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ny3sx"]
|
[sub_resource type="Resource" id="Resource_ny3sx"]
|
||||||
script = ExtResource("1_pp4qy")
|
script = ExtResource("1_pp4qy")
|
||||||
|
@ -29,10 +29,10 @@ scaleRandomRange = 0.0
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("3_dq1j1")
|
script = ExtResource("3_dq1j1")
|
||||||
flashCurve = SubResource("Resource_pwp07")
|
flashCurve = SubResource("Resource_pwp07")
|
||||||
|
timeline = ExtResource("4_d6hj6")
|
||||||
color = SubResource("Resource_ny3sx")
|
color = SubResource("Resource_ny3sx")
|
||||||
lightMode = 0
|
lightMode = 0
|
||||||
lightRange = 2.0
|
lightRange = 2.0
|
||||||
lightFlashCurveScale = 2.0
|
lightFlashCurveScale = 2.0
|
||||||
lightHasShadows = false
|
lightHasShadows = false
|
||||||
materialMode = 0
|
materialMode = 0
|
||||||
timeline = ExtResource("4_v17wj")
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class KeyFrame<T>
|
||||||
|
{
|
||||||
|
public float time;
|
||||||
|
public T data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class KeyFrameAnimation<T>
|
||||||
|
{
|
||||||
|
public List<KeyFrame<T>> keyFrames = new List<KeyFrame<T>>();
|
||||||
|
|
||||||
|
int _currentIndex = -1;
|
||||||
|
bool _sorted = false;
|
||||||
|
|
||||||
|
public void FlagUnsorted()
|
||||||
|
{
|
||||||
|
_sorted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FlagSorted()
|
||||||
|
{
|
||||||
|
_sorted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Sort()
|
||||||
|
{
|
||||||
|
if ( _sorted )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyFrames.Sort( ( a, b ) => Mathf.Sign( a.time - b.time ) );
|
||||||
|
|
||||||
|
_sorted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyFrame<T> GetKeyFrameAt( float time )
|
||||||
|
{
|
||||||
|
var index = GetKeyFrameIndexAt( time );
|
||||||
|
|
||||||
|
return index == -1 ? null : keyFrames[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetKeyFrameIndexAt( float time )
|
||||||
|
{
|
||||||
|
if ( keyFrames.Count == 0 )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sort();
|
||||||
|
|
||||||
|
for ( int i = 0; i < keyFrames.Count; i++ )
|
||||||
|
{
|
||||||
|
if ( keyFrames[ i ].time > time )
|
||||||
|
{
|
||||||
|
return Mathf.Max( 0, i - 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _sorted )
|
||||||
|
{
|
||||||
|
return keyFrames.Count - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
||||||
|
{
|
||||||
|
return _currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentIndex = MathX.SafeIndex( _currentIndex, keyFrames );
|
||||||
|
|
||||||
|
var kf = keyFrames[ _currentIndex ];
|
||||||
|
|
||||||
|
if ( kf.time < time )
|
||||||
|
{
|
||||||
|
_currentIndex ++;
|
||||||
|
|
||||||
|
while ( _currentIndex < keyFrames.Count )
|
||||||
|
{
|
||||||
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
||||||
|
{
|
||||||
|
return _currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentIndex ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_currentIndex --;
|
||||||
|
|
||||||
|
while ( _currentIndex > -1 )
|
||||||
|
{
|
||||||
|
if ( IsKeyFrameAt( time, _currentIndex ) )
|
||||||
|
{
|
||||||
|
return _currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentIndex --;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsKeyFrameAt( float time, int index )
|
||||||
|
{
|
||||||
|
if ( index < 0 || index >= keyFrames.Count -1 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = keyFrames[ index ];
|
||||||
|
|
||||||
|
if ( i.time < time && index == keyFrames.Count - 1 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var n = keyFrames[ index + 1 ];
|
||||||
|
|
||||||
|
return i.time < time && time < n.time;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
[gd_resource type="Resource" script_class="ShakeEffect" load_steps=8 format=3 uid="uid://c2wbn25rxynk8"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/Shake/ShakeEffect.cs" id="1_41sot"]
|
||||||
|
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Animation/AnimationCurve.cs" id="2_rwbu4"]
|
||||||
|
[ext_resource type="Resource" uid="uid://h6oi6vkj4c2m" path="res://addons/rokojori_action_library/Runtime/Time/TimeLines/RealTime.tres" id="3_rqeiy"]
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_j2uji"]
|
||||||
|
min_value = -1.0
|
||||||
|
_data = [Vector2(0, 1), 0.0, -0.608916, 0, 0, Vector2(1, -1), -3.46819, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_jwnpm"]
|
||||||
|
script = ExtResource("2_rwbu4")
|
||||||
|
duration = 0.4
|
||||||
|
durationRandomRange = 0.0
|
||||||
|
delay = 0.0
|
||||||
|
delayRandomRange = 0.0
|
||||||
|
curve = SubResource("Curve_j2uji")
|
||||||
|
scaleY = 1.0
|
||||||
|
scaleRandomRange = 0.0
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_b6b7u"]
|
||||||
|
_data = [Vector2(0, 0.368339), 0.0, 3.25035, 0, 0, Vector2(0.264591, 0.73511), 0.0, 0.0, 0, 0, Vector2(1, 0.266458), -0.637268, 0.0, 1, 0]
|
||||||
|
point_count = 3
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_1s2e6"]
|
||||||
|
script = ExtResource("2_rwbu4")
|
||||||
|
duration = 0.5
|
||||||
|
durationRandomRange = 0.0
|
||||||
|
delay = 0.0
|
||||||
|
delayRandomRange = 0.0
|
||||||
|
curve = SubResource("Curve_b6b7u")
|
||||||
|
scaleY = 30.0
|
||||||
|
scaleRandomRange = 0.0
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_41sot")
|
||||||
|
shakeAmountCurve = SubResource("Resource_jwnpm")
|
||||||
|
shakeChangeFPSCurve = SubResource("Resource_1s2e6")
|
||||||
|
timeline = ExtResource("3_rqeiy")
|
||||||
|
smooth = true
|
||||||
|
smoothingStrength = 0.291
|
||||||
|
positionShake = Vector3(0.075, 0, 0.075)
|
||||||
|
globalPosition = true
|
||||||
|
repeatAndFlipFirstPosition = true
|
||||||
|
rotationShake = Vector3(2, 2, 40)
|
||||||
|
globalRotation = false
|
||||||
|
scaleShake = Vector3(0.5, 0.5, 0.1)
|
||||||
|
scaleShakeIsRelative = true
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Shake:RJSequenceAction
|
public partial class Shake:SequenceAction, Animator
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public ShakeEffect shakeEffect;
|
public ShakeEffect shakeEffect;
|
||||||
|
@ -16,45 +16,159 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D[] targets;
|
public Node3D[] targets;
|
||||||
|
|
||||||
List<Transform3D> _targetValues;
|
List<TransformData> _targetValues;
|
||||||
|
|
||||||
int actionID = -1;
|
int _actionID = -1;
|
||||||
int animationID = -1;
|
int _currentSpanAnimationID = -1;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
public void OnAnimatorStart(){}
|
||||||
|
public void OnAnimatorEnd(){}
|
||||||
|
public void OnAnimatorCancel(){}
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( actionID != -1 )
|
if ( _actionID != -1 )
|
||||||
{
|
{
|
||||||
CancelAction( actionID );
|
CancelAction( _actionID );
|
||||||
}
|
}
|
||||||
|
|
||||||
actionID = DispatchStart();
|
_actionID = DispatchStart();
|
||||||
|
|
||||||
var random = shakeEffect.shakeCurve.Randomize();
|
var random = LCG.Randomized();
|
||||||
|
|
||||||
|
var networkSeed = random.GetSeed();
|
||||||
|
|
||||||
|
var randomization = shakeEffect.shakeAmountCurve.Randomize( random );
|
||||||
var timeline = shakeEffect.timeline;
|
var timeline = shakeEffect.timeline;
|
||||||
|
|
||||||
var duration = shakeEffect.shakeCurve.GetRandomizedEndTime( random );
|
var duration = shakeEffect.shakeAmountCurve.GetRandomizedEndTime( randomization );
|
||||||
|
var curve = shakeEffect;
|
||||||
|
|
||||||
var start = TimeLineManager.GetPosition( shakeEffect.timeline );
|
var start = TimeLineManager.GetPosition( shakeEffect.timeline );
|
||||||
var end = start + duration;
|
|
||||||
|
|
||||||
|
var keyFrames = new List<KeyFrame<TransformData>>();
|
||||||
|
var elapsed = 0f;
|
||||||
|
|
||||||
|
while ( elapsed < duration )
|
||||||
animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
|
||||||
( int id, int type )=>
|
|
||||||
{
|
{
|
||||||
if ( animationID != id )
|
var key = new KeyFrame<TransformData>();
|
||||||
|
key.data = shakeEffect.GetShakeData( elapsed, randomization, random );
|
||||||
|
key.time = elapsed;
|
||||||
|
keyFrames.Add( key );
|
||||||
|
|
||||||
|
elapsed += 1f / shakeEffect.GetShakeChangeFPSRandomized( elapsed, random );
|
||||||
|
}
|
||||||
|
|
||||||
|
var kfAnimation = new KeyFrameAnimation<TransformData>();
|
||||||
|
kfAnimation.keyFrames = keyFrames;
|
||||||
|
kfAnimation.FlagSorted();
|
||||||
|
|
||||||
|
KeyFrame<TransformData> lastKeyFrame = null;
|
||||||
|
|
||||||
|
AnimationManager.StartAnimation( this, targets, AnimationMember.Transform );
|
||||||
|
|
||||||
|
if ( _targetValues == null || _targetValues.Count == 0 )
|
||||||
|
{
|
||||||
|
_targetValues = Lists.Map( targets, t => TransformData.From( t, shakeEffect.globalPosition, shakeEffect.globalRotation ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
_currentSpanAnimationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
||||||
|
( int spanAnimationID, TimeLineSpanUpdateType type )=>
|
||||||
|
{
|
||||||
|
if ( spanAnimationID != _currentSpanAnimationID )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! AnimationManager.IsAnimating( this, targets, AnimationMember.Transform ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( TimeLineSpanUpdateType.End == type )
|
||||||
|
{
|
||||||
|
AnimationManager.EndAnimation( this, targets, AnimationMember.Transform );
|
||||||
|
|
||||||
|
for ( int i = 0; i < targets.Length; i++ )
|
||||||
|
{
|
||||||
|
var o = _targetValues[ i ];
|
||||||
|
|
||||||
|
o.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
_targetValues.Clear();
|
||||||
|
_actionID = -1;
|
||||||
|
_currentSpanAnimationID = -1;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var offset = TimeLineManager.GetPosition( shakeEffect.timeline ) - start;
|
||||||
|
var keyFrame = kfAnimation.GetKeyFrameAt( offset );
|
||||||
|
|
||||||
|
if ( keyFrame == lastKeyFrame && ! shakeEffect.smooth )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var offsetData = keyFrame.data;
|
||||||
|
var delta = shakeEffect.timeline.delta;
|
||||||
|
|
||||||
|
for ( int i = 0; i < targets.Length; i++ )
|
||||||
|
{
|
||||||
|
var combined = offsetData.Clone();
|
||||||
|
|
||||||
|
var o = _targetValues[ i ];
|
||||||
|
|
||||||
|
if ( shakeEffect.scaleShakeIsRelative )
|
||||||
|
{
|
||||||
|
combined.scale *= _targetValues[ i ].scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
combined.rotation *= MathX.DegreesToRadians;
|
||||||
|
|
||||||
|
var beforeAdd = combined.Clone();
|
||||||
|
|
||||||
|
combined.Add( o );
|
||||||
|
|
||||||
|
// this.LogInfo( "Applying:", beforeAdd, " + ", o, "=", combined );
|
||||||
|
|
||||||
|
|
||||||
|
if ( shakeEffect.smooth )
|
||||||
|
{
|
||||||
|
var rawSmooth = Mathf.Clamp( shakeEffect.smoothingStrength, 0, 1 );
|
||||||
|
rawSmooth = Mathf.Pow( 1f - rawSmooth, 3 );
|
||||||
|
var smoothStrength = rawSmooth * 250f;
|
||||||
|
|
||||||
|
var current = TransformData.From( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
|
||||||
|
combined.position = Smoother.SmoothTimeInvariant( current.position, combined.position, delta, smoothStrength );
|
||||||
|
combined.rotation = Smoother.SmoothTimeInvariant( current.rotation, combined.rotation, delta, smoothStrength );
|
||||||
|
combined.scale = Smoother.SmoothTimeInvariant( current.scale, combined.scale, delta, smoothStrength );
|
||||||
|
}
|
||||||
|
|
||||||
|
combined.Set( targets[ i ], shakeEffect.globalPosition, shakeEffect.globalRotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
lastKeyFrame = keyFrame;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CancelAction( int id )
|
public override void CancelAction( int actionID )
|
||||||
{
|
{
|
||||||
|
if ( actionID != _actionID )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimationManager.EndAnimation( this, targets, AnimationMember.Transform );
|
||||||
|
_actionID = -1;
|
||||||
|
_currentSpanAnimationID = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,27 +12,63 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public AnimationCurve shakeCurve;
|
public AnimationCurve shakeAmountCurve;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public AnimationCurve shakeChangeFPSCurve;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public AnimationCurve shakeChangeFPSRandomCurve;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public TimeLine timeline;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool smooth = true;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,1" )]
|
||||||
|
public float smoothingStrength = 0;
|
||||||
|
|
||||||
|
public float GetShakeChangeFPSRandomized( float time, RandomEngine random = null )
|
||||||
|
{
|
||||||
|
random = RandomEngine.CreateIfNull( random );
|
||||||
|
var staticChange = shakeChangeFPSCurve == null ? 10 : shakeChangeFPSCurve.Sample( time );
|
||||||
|
var randomChange = shakeChangeFPSRandomCurve == null ? 0 : shakeChangeFPSRandomCurve.Sample( time );
|
||||||
|
return staticChange + random.Polar( randomChange );
|
||||||
|
}
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 positionShake = Vector3.Zero;
|
public Vector3 positionShake = Vector3.Zero;
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 positionShakeRandom = Vector3.Zero;
|
public bool globalPosition = true;
|
||||||
|
[Export]
|
||||||
|
public bool repeatAndFlipFirstPosition = true;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 rotationShake = Vector3.Zero;
|
public Vector3 rotationShake = Vector3.Zero;
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 rotationShakeRandom = Vector3.Zero;
|
public bool globalRotation = true;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 scaleShake = Vector3.Zero;
|
public Vector3 scaleShake = Vector3.Zero;
|
||||||
[Export]
|
|
||||||
public Vector3 scaleShakeRandom = Vector3.Zero;
|
|
||||||
[Export]
|
|
||||||
public bool scaleIsPercentage = true;
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJTimeLine timeline;
|
public bool scaleShakeIsRelative = true;
|
||||||
|
|
||||||
|
public TransformData GetShakeData( float time, Vector3 curveRandomization, RandomEngine random = null )
|
||||||
|
{
|
||||||
|
random = RandomEngine.CreateIfNull( random );
|
||||||
|
|
||||||
|
var shakeAmount = shakeAmountCurve.Sample( time, curveRandomization );
|
||||||
|
|
||||||
|
var transformData = new TransformData();
|
||||||
|
transformData.position = random.IndividualBetween( -positionShake, positionShake ) * shakeAmount;
|
||||||
|
transformData.rotation = random.IndividualBetween( -rotationShake, rotationShake ) * shakeAmount;
|
||||||
|
transformData.scale = random.IndividualBetween( -scaleShake, scaleShake ) * shakeAmount;
|
||||||
|
|
||||||
|
return transformData;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
[Tool]
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class AnimateTransform:RJSequenceAction, Animator
|
public partial class AnimateTransform:SequenceAction, Animator
|
||||||
{
|
{
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
|
@ -25,7 +25,7 @@ namespace Rokojori
|
||||||
public void OnAnimatorCancel(){}
|
public void OnAnimatorCancel(){}
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
_frameValues = new List<Vector3>();
|
_frameValues = new List<Vector3>();
|
||||||
_randomizations = new List<Vector3>();
|
_randomizations = new List<Vector3>();
|
||||||
|
@ -50,7 +50,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration,
|
||||||
( int id, int type )=>
|
( int id, TimeLineSpanUpdateType type )=>
|
||||||
{
|
{
|
||||||
var timeNow = TimeLineManager.GetPosition( timeline );
|
var timeNow = TimeLineManager.GetPosition( timeline );
|
||||||
var elapsed = timeNow - start;
|
var elapsed = timeNow - start;
|
||||||
|
@ -67,7 +67,7 @@ namespace Rokojori
|
||||||
index ++;
|
index ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( type == TimeLineSpan.End )
|
if ( type == TimeLineSpanUpdateType.End )
|
||||||
{
|
{
|
||||||
foreach ( var c in animations.curves )
|
foreach ( var c in animations.curves )
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Rokojori
|
||||||
public TransformCurve[] curves;
|
public TransformCurve[] curves;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJTimeLine timeline;
|
public TimeLine timeline;
|
||||||
|
|
||||||
public float GetMaxDuration( List<Vector3> randomizations )
|
public float GetMaxDuration( List<Vector3> randomizations )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class TransformData
|
||||||
|
{
|
||||||
|
public Vector3 position;
|
||||||
|
public Vector3 rotation;
|
||||||
|
public Vector3 scale;
|
||||||
|
|
||||||
|
|
||||||
|
public TransformData Clone()
|
||||||
|
{
|
||||||
|
var data = new TransformData();
|
||||||
|
data.position = position;
|
||||||
|
data.rotation = rotation;
|
||||||
|
data.scale = scale;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add( TransformData other )
|
||||||
|
{
|
||||||
|
position += other.position;
|
||||||
|
rotation += other.rotation;
|
||||||
|
scale += other.scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return RJLog.Stringify( position ) + ", " + RJLog.Stringify( rotation ) + ", " + RJLog.Stringify( scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Set( Node3D node, bool globalPosition = true, bool globalRotation = true )
|
||||||
|
{
|
||||||
|
TransformTargets.Set( position, node, TransformTargets.Position( globalPosition ) );
|
||||||
|
TransformTargets.Set( rotation, node, TransformTargets.Rotation( globalRotation ) );
|
||||||
|
TransformTargets.Set( scale, node, TransformTargets.Scale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Get( Node3D node, bool globalPosition = true, bool globalRotation = true )
|
||||||
|
{
|
||||||
|
position = TransformTargets.Get( node, TransformTargets.Position( globalPosition ) );
|
||||||
|
rotation = TransformTargets.Get( node, TransformTargets.Rotation( globalRotation ) );
|
||||||
|
scale = TransformTargets.Get( node, TransformTargets.Scale() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TransformData From( Node3D n, bool globalPosition = true, bool globalRotation = true )
|
||||||
|
{
|
||||||
|
var td = new TransformData();
|
||||||
|
td.Get( n, globalPosition, globalRotation );
|
||||||
|
return td;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -15,23 +15,40 @@ namespace Rokojori
|
||||||
Local_Scale
|
Local_Scale
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class TransformTargets
|
public class TransformTargets
|
||||||
{
|
{
|
||||||
|
public static TransformTarget Position( bool global = true )
|
||||||
|
{
|
||||||
|
return global ? TransformTarget.Global_Position : TransformTarget.Local_Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TransformTarget Rotation( bool global = true )
|
||||||
|
{
|
||||||
|
return global ? TransformTarget.Global_Rotation : TransformTarget.Local_Rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TransformTarget Scale()
|
||||||
|
{
|
||||||
|
return TransformTarget.Local_Scale;
|
||||||
|
}
|
||||||
|
|
||||||
public static AnimationMember ToAnimationMember( TransformTarget target )
|
public static AnimationMember ToAnimationMember( TransformTarget target )
|
||||||
{
|
{
|
||||||
if ( TransformTarget.Local_Position == target || TransformTarget.Global_Position == target )
|
if ( TransformTarget.Local_Position == target || TransformTarget.Global_Position == target )
|
||||||
{
|
{
|
||||||
return AnimationManager.position;
|
return AnimationMember.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TransformTarget.Local_Rotation == target || TransformTarget.Global_Rotation == target )
|
if ( TransformTarget.Local_Rotation == target || TransformTarget.Global_Rotation == target )
|
||||||
{
|
{
|
||||||
return AnimationManager.rotation;
|
return AnimationMember.Rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( TransformTarget.Local_Scale == target )
|
if ( TransformTarget.Local_Scale == target )
|
||||||
{
|
{
|
||||||
return AnimationManager.scale;
|
return AnimationMember.Scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -45,6 +62,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Global_Rotation == transformTarget )
|
else if ( TransformTarget.Global_Rotation == transformTarget )
|
||||||
{
|
{
|
||||||
|
// RJLog.Log( "GlobalRotation => ", target.GlobalRotation );
|
||||||
return target.GlobalRotation;
|
return target.GlobalRotation;
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Position == transformTarget )
|
else if ( TransformTarget.Local_Position == transformTarget )
|
||||||
|
@ -53,6 +71,7 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Rotation == transformTarget )
|
else if ( TransformTarget.Local_Rotation == transformTarget )
|
||||||
{
|
{
|
||||||
|
// RJLog.Log( "Rotation => ", target.Rotation );
|
||||||
return target.Rotation;
|
return target.Rotation;
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Scale == transformTarget )
|
else if ( TransformTarget.Local_Scale == transformTarget )
|
||||||
|
@ -71,7 +90,9 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Global_Rotation == transformTarget )
|
else if ( TransformTarget.Global_Rotation == transformTarget )
|
||||||
{
|
{
|
||||||
|
var rotation = target.GlobalRotation;
|
||||||
target.GlobalRotation = value;
|
target.GlobalRotation = value;
|
||||||
|
// RJLog.Log( "GlobalRotation = ", rotation, ">>", value, target.GlobalRotation );
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Position == transformTarget )
|
else if ( TransformTarget.Local_Position == transformTarget )
|
||||||
{
|
{
|
||||||
|
@ -79,7 +100,9 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Rotation == transformTarget )
|
else if ( TransformTarget.Local_Rotation == transformTarget )
|
||||||
{
|
{
|
||||||
|
var rotation = target.Rotation;
|
||||||
target.Rotation = value;
|
target.Rotation = value;
|
||||||
|
// RJLog.Log( "Rotation = ", rotation, ">>", value, target.Rotation );
|
||||||
}
|
}
|
||||||
else if ( TransformTarget.Local_Scale == transformTarget )
|
else if ( TransformTarget.Local_Scale == transformTarget )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class FadeWipeEffect:TextureWipeEffect
|
||||||
|
{
|
||||||
|
public override void Assign( ColorRect colorRect )
|
||||||
|
{
|
||||||
|
var material = new FadeWipeMaterial();
|
||||||
|
colorRect.Material = material;
|
||||||
|
|
||||||
|
base.Assign( colorRect );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class TextureWipeEffect:WipeEffect
|
||||||
|
{
|
||||||
|
[ExportGroup("Texture")]
|
||||||
|
[Export]
|
||||||
|
public Texture2D texture;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Gradient tint;
|
||||||
|
|
||||||
|
[ExportGroup("Texture Transform")]
|
||||||
|
[Export]
|
||||||
|
public Curve rotation = MathX.Curve( 0, 0 );
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Curve scale = MathX.Curve( 1, 1 );
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Curve translationX = MathX.Curve( 0, 0 );
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Curve translationY = MathX.Curve( 0, 0 );
|
||||||
|
|
||||||
|
[ExportGroup("Texture Transform Centers")]
|
||||||
|
[Export]
|
||||||
|
public Vector2 rotationCenter = new Vector2( 0.5f, 0.5f );
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Vector2 scaleCenter = new Vector2( 0.5f, 0.5f );
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly Texture2DPropertyName _wipeTextureProperty = Texture2DPropertyName.Create( "wipeTexture" );
|
||||||
|
public static readonly Vector2PropertyName _outputViewSizeProperty = Vector2PropertyName.Create( "outputViewSize" );
|
||||||
|
public static readonly Vector2PropertyName _wipeTextureSizeProperty = Vector2PropertyName.Create( "wipeTextureSize" );
|
||||||
|
public static readonly Vector2PropertyName _uvRotationCenterProperty = Vector2PropertyName.Create( "uvRotationCenter" );
|
||||||
|
public static readonly Vector2PropertyName _uvScaleCenterPropery = Vector2PropertyName.Create( "uvScaleCenter" );
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly ColorPropertyName _wipeTextureTintProperty = ColorPropertyName.Create( "wipeTextureTint" );
|
||||||
|
public static readonly FloatPropertyName _uvRotationProperty = FloatPropertyName.Create( "uvRotation" );
|
||||||
|
public static readonly FloatPropertyName _uvScaleProperty = FloatPropertyName.Create( "uvScale" );
|
||||||
|
public static readonly Vector2PropertyName _uvTranslationProperty = Vector2PropertyName.Create( "uvTranslation" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public override void Assign( ColorRect colorRect )
|
||||||
|
{
|
||||||
|
if ( colorRect == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var material = GetMaterial( colorRect );
|
||||||
|
|
||||||
|
if ( texture != null )
|
||||||
|
{
|
||||||
|
_wipeTextureProperty.Set( material, texture );
|
||||||
|
_wipeTextureSizeProperty.Set( material, texture.GetSize() );
|
||||||
|
|
||||||
|
_uvRotationCenterProperty.Set( material, rotationCenter );
|
||||||
|
_uvScaleCenterPropery.Set( material, scaleCenter );
|
||||||
|
}
|
||||||
|
|
||||||
|
_outputViewSizeProperty.Set( material, colorRect.GetViewportRect().Size );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetWipeState( float state, ColorRect target )
|
||||||
|
{
|
||||||
|
if ( target == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var material = GetMaterial( target );
|
||||||
|
|
||||||
|
_wipeTextureTintProperty.Set( material, tint.Sample( state ) );
|
||||||
|
_uvRotationProperty.Set( material, rotation.Sample( state ) );
|
||||||
|
_uvScaleProperty.Set( material, rotation.Sample( state ) );
|
||||||
|
_uvTranslationProperty.Set( material, new Vector2( translationX.Sample( state ), translationY.Sample( state ) ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class Wipe:SequenceAction
|
||||||
|
{
|
||||||
|
public enum Direction
|
||||||
|
{
|
||||||
|
In,
|
||||||
|
Out,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Direction direction;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float duration;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public TimeLine timeLine;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public WipeEffect wipeEffect;
|
||||||
|
|
||||||
|
[ExportGroup("Target Overwrite")]
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public ColorRect targetOverwriteColorRect;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Selector targetOverwriteSelector;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node targetOverwriteRoot;
|
||||||
|
|
||||||
|
int _actionID = -1;
|
||||||
|
int _animationID = -1;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
if ( _actionID != -1 )
|
||||||
|
{
|
||||||
|
CancelAction( _actionID );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CancelAction( int id )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class WipeEffect:Resource
|
||||||
|
{
|
||||||
|
public static readonly FloatPropertyName wipeState = FloatPropertyName.Create( "wipeState" );
|
||||||
|
|
||||||
|
[ExportGroup("Target")]
|
||||||
|
[Export]
|
||||||
|
public Selector selector;
|
||||||
|
|
||||||
|
|
||||||
|
public ShaderMaterial GetMaterial( ColorRect rect )
|
||||||
|
{
|
||||||
|
return rect.Material as ShaderMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Assign( ColorRect colorRect )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SetWipeState( float state, ColorRect target )
|
||||||
|
{}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class BitMath
|
||||||
|
{
|
||||||
|
public static int GetInt32BitMask( int bit )
|
||||||
|
{
|
||||||
|
return ( 1 << bit );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int SetBit( int value, int bitPosition )
|
||||||
|
{
|
||||||
|
return value | GetInt32BitMask( bitPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int UnsetBit( int value, int bitPosition )
|
||||||
|
{
|
||||||
|
return value & ~GetInt32BitMask( bitPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsBitSet( int value, int bitPosition )
|
||||||
|
{
|
||||||
|
var mask = GetInt32BitMask( bitPosition );
|
||||||
|
return ( value & mask ) == mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetTransform: NetClassDefinition
|
||||||
|
{
|
||||||
|
public readonly NetVector3 position = new NetVector3( Vector3.Zero );
|
||||||
|
public readonly NetQuaternion rotation = new NetQuaternion( Quaternion.Identity );
|
||||||
|
public readonly NetVector3 scale = new NetVector3( Vector3.One );
|
||||||
|
|
||||||
|
public NetTransform()
|
||||||
|
{
|
||||||
|
SetMembers( position, rotation, scale );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetMovementData: NetClassDefinition
|
||||||
|
{
|
||||||
|
public readonly NetClass<NetTransform> transform = new NetClass<NetTransform>(
|
||||||
|
new NetTransform()
|
||||||
|
);
|
||||||
|
|
||||||
|
public readonly NetInt id = new NetInt( -1 );
|
||||||
|
|
||||||
|
public NetMovementData()
|
||||||
|
{
|
||||||
|
SetMembers( transform, id );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class BitViewTest : Action
|
||||||
|
{
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
TestSingleBitWriting();
|
||||||
|
TestByteWriting();
|
||||||
|
TestIntVL8Writing();
|
||||||
|
TestClassWriting();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TestSingleBitWriting()
|
||||||
|
{
|
||||||
|
RJLog.Log( "----- TestSingleBitWriting -------" );
|
||||||
|
|
||||||
|
var bitView = BitView.CreateEmpty();
|
||||||
|
var numBits = 21;
|
||||||
|
|
||||||
|
for ( int i = 0; i < numBits; i++ )
|
||||||
|
{
|
||||||
|
bitView.WriteBit( i % 2 == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
LogAndTestReversal( bitView );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TestClassWriting()
|
||||||
|
{
|
||||||
|
RJLog.Log( "----- TestClassWriting -------" );
|
||||||
|
|
||||||
|
var bitView = BitView.CreateEmpty();
|
||||||
|
bitView.WriteBit( true );
|
||||||
|
bitView.WriteFloat( -1234.567f );
|
||||||
|
|
||||||
|
var trsf = new NetTransform();
|
||||||
|
trsf.position.value = new Vector3( 1, 2, 3 );
|
||||||
|
trsf.rotation.value = Quaternion.FromEuler( new Vector3( 0, 90, 0 ) );
|
||||||
|
trsf.scale.value = new Vector3( 10,5,-1 );
|
||||||
|
//var md = new NetMovementData();
|
||||||
|
|
||||||
|
trsf.WriteMembers( bitView );
|
||||||
|
|
||||||
|
LogAndTestReversal( bitView );
|
||||||
|
|
||||||
|
var copy = bitView.Clone();
|
||||||
|
copy.SetPointer( 0 );
|
||||||
|
|
||||||
|
var bit = copy.ReadBit();
|
||||||
|
var data = copy.ReadFloat();
|
||||||
|
var copyTrsf = Singleton<NetClassDataType<NetTransform>>.Get().ReadData( copy );
|
||||||
|
|
||||||
|
RJLog.Log( bit, data, trsf.position.value, trsf.rotation.value, trsf.scale.value );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TestByteWriting()
|
||||||
|
{
|
||||||
|
RJLog.Log( "----- TestByteWriting -------" );
|
||||||
|
|
||||||
|
var bitView = BitView.CreateEmpty();
|
||||||
|
|
||||||
|
bitView.WriteByte( 1 );
|
||||||
|
bitView.WriteByte( 0 );
|
||||||
|
bitView.WriteByte( 0 );
|
||||||
|
bitView.WriteByte( 0 );
|
||||||
|
|
||||||
|
bitView.WriteBit( true );
|
||||||
|
bitView.WriteBit( false );
|
||||||
|
bitView.WriteBit( true );
|
||||||
|
bitView.WriteByte( 19 );
|
||||||
|
bitView.WriteByte( 84 );
|
||||||
|
|
||||||
|
LogAndTestReversal( bitView );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TestIntVL8Writing()
|
||||||
|
{
|
||||||
|
RJLog.Log( "----- TestIntVL8Writing -------" );
|
||||||
|
|
||||||
|
var bitView = BitView.CreateEmpty();
|
||||||
|
|
||||||
|
bitView.WriteUIntVL8( 127 );
|
||||||
|
bitView.WriteUIntVL8( 128 );
|
||||||
|
bitView.WriteUIntVL8( 70000 );
|
||||||
|
bitView.WriteUIntVL8( 17121984 );
|
||||||
|
|
||||||
|
LogAndTestReversal( bitView );
|
||||||
|
|
||||||
|
var copy = BitView.From( bitView.GetBytes(), bitView.numBits );
|
||||||
|
copy.SetPointer( 0 );
|
||||||
|
|
||||||
|
RJLog.Log( "----- Reading -------" );
|
||||||
|
|
||||||
|
for ( int i = 0; i < 4; i++ )
|
||||||
|
{
|
||||||
|
copy.ReadUIntVL8();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LogAndTestReversal( BitView bitView )
|
||||||
|
{
|
||||||
|
Log( bitView );
|
||||||
|
|
||||||
|
var fromBytes = BitView.From( bitView.GetBytes(), bitView.numBits );
|
||||||
|
|
||||||
|
Log( fromBytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log( BitView view )
|
||||||
|
{
|
||||||
|
RJLog.Log( view.GetBitString(), "|", ByteView.Stringify( view.GetBytes() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
public void WriteByte( byte value )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
WriteBit( BitMath.IsBitSet( value, i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteBytes( byte[] values )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < values.Length; i++ )
|
||||||
|
{
|
||||||
|
WriteByte( values[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadByte()
|
||||||
|
{
|
||||||
|
var byteValue = 0;
|
||||||
|
|
||||||
|
for ( int i = 0; i < 8; i++ )
|
||||||
|
{
|
||||||
|
var bitValue = ReadBit();
|
||||||
|
|
||||||
|
if ( ! bitValue )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byteValue = byteValue | ( 1 << i );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte) byteValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadBytes( byte[] output, int size )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < size; i++ )
|
||||||
|
{
|
||||||
|
output[ i ] = ReadByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] ReadByteArray( int size )
|
||||||
|
{
|
||||||
|
var data = new byte[ size ];
|
||||||
|
ReadBytes( data, size );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
public void WriteFloat( float value )
|
||||||
|
{
|
||||||
|
WriteBytes( BitConverter.GetBytes( value ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ReadFloat()
|
||||||
|
{
|
||||||
|
return BitConverter.ToSingle( ReadByteArray( 4 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
public void WriteInt( int value )
|
||||||
|
{
|
||||||
|
WriteBytes( BitConverter.GetBytes( value ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ReadInt()
|
||||||
|
{
|
||||||
|
return BitConverter.ToInt32( ReadByteArray( 4 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
public static int numBitsForIntVL8( int value )
|
||||||
|
{
|
||||||
|
return numBytesForUIntVL8( value ) * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int numBytesForUIntVL8( int value )
|
||||||
|
{
|
||||||
|
var numBits = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) );
|
||||||
|
var numBytes = ( numBits - 1 )/ 7 + 1;
|
||||||
|
|
||||||
|
return numBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void WriteUIntVL8( int value )
|
||||||
|
{
|
||||||
|
if ( value < 0 )
|
||||||
|
{
|
||||||
|
throw new System.Exception( "Value is negative, writing only positive value:" + value );
|
||||||
|
}
|
||||||
|
|
||||||
|
var numBits = Mathf.CeilToInt( MathX.Exponent( 2, value + 1 ) );
|
||||||
|
var numBytes = ( numBits - 1 )/ 7 + 1;
|
||||||
|
var position = 0;
|
||||||
|
|
||||||
|
RJLog.Log( "WriteIntVL8", value, "bits:", numBits," >> bytes:", numBytes );
|
||||||
|
|
||||||
|
for ( int b = 0; b < numBytes; b++ )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < 7; i++ )
|
||||||
|
{
|
||||||
|
WriteBit( BitMath.IsBitSet( value, position ) );
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteBit( b != ( numBytes - 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ReadUIntVL8()
|
||||||
|
{
|
||||||
|
var byteValue = ReadByte();
|
||||||
|
var intValue = byteValue & 127;
|
||||||
|
var numShifts = 1;
|
||||||
|
|
||||||
|
while ( byteValue > 127 )
|
||||||
|
{
|
||||||
|
byteValue = ReadByte();
|
||||||
|
var nextIntValue = ( byteValue & 127 ) << ( 7 * numShifts );
|
||||||
|
numShifts ++;
|
||||||
|
intValue = intValue | nextIntValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJLog.Log( "ReadIntVL8 >> ", intValue );
|
||||||
|
|
||||||
|
return intValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteIntVL8( int value )
|
||||||
|
{
|
||||||
|
var isNegative = value < 0;
|
||||||
|
var absValue = Mathf.Abs( value );
|
||||||
|
|
||||||
|
WriteBit( isNegative );
|
||||||
|
WriteUIntVL8( absValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ReadIntVL8()
|
||||||
|
{
|
||||||
|
var isNegative = ReadBit();
|
||||||
|
var absValue = ReadUIntVL8();
|
||||||
|
|
||||||
|
return isNegative ? ( -absValue ) : absValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
public void WriteVector2( Vector2 value )
|
||||||
|
{
|
||||||
|
WriteFloat( value.X );
|
||||||
|
WriteFloat( value.Y );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 ReadVector2()
|
||||||
|
{
|
||||||
|
return new Vector2( ReadFloat(), ReadFloat() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteVector3( Vector3 value )
|
||||||
|
{
|
||||||
|
WriteFloat( value.X );
|
||||||
|
WriteFloat( value.Y );
|
||||||
|
WriteFloat( value.Z );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 ReadVector3()
|
||||||
|
{
|
||||||
|
return new Vector3( ReadFloat(), ReadFloat(), ReadFloat() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteVector4( Vector4 value )
|
||||||
|
{
|
||||||
|
WriteFloat( value.X );
|
||||||
|
WriteFloat( value.Y );
|
||||||
|
WriteFloat( value.Z );
|
||||||
|
WriteFloat( value.W );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector4 ReadVector4()
|
||||||
|
{
|
||||||
|
return new Vector4( ReadFloat(), ReadFloat(), ReadFloat(), ReadFloat() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteQuaternion( Quaternion value )
|
||||||
|
{
|
||||||
|
WriteFloat( value.X );
|
||||||
|
WriteFloat( value.Y );
|
||||||
|
WriteFloat( value.Z );
|
||||||
|
WriteFloat( value.W );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Quaternion ReadQuaternion()
|
||||||
|
{
|
||||||
|
return new Quaternion( ReadFloat(), ReadFloat(), ReadFloat(), ReadFloat() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,266 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class BitView
|
||||||
|
{
|
||||||
|
byte[] _data;
|
||||||
|
|
||||||
|
int _internalViewOffset = 0;
|
||||||
|
public int bitOffset => _internalViewOffset;
|
||||||
|
|
||||||
|
int _internalViewSize = 0;
|
||||||
|
public int numBits => _internalViewSize;
|
||||||
|
|
||||||
|
public int numBytes => Mathf.CeilToInt( _internalViewSize / 8f );
|
||||||
|
|
||||||
|
|
||||||
|
int _externalPointer = 0;
|
||||||
|
public int pointerPosition => _externalPointer;
|
||||||
|
|
||||||
|
public void SetPointer( int bitPosition )
|
||||||
|
{
|
||||||
|
_externalPointer = bitPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public byte[] GetBytes()
|
||||||
|
{
|
||||||
|
var numBytes = this.numBytes;
|
||||||
|
var data = new byte[ numBytes ];
|
||||||
|
System.Array.Fill( data, (byte)0 );
|
||||||
|
|
||||||
|
for ( int i = 0; i < _internalViewSize; i++ )
|
||||||
|
{
|
||||||
|
var isSet = GetValueInternal( i + _internalViewOffset );
|
||||||
|
|
||||||
|
if ( ! isSet )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shift = i % 8;
|
||||||
|
var index = i / 8;
|
||||||
|
var value = 1 << shift;
|
||||||
|
|
||||||
|
data[ index ] = (byte) ( data[ index ] | value );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BitView Clone()
|
||||||
|
{
|
||||||
|
var clone = new BitView();
|
||||||
|
clone._data = _data;
|
||||||
|
clone._internalViewOffset = _internalViewOffset;
|
||||||
|
clone._internalViewSize = _internalViewSize;
|
||||||
|
clone._externalPointer = _externalPointer;
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetBitString()
|
||||||
|
{
|
||||||
|
var output = new StringBuilder();
|
||||||
|
|
||||||
|
for ( int i = 0; i < _internalViewSize; i++ )
|
||||||
|
{
|
||||||
|
var mod = i % 8;
|
||||||
|
|
||||||
|
if ( i != 0 && mod == 0 )
|
||||||
|
{
|
||||||
|
output.Append( " " );
|
||||||
|
}
|
||||||
|
|
||||||
|
var reverseIndex = 7 - mod * 2;
|
||||||
|
|
||||||
|
var value = GetValueInternal( reverseIndex + i + _internalViewOffset ) ? "1" : "0";
|
||||||
|
output.Append( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetValueInternal( int position, bool value )
|
||||||
|
{
|
||||||
|
var byteIndex = position / 8;
|
||||||
|
var bitOffset = position - byteIndex * 8;
|
||||||
|
|
||||||
|
if ( value )
|
||||||
|
{
|
||||||
|
_data[ byteIndex ] = Bytes.SetBit( _data[ byteIndex ], bitOffset );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_data[ byteIndex ] = Bytes.UnsetBit( _data[ byteIndex ], bitOffset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetValueInternal( int bitPosition )
|
||||||
|
{
|
||||||
|
var byteIndex = bitPosition / 8;
|
||||||
|
var bitOffset = bitPosition - byteIndex * 8;
|
||||||
|
|
||||||
|
return Bytes.IsBitSet( _data[ byteIndex ], bitOffset );
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetShiftedValueInternal( int bitPosition, int shift )
|
||||||
|
{
|
||||||
|
if ( ! GetValueInternal( bitPosition ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1 << shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnsureInternalSize( int bitPosition )
|
||||||
|
{
|
||||||
|
var byteIndex = bitPosition / 8;
|
||||||
|
|
||||||
|
if ( byteIndex >= _data.Length )
|
||||||
|
{
|
||||||
|
var newData = new byte[ _data.Length + 1 ];
|
||||||
|
System.Array.Fill( newData, (byte) 0 );
|
||||||
|
System.Array.Copy( _data, 0, newData, 0, _data.Length );
|
||||||
|
|
||||||
|
_data = newData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_externalPointer = 0;
|
||||||
|
|
||||||
|
for ( int i = 0; i < _internalViewSize; i++ )
|
||||||
|
{
|
||||||
|
SetValueInternal( i + _internalViewOffset, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetPointerAndSize()
|
||||||
|
{
|
||||||
|
_externalPointer = 0;
|
||||||
|
_internalViewSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteBit( bool value )
|
||||||
|
{
|
||||||
|
var position = _externalPointer + _internalViewOffset;
|
||||||
|
EnsureInternalSize( position );
|
||||||
|
|
||||||
|
SetValueInternal( position, value );
|
||||||
|
_externalPointer ++;
|
||||||
|
|
||||||
|
_internalViewSize = Mathf.Max( _externalPointer, _internalViewSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetBitAt( int bitPosition )
|
||||||
|
{
|
||||||
|
var internalBitPosition = bitPosition + _internalViewOffset;
|
||||||
|
return GetValueInternal( bitPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ReadBit()
|
||||||
|
{
|
||||||
|
var bitPosition = _externalPointer + _internalViewOffset;
|
||||||
|
|
||||||
|
if ( bitPosition < 0 || bitPosition >= numBits )
|
||||||
|
{
|
||||||
|
RJLog.Log( "Can't read: >> ", bitPosition, "in", numBits, "p:", _externalPointer, "o:", _internalViewOffset );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var value = GetValueInternal( bitPosition );
|
||||||
|
_externalPointer ++;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPointerPosition( int position )
|
||||||
|
{
|
||||||
|
_externalPointer = Mathf.Clamp( position, 0, _internalViewSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitView CreateEmpty()
|
||||||
|
{
|
||||||
|
var view = new BitView();
|
||||||
|
view._data = new byte[]{};
|
||||||
|
view._internalViewOffset = 0;
|
||||||
|
view._internalViewSize = 0;
|
||||||
|
view._externalPointer = 0;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitView From( byte[] data)
|
||||||
|
{
|
||||||
|
var view = new BitView();
|
||||||
|
|
||||||
|
view._data = data;
|
||||||
|
view._internalViewOffset = 0;
|
||||||
|
view._internalViewSize = data.Length * 8;
|
||||||
|
view._externalPointer = 0;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static BitView From( byte[] data, int bitSize = -1 )
|
||||||
|
{
|
||||||
|
var view = new BitView();
|
||||||
|
|
||||||
|
view._data = data;
|
||||||
|
view._internalViewOffset = 0;
|
||||||
|
view._internalViewSize = bitSize == -1 ? data.Length * 8 : bitSize;
|
||||||
|
view._externalPointer = 0;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitView PrependBytes( byte[] before, BitView after )
|
||||||
|
{
|
||||||
|
var data = new byte[ before.Length + after.numBytes ];
|
||||||
|
|
||||||
|
System.Array.Copy( before, 0, data, 0, before.Length );
|
||||||
|
|
||||||
|
var view = BitView.From( data, before.Length * 8 + after.numBits );
|
||||||
|
|
||||||
|
|
||||||
|
if ( after.bitOffset == 0 )
|
||||||
|
{
|
||||||
|
System.Array.Copy( after._data, 0, data, 0, after.numBytes );
|
||||||
|
view.SetPointer( after.pointerPosition + before.Length * 8 );
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
view.SetPointer( before.Length * 8 );
|
||||||
|
|
||||||
|
for ( int i = 0; i < after.numBits; i++ )
|
||||||
|
{
|
||||||
|
view.WriteBit( after.GetBitAt( i ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
view.SetPointer( after.pointerPosition + before.Length * 8 );
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BitView PrependID( int id, BitView after )
|
||||||
|
{
|
||||||
|
var idView = BitView.CreateEmpty();
|
||||||
|
idView.WriteUIntVL8( id );
|
||||||
|
|
||||||
|
return BitView.PrependBytes( idView.GetBytes(), after );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class ByteView
|
||||||
|
{
|
||||||
|
byte[] _data;
|
||||||
|
int _start;
|
||||||
|
int _size;
|
||||||
|
|
||||||
|
public ByteView From( byte[] bytes )
|
||||||
|
{
|
||||||
|
var view = new ByteView();
|
||||||
|
view._start = 0;
|
||||||
|
view._size = bytes.Length;
|
||||||
|
view._data = bytes;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetBytes()
|
||||||
|
{
|
||||||
|
if ( _start == 0 && _size == _data.Length )
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = new byte[ _size ];
|
||||||
|
|
||||||
|
Array.Copy( _data, _start, bytes, 0, _size );
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Stringify()
|
||||||
|
{
|
||||||
|
return Stringify( _data, _start, _size );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Stringify( byte[] _data, int _start = 0, int _size = -1)
|
||||||
|
{
|
||||||
|
if ( _size < 0 )
|
||||||
|
{
|
||||||
|
_size = _data.Length - _start;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
for ( int i = 0; i < _size; i++ )
|
||||||
|
{
|
||||||
|
if ( i != 0 )
|
||||||
|
{
|
||||||
|
sb.Append( " " );
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = _data[ i + _start ] + "";
|
||||||
|
|
||||||
|
while ( value.Length < 3 )
|
||||||
|
{
|
||||||
|
value = "0" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Append( value );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class Bytes
|
||||||
|
{
|
||||||
|
|
||||||
|
public static byte SetBit( byte value, int position )
|
||||||
|
{
|
||||||
|
return (byte) ( ( 1 << position ) | value );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte UnsetBit( byte value, int position )
|
||||||
|
{
|
||||||
|
var mask = 1 << position;
|
||||||
|
var invertedMask = ~mask;
|
||||||
|
|
||||||
|
return (byte)( value & invertedMask );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsBitSet( byte value, int position )
|
||||||
|
{
|
||||||
|
var mask = 1 << position;
|
||||||
|
return ( mask & value ) == mask ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,10 +37,13 @@ namespace Rokojori
|
||||||
|
|
||||||
public virtual void DispatchEvent()
|
public virtual void DispatchEvent()
|
||||||
{
|
{
|
||||||
|
_canModify = false;
|
||||||
|
|
||||||
_actions.ForEach( a => { if ( a != null ){ a( _value ); } } );
|
_actions.ForEach( a => { if ( a != null ){ a( _value ); } } );
|
||||||
|
|
||||||
_ClearOnceActions();
|
_UpdateLists();
|
||||||
|
|
||||||
|
_canModify = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,35 +12,88 @@ namespace Rokojori
|
||||||
protected List<Action<T>> _actions = new List<Action<T>>();
|
protected List<Action<T>> _actions = new List<Action<T>>();
|
||||||
List<Action<T>> _once = new List<Action<T>>();
|
List<Action<T>> _once = new List<Action<T>>();
|
||||||
|
|
||||||
|
protected bool _canModify = true;
|
||||||
|
List<Action<T>> _additions = new List<Action<T>>();
|
||||||
|
List<Action<T>> _onceAdditions = new List<Action<T>>();
|
||||||
|
List<Action<T>> _removals = new List<Action<T>>();
|
||||||
|
|
||||||
|
|
||||||
public bool hasListeners => _once.Count > 0 || _actions.Count > 0;
|
public bool hasListeners => _once.Count > 0 || _actions.Count > 0;
|
||||||
|
|
||||||
public void AddAction( Action<T> action )
|
public void AddAction( Action<T> action )
|
||||||
|
{
|
||||||
|
if ( _canModify )
|
||||||
{
|
{
|
||||||
_actions.Add( action );
|
_actions.Add( action );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_additions.Add( action );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RemoveAction( Action<T> action )
|
public void RemoveAction( Action<T> action )
|
||||||
|
{
|
||||||
|
if ( _canModify )
|
||||||
{
|
{
|
||||||
_actions.Remove( action );
|
_actions.Remove( action );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_removals.Add( action );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Once( Action<T> action )
|
public void Once( Action<T> action )
|
||||||
|
{
|
||||||
|
if ( _canModify )
|
||||||
{
|
{
|
||||||
_actions.Add( action );
|
_actions.Add( action );
|
||||||
_once.Add( action );
|
_once.Add( action );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_onceAdditions.Add( action );
|
||||||
|
}
|
||||||
|
|
||||||
protected void _ClearOnceActions()
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void _UpdateLists()
|
||||||
{
|
{
|
||||||
_once.ForEach( a => { _actions.Remove( a ); } );
|
_once.ForEach( a => { _actions.Remove( a ); } );
|
||||||
_once.Clear();
|
_once.Clear();
|
||||||
|
|
||||||
|
if ( _removals.Count > 0 )
|
||||||
|
{
|
||||||
|
Lists.RemoveRange( _actions, _removals );
|
||||||
|
_removals.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _additions.Count > 0 )
|
||||||
|
{
|
||||||
|
_actions.AddRange( _additions );
|
||||||
|
_additions.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _onceAdditions.Count > 0 )
|
||||||
|
{
|
||||||
|
_once.AddRange( _onceAdditions );
|
||||||
|
_actions.AddRange( _onceAdditions );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchEvent( T t )
|
public void DispatchEvent( T t )
|
||||||
{
|
{
|
||||||
|
_canModify = false;
|
||||||
|
|
||||||
_actions.ForEach( a => { if ( a != null ){ a( t ); } } );
|
_actions.ForEach( a => { if ( a != null ){ a( t ); } } );
|
||||||
|
|
||||||
_ClearOnceActions();
|
_UpdateLists();
|
||||||
|
|
||||||
|
_canModify = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,71 +9,71 @@ namespace Rokojori
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnInputEvent;
|
public Action OnInputEvent;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnMouseEntered;
|
public Action OnMouseEntered;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnMouseExited;
|
public Action OnMouseExited;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnVisibilityChanged;
|
public Action OnVisibilityChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnReady;
|
public Action OnReady;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnRenamed;
|
public Action OnRenamed;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeEntered;
|
public Action OnTreeEntered;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeExiting;
|
public Action OnTreeExiting;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeExited;
|
public Action OnTreeExited;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildEnteredTree;
|
public Action OnChildEnteredTree;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildExitingTree;
|
public Action OnChildExitingTree;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildOrderChanged;
|
public Action OnChildOrderChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnReplacingBy;
|
public Action OnReplacingBy;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnEditorDescriptionChanged;
|
public Action OnEditorDescriptionChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnScriptChanged;
|
public Action OnScriptChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnPropertyListChanged;
|
public Action OnPropertyListChanged;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
InputEvent += ( p0, p1, p2, p3, p4 ) => { Actions.Trigger( OnInputEvent ); };
|
InputEvent += ( p0, p1, p2, p3, p4 ) => { Action.Trigger( OnInputEvent ); };
|
||||||
MouseEntered += ( ) => { Actions.Trigger( OnMouseEntered ); };
|
MouseEntered += ( ) => { Action.Trigger( OnMouseEntered ); };
|
||||||
MouseExited += ( ) => { Actions.Trigger( OnMouseExited ); };
|
MouseExited += ( ) => { Action.Trigger( OnMouseExited ); };
|
||||||
VisibilityChanged += ( ) => { Actions.Trigger( OnVisibilityChanged ); };
|
VisibilityChanged += ( ) => { Action.Trigger( OnVisibilityChanged ); };
|
||||||
Ready += ( ) => { Actions.Trigger( OnReady ); };
|
Ready += ( ) => { Action.Trigger( OnReady ); };
|
||||||
Renamed += ( ) => { Actions.Trigger( OnRenamed ); };
|
Renamed += ( ) => { Action.Trigger( OnRenamed ); };
|
||||||
TreeEntered += ( ) => { Actions.Trigger( OnTreeEntered ); };
|
TreeEntered += ( ) => { Action.Trigger( OnTreeEntered ); };
|
||||||
TreeExiting += ( ) => { Actions.Trigger( OnTreeExiting ); };
|
TreeExiting += ( ) => { Action.Trigger( OnTreeExiting ); };
|
||||||
TreeExited += ( ) => { Actions.Trigger( OnTreeExited ); };
|
TreeExited += ( ) => { Action.Trigger( OnTreeExited ); };
|
||||||
ChildEnteredTree += ( p0 ) => { Actions.Trigger( OnChildEnteredTree ); };
|
ChildEnteredTree += ( p0 ) => { Action.Trigger( OnChildEnteredTree ); };
|
||||||
ChildExitingTree += ( p0 ) => { Actions.Trigger( OnChildExitingTree ); };
|
ChildExitingTree += ( p0 ) => { Action.Trigger( OnChildExitingTree ); };
|
||||||
ChildOrderChanged += ( ) => { Actions.Trigger( OnChildOrderChanged ); };
|
ChildOrderChanged += ( ) => { Action.Trigger( OnChildOrderChanged ); };
|
||||||
ReplacingBy += ( p0 ) => { Actions.Trigger( OnReplacingBy ); };
|
ReplacingBy += ( p0 ) => { Action.Trigger( OnReplacingBy ); };
|
||||||
EditorDescriptionChanged += ( p0 ) => { Actions.Trigger( OnEditorDescriptionChanged ); };
|
EditorDescriptionChanged += ( p0 ) => { Action.Trigger( OnEditorDescriptionChanged ); };
|
||||||
ScriptChanged += ( ) => { Actions.Trigger( OnScriptChanged ); };
|
ScriptChanged += ( ) => { Action.Trigger( OnScriptChanged ); };
|
||||||
PropertyListChanged += ( ) => { Actions.Trigger( OnPropertyListChanged ); };
|
PropertyListChanged += ( ) => { Action.Trigger( OnPropertyListChanged ); };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,71 +9,71 @@ namespace Rokojori
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnInputEvent;
|
public Action OnInputEvent;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnMouseEntered;
|
public Action OnMouseEntered;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnMouseExited;
|
public Action OnMouseExited;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnVisibilityChanged;
|
public Action OnVisibilityChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnReady;
|
public Action OnReady;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnRenamed;
|
public Action OnRenamed;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeEntered;
|
public Action OnTreeEntered;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeExiting;
|
public Action OnTreeExiting;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnTreeExited;
|
public Action OnTreeExited;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildEnteredTree;
|
public Action OnChildEnteredTree;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildExitingTree;
|
public Action OnChildExitingTree;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnChildOrderChanged;
|
public Action OnChildOrderChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnReplacingBy;
|
public Action OnReplacingBy;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnEditorDescriptionChanged;
|
public Action OnEditorDescriptionChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnScriptChanged;
|
public Action OnScriptChanged;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction OnPropertyListChanged;
|
public Action OnPropertyListChanged;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
InputEvent += ( p0, p1, p2, p3, p4 ) => { Actions.Trigger( OnInputEvent ); };
|
InputEvent += ( p0, p1, p2, p3, p4 ) => { Action.Trigger( OnInputEvent ); };
|
||||||
MouseEntered += ( ) => { Actions.Trigger( OnMouseEntered ); };
|
MouseEntered += ( ) => { Action.Trigger( OnMouseEntered ); };
|
||||||
MouseExited += ( ) => { Actions.Trigger( OnMouseExited ); };
|
MouseExited += ( ) => { Action.Trigger( OnMouseExited ); };
|
||||||
VisibilityChanged += ( ) => { Actions.Trigger( OnVisibilityChanged ); };
|
VisibilityChanged += ( ) => { Action.Trigger( OnVisibilityChanged ); };
|
||||||
Ready += ( ) => { Actions.Trigger( OnReady ); };
|
Ready += ( ) => { Action.Trigger( OnReady ); };
|
||||||
Renamed += ( ) => { Actions.Trigger( OnRenamed ); };
|
Renamed += ( ) => { Action.Trigger( OnRenamed ); };
|
||||||
TreeEntered += ( ) => { Actions.Trigger( OnTreeEntered ); };
|
TreeEntered += ( ) => { Action.Trigger( OnTreeEntered ); };
|
||||||
TreeExiting += ( ) => { Actions.Trigger( OnTreeExiting ); };
|
TreeExiting += ( ) => { Action.Trigger( OnTreeExiting ); };
|
||||||
TreeExited += ( ) => { Actions.Trigger( OnTreeExited ); };
|
TreeExited += ( ) => { Action.Trigger( OnTreeExited ); };
|
||||||
ChildEnteredTree += ( p0 ) => { Actions.Trigger( OnChildEnteredTree ); };
|
ChildEnteredTree += ( p0 ) => { Action.Trigger( OnChildEnteredTree ); };
|
||||||
ChildExitingTree += ( p0 ) => { Actions.Trigger( OnChildExitingTree ); };
|
ChildExitingTree += ( p0 ) => { Action.Trigger( OnChildExitingTree ); };
|
||||||
ChildOrderChanged += ( ) => { Actions.Trigger( OnChildOrderChanged ); };
|
ChildOrderChanged += ( ) => { Action.Trigger( OnChildOrderChanged ); };
|
||||||
ReplacingBy += ( p0 ) => { Actions.Trigger( OnReplacingBy ); };
|
ReplacingBy += ( p0 ) => { Action.Trigger( OnReplacingBy ); };
|
||||||
EditorDescriptionChanged += ( p0 ) => { Actions.Trigger( OnEditorDescriptionChanged ); };
|
EditorDescriptionChanged += ( p0 ) => { Action.Trigger( OnEditorDescriptionChanged ); };
|
||||||
ScriptChanged += ( ) => { Actions.Trigger( OnScriptChanged ); };
|
ScriptChanged += ( ) => { Action.Trigger( OnScriptChanged ); };
|
||||||
PropertyListChanged += ( ) => { Actions.Trigger( OnPropertyListChanged ); };
|
PropertyListChanged += ( ) => { Action.Trigger( OnPropertyListChanged ); };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace Rokojori
|
||||||
|
|
||||||
output.Append( " \n" );
|
output.Append( " \n" );
|
||||||
output.Append( " [Export]\n" );
|
output.Append( " [Export]\n" );
|
||||||
output.Append( " public RJAction On" + eventName + ";\n" );
|
output.Append( " public Action On" + eventName + ";\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
output.Append( " \n" );
|
output.Append( " \n" );
|
||||||
|
@ -100,7 +100,7 @@ namespace Rokojori
|
||||||
p += " )";
|
p += " )";
|
||||||
|
|
||||||
|
|
||||||
output.Append( " " + eventName + " += " + p + " => { Actions.Trigger( On" + eventName +" ); }; \n" );
|
output.Append( " " + eventName + " += " + p + " => { Action.Trigger( On" + eventName +" ); }; \n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
output.Append( " }\n" );
|
output.Append( " }\n" );
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class Caster:Node3D
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Action beforeProcess;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action afterProcess;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Selector includeSelector;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Selector excludeSelector;
|
||||||
|
|
||||||
|
|
||||||
|
public virtual int NumColliders()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public virtual Node GetCollider( int index )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Vector3 GetCollisionPosition( int index )
|
||||||
|
{
|
||||||
|
return Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Vector3 GetCollisionNormal( int index )
|
||||||
|
{
|
||||||
|
return Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Shape3D GetCollisionShape( int index )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ namespace Rokojori
|
||||||
if ( CharacterUpdateMode.Process == characterUpdateMode )
|
if ( CharacterUpdateMode.Process == characterUpdateMode )
|
||||||
{
|
{
|
||||||
this.delta = (float)delta;
|
this.delta = (float)delta;
|
||||||
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, a => Actions.Trigger( a ) );
|
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, a => Action.Trigger( a ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// positionSmoother.CopyPosition( graphics, body, rotationSmoothingDuration, delta );
|
// positionSmoother.CopyPosition( graphics, body, rotationSmoothingDuration, delta );
|
||||||
|
@ -64,7 +64,7 @@ namespace Rokojori
|
||||||
if ( CharacterUpdateMode.Physics_Process == characterUpdateMode )
|
if ( CharacterUpdateMode.Physics_Process == characterUpdateMode )
|
||||||
{
|
{
|
||||||
this.delta = (float)delta;
|
this.delta = (float)delta;
|
||||||
Nodes.ForEach<RJAction>( actionsContainer, a => Actions.Trigger( a ) );
|
Nodes.ForEach<Action>( actionsContainer, a => Action.Trigger( a ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using Godot.Collections;
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class CharacterControllerAction:RJAction
|
public partial class CharacterControllerAction:Action
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public CharacterController controller;
|
public CharacterController controller;
|
||||||
|
|
|
@ -16,18 +16,18 @@ namespace Rokojori
|
||||||
|
|
||||||
[ExportGroup( "Actions" )]
|
[ExportGroup( "Actions" )]
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onMoving;
|
public Action onMoving;
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onIdle;
|
public Action onIdle;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onForward;
|
public Action onForward;
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onBackwards;
|
public Action onBackwards;
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onStrafeLeft;
|
public Action onStrafeLeft;
|
||||||
[Export]
|
[Export]
|
||||||
public RJAction onStrafeRight;
|
public Action onStrafeRight;
|
||||||
|
|
||||||
|
|
||||||
[ExportGroup( "Direction Source" )]
|
[ExportGroup( "Direction Source" )]
|
||||||
|
@ -50,20 +50,20 @@ namespace Rokojori
|
||||||
public float moveSpeed;
|
public float moveSpeed;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJSensor forward;
|
public Sensor forward;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJSensor backwards;
|
public Sensor backwards;
|
||||||
|
|
||||||
[ExportGroup( "Strafing" )]
|
[ExportGroup( "Strafing" )]
|
||||||
[Export]
|
[Export]
|
||||||
public float strafeSpeed;
|
public float strafeSpeed;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJSensor strafeLeft;
|
public Sensor strafeLeft;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public RJSensor strafeRight;
|
public Sensor strafeRight;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool useBodyDirection = true;
|
public bool useBodyDirection = true;
|
||||||
|
@ -81,7 +81,7 @@ namespace Rokojori
|
||||||
Smoother rotationSmoother = new Smoother();
|
Smoother rotationSmoother = new Smoother();
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( ! body.IsOnFloor() )
|
if ( ! body.IsOnFloor() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public float strength = 10;
|
public float strength = 10;
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( body.IsOnFloor() )
|
if ( body.IsOnFloor() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class GroundReset:CharacterControllerAction
|
public partial class GroundReset:CharacterControllerAction
|
||||||
{
|
{
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( ! body.IsOnFloor() )
|
if ( ! body.IsOnFloor() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Rokojori
|
||||||
public partial class Jump:CharacterControllerAction
|
public partial class Jump:CharacterControllerAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public RJSensor button;
|
public Sensor button;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float jumpStrength;
|
public float jumpStrength;
|
||||||
|
@ -31,7 +31,7 @@ namespace Rokojori
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( body.IsOnFloor() )
|
if ( body.IsOnFloor() )
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! button.IsActive() )
|
if ( ! button.isActive )
|
||||||
{
|
{
|
||||||
jumping = false;
|
jumping = false;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class MoveAndSlide:CharacterControllerAction
|
public partial class MoveAndSlide:CharacterControllerAction
|
||||||
{
|
{
|
||||||
public override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
// RJLog.Log( controller.body.Velocity );
|
// RJLog.Log( controller.body.Velocity );
|
||||||
controller.body.MoveAndSlide();
|
controller.body.MoveAndSlide();
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
|
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class MultiRayCaster:RJCaster
|
public partial class MultiRayCaster:Caster
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public float rayLength = 10;
|
public float rayLength = 10;
|
||||||
|
@ -54,13 +54,13 @@ namespace Rokojori
|
||||||
|
|
||||||
public override void _Process( double delta )
|
public override void _Process( double delta )
|
||||||
{
|
{
|
||||||
Actions.Trigger( BeforeProcess );
|
Action.Trigger( beforeProcess );
|
||||||
|
|
||||||
ResolveCollisions();
|
ResolveCollisions();
|
||||||
SortCollisions();
|
SortCollisions();
|
||||||
|
|
||||||
|
|
||||||
Actions.Trigger( AfterProcess );
|
Action.Trigger( afterProcess );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +119,6 @@ namespace Rokojori
|
||||||
|
|
||||||
bool IsSelected( CollisionData cd )
|
bool IsSelected( CollisionData cd )
|
||||||
{
|
{
|
||||||
var includeSelector = IncludeSelector;
|
|
||||||
var excludeSelector = ExcludeSelector;
|
|
||||||
|
|
||||||
if ( includeSelector != null && ! includeSelector.Selects( cd.collider ) )
|
if ( includeSelector != null && ! includeSelector.Selects( cd.collider ) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -164,11 +161,11 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
float priority = 0;
|
float priority = 0;
|
||||||
|
|
||||||
var pointable = Nodes.Find<RJPointable>( cd.collider );
|
var pointable = Nodes.Find<Pointable>( cd.collider );
|
||||||
|
|
||||||
if ( pointable != null )
|
if ( pointable != null )
|
||||||
{
|
{
|
||||||
priority = pointable.PointingPriority;
|
priority = pointable.pointingPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
return priority;
|
return priority;
|
||||||
|
|
|
@ -7,21 +7,33 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
|
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Pointable:RJPointable
|
public partial class Pointable:Node3D
|
||||||
{
|
{
|
||||||
List<RJPointer> _pointers = new List<RJPointer>();
|
[Export]
|
||||||
|
public int pointingPriority;
|
||||||
|
|
||||||
public override int NumPointing()
|
[Export]
|
||||||
{
|
public Action onPointed;
|
||||||
return _pointers.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsPointedBy( RJPointer pointer )
|
[Export]
|
||||||
|
public Action onUnpointed;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onPointerAdded;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onPointerRemoved;
|
||||||
|
|
||||||
|
List<Pointer> _pointers = new List<Pointer>();
|
||||||
|
|
||||||
|
public int numPointing => _pointers.Count;
|
||||||
|
|
||||||
|
public bool IsPointedBy( Pointer pointer )
|
||||||
{
|
{
|
||||||
return _pointers.Contains( pointer );
|
return _pointers.Contains( pointer );
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdatePointerState( RJPointer pointer, bool pointed )
|
public void UpdatePointerState( Pointer pointer, bool pointed )
|
||||||
{
|
{
|
||||||
var isCurrentlyPointed = IsPointedBy( pointer );
|
var isCurrentlyPointed = IsPointedBy( pointer );
|
||||||
|
|
||||||
|
@ -34,11 +46,11 @@ namespace Rokojori
|
||||||
if ( pointed )
|
if ( pointed )
|
||||||
{
|
{
|
||||||
_pointers.Add( pointer );
|
_pointers.Add( pointer );
|
||||||
Actions.Trigger( OnPointerAdded );
|
Action.Trigger( onPointerAdded );
|
||||||
|
|
||||||
if ( _pointers.Count == 1 )
|
if ( _pointers.Count == 1 )
|
||||||
{
|
{
|
||||||
Actions.Trigger( OnPointed );
|
Action.Trigger( onPointed );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -46,11 +58,11 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
_pointers.Remove( pointer );
|
_pointers.Remove( pointer );
|
||||||
|
|
||||||
Actions.Trigger( OnPointerRemoved );
|
Action.Trigger( onPointerRemoved );
|
||||||
|
|
||||||
if ( _pointers.Count == 0 )
|
if ( _pointers.Count == 0 )
|
||||||
{
|
{
|
||||||
Actions.Trigger( OnUnpointed );
|
Action.Trigger( onUnpointed );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,22 +7,25 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
|
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Pointer:RJPointer
|
public partial class Pointer:Node3D
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public RJPointable pointable;
|
public Pointable pointable;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Caster caster;
|
||||||
|
|
||||||
public override void _Process( double delta )
|
public override void _Process( double delta )
|
||||||
{
|
{
|
||||||
if ( Caster == null )
|
if ( caster == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentCollider = Caster.NumColliders() == 0 ? null : Caster.GetCollider( 0 );
|
var currentCollider = caster.NumColliders() == 0 ? null : caster.GetCollider( 0 );
|
||||||
|
|
||||||
|
|
||||||
var currentPointable = currentCollider == null ? null : Nodes.Find<RJPointable>( currentCollider );
|
var currentPointable = currentCollider == null ? null : Nodes.Find<Pointable>( currentCollider );
|
||||||
|
|
||||||
// RJLog.Log( currentCollider, currentPointable );
|
// RJLog.Log( currentCollider, currentPointable );
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,11 @@ namespace Rokojori
|
||||||
return LookingAtEachOtherAngle( lookDirectionA, lookDirectionB ) > 0;
|
return LookingAtEachOtherAngle( lookDirectionA, lookDirectionB ) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector2 Lerp( Vector2 a, Vector2 b, float lerpAmount )
|
||||||
|
{
|
||||||
|
return a.Lerp( b, lerpAmount );
|
||||||
|
}
|
||||||
|
|
||||||
public static bool LookingTowards( Vector2 from, Vector2 fromDirection, Vector2 to )
|
public static bool LookingTowards( Vector2 from, Vector2 fromDirection, Vector2 to )
|
||||||
{
|
{
|
||||||
return LookingAtEachOther( fromDirection.Normalized(), ( to - from ).Normalized() );
|
return LookingAtEachOther( fromDirection.Normalized(), ( to - from ).Normalized() );
|
||||||
|
|
|
@ -118,6 +118,9 @@ namespace Rokojori
|
||||||
return Mathf.Floor( value / snappingDistance ) * snappingDistance;
|
return Mathf.Floor( value / snappingDistance ) * snappingDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public const float DegreesToRadians = Mathf.Pi / 180f;
|
||||||
|
public const float RadiansToDegreens = 180f / Mathf.Pi;
|
||||||
|
|
||||||
public static float AngleDelta( float degreesA, float degreesB)
|
public static float AngleDelta( float degreesA, float degreesB)
|
||||||
{
|
{
|
||||||
var angleDelta = degreesB - degreesA;
|
var angleDelta = degreesB - degreesA;
|
||||||
|
@ -279,6 +282,11 @@ namespace Rokojori
|
||||||
return ( phase - phaseStart ) / ( phaseStart - phaseEnd );
|
return ( phase - phaseStart ) / ( phaseStart - phaseEnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int SafeIndex<T>( int index, List<T> elements, bool wrap = false )
|
||||||
|
{
|
||||||
|
return SafeIndex( index, elements.Count, wrap );
|
||||||
|
}
|
||||||
|
|
||||||
public static int SafeIndex( int index, int maxElements, bool wrap = false )
|
public static int SafeIndex( int index, int maxElements, bool wrap = false )
|
||||||
{
|
{
|
||||||
if ( wrap )
|
if ( wrap )
|
||||||
|
|
|
@ -8,6 +8,24 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
float overflowDelta = 0;
|
float overflowDelta = 0;
|
||||||
|
|
||||||
|
public static float SmoothTimeInvariant( float value, float nextValue, float delta, float coefficient )
|
||||||
|
{
|
||||||
|
var lerpAmount = Mathf.Exp( -coefficient * delta );
|
||||||
|
return Mathf.Lerp( nextValue, value, lerpAmount );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 SmoothTimeInvariant( Vector2 value, Vector2 nextValue, float delta, float coefficient )
|
||||||
|
{
|
||||||
|
var lerpAmount = Mathf.Exp( -coefficient * delta );
|
||||||
|
return Math2D.Lerp( nextValue, value, lerpAmount );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 SmoothTimeInvariant( Vector3 value, Vector3 nextValue, float delta, float coefficient )
|
||||||
|
{
|
||||||
|
var lerpAmount = Mathf.Exp( -coefficient * delta );
|
||||||
|
return Math3D.Lerp( nextValue, value, lerpAmount );
|
||||||
|
}
|
||||||
|
|
||||||
public float SmoothForDuration( float value, float nextValue, float duration, float delta, float processDelta = MathX.fps120Delta )
|
public float SmoothForDuration( float value, float nextValue, float duration, float delta, float processDelta = MathX.fps120Delta )
|
||||||
{
|
{
|
||||||
var coefficient = MathX.SmoothingCoefficient( duration * 1000f, processDelta );
|
var coefficient = MathX.SmoothingCoefficient( duration * 1000f, processDelta );
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class LANNetworkBackend:NetworkBackend
|
||||||
|
{
|
||||||
|
SceneMultiplayer multiplayer;
|
||||||
|
ENetMultiplayerPeer peer;
|
||||||
|
|
||||||
|
public override void StartSession( NetworkSessionRequest request )
|
||||||
|
{
|
||||||
|
if ( _state != NetworkSessionConnectionState.Not_Connected )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignSessionRequestVariables( request );
|
||||||
|
|
||||||
|
RJLog.Log( "Starting Session:", request );
|
||||||
|
|
||||||
|
_state = NetworkSessionConnectionState.Connecting_As_Server;
|
||||||
|
|
||||||
|
multiplayer = new SceneMultiplayer();
|
||||||
|
|
||||||
|
ConnectListeners();
|
||||||
|
|
||||||
|
|
||||||
|
peer = new ENetMultiplayerPeer();
|
||||||
|
|
||||||
|
var result = peer.CreateServer( port, maxMembers );
|
||||||
|
|
||||||
|
if ( Error.Ok != result )
|
||||||
|
{
|
||||||
|
_state = NetworkSessionConnectionState.Not_Connected;
|
||||||
|
|
||||||
|
RJLog.Log( "Session Creation Failed >>", result );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = NetworkSessionConnectionState.Connected_As_Server;
|
||||||
|
_sessionManager.SetInSessionState();
|
||||||
|
|
||||||
|
Action.Trigger( _manager.onStartedSession );
|
||||||
|
|
||||||
|
|
||||||
|
AssignMultiplyer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void JoinSession( NetworkSessionRequest request )
|
||||||
|
{
|
||||||
|
if ( _state != NetworkSessionConnectionState.Not_Connected )
|
||||||
|
{
|
||||||
|
if ( NetworkSessionConnectionState.Connected_As_Client == _state )
|
||||||
|
{
|
||||||
|
SendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignSessionRequestVariables( request );
|
||||||
|
|
||||||
|
RJLog.Log( "Joining Session:", request );
|
||||||
|
|
||||||
|
_state = NetworkSessionConnectionState.Connecting_As_Client;
|
||||||
|
|
||||||
|
multiplayer = new SceneMultiplayer();
|
||||||
|
|
||||||
|
ConnectListeners();
|
||||||
|
|
||||||
|
peer = new ENetMultiplayerPeer();
|
||||||
|
|
||||||
|
var result = peer.CreateClient( serverIP, port, maxMembers );
|
||||||
|
|
||||||
|
if ( Error.Ok != result )
|
||||||
|
{
|
||||||
|
RJLog.Log( "Joining Session Failed >>", result );
|
||||||
|
_state = NetworkSessionConnectionState.Not_Connected;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignMultiplyer();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendData()
|
||||||
|
{
|
||||||
|
var data = new byte[]{ 0, 1, 2, 3 };
|
||||||
|
|
||||||
|
var resultSending = multiplayer.SendBytes( data, 0, MultiplayerPeer.TransferModeEnum.Reliable );
|
||||||
|
|
||||||
|
RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( data ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssignMultiplyer()
|
||||||
|
{
|
||||||
|
RJLog.Log( "AssignMultiplyer" );
|
||||||
|
multiplayer.MultiplayerPeer = peer;
|
||||||
|
GetTree().SetMultiplayer( multiplayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConnectListeners()
|
||||||
|
{
|
||||||
|
multiplayer.PeerPacket += ( id, data )=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "Received Data:", id, ByteView.Stringify( data ) );
|
||||||
|
_transport.HandleIncomingMessage( id, data );
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplayer.ConnectionFailed += ()=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "ConnectionFailed" );
|
||||||
|
_state = NetworkSessionConnectionState.Not_Connected;
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplayer.ServerDisconnected += ()=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "ServerDisconnected" );
|
||||||
|
_state = NetworkSessionConnectionState.Not_Connected;
|
||||||
|
_sessionManager.SetInSessionState( false );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplayer.ConnectedToServer += ()=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "Connecting_As_Client" );
|
||||||
|
_state = NetworkSessionConnectionState.Connected_As_Client;
|
||||||
|
_sessionManager.SetInSessionState();
|
||||||
|
|
||||||
|
Action.Trigger( _manager.onStartedSession );
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplayer.PeerConnected += ( id )=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "PeerConnected:", id );
|
||||||
|
var networkSessionMember = NetworkSessionMember.Create( id );
|
||||||
|
_sessionManager.AddMember( networkSessionMember );
|
||||||
|
};
|
||||||
|
|
||||||
|
multiplayer.PeerDisconnected += ( id )=>
|
||||||
|
{
|
||||||
|
RJLog.Log( "PeerDisconnected:", id );
|
||||||
|
_sessionManager.RemoveMember( id );
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SendMessage( byte[] bytes, List<int> targetMembers, bool reliable = true )
|
||||||
|
{
|
||||||
|
var mode = reliable ? MultiplayerPeer.TransferModeEnum.Reliable : MultiplayerPeer.TransferModeEnum.Unreliable;
|
||||||
|
|
||||||
|
if ( targetMembers.Count == 0 )
|
||||||
|
{
|
||||||
|
var resultSending = multiplayer.SendBytes( bytes, 0, mode );
|
||||||
|
RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( bytes ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetMembers.ForEach(
|
||||||
|
( id )=>
|
||||||
|
{
|
||||||
|
var resultSending = multiplayer.SendBytes( bytes, id, mode );
|
||||||
|
RJLog.Log( "Sending Data", resultSending, ByteView.Stringify( bytes ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public abstract class NetClassDefinition
|
||||||
|
{
|
||||||
|
protected NetMember[] _members;
|
||||||
|
|
||||||
|
public void SetMembers( params NetMember[] members )
|
||||||
|
{
|
||||||
|
_members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadMembers( BitView view )
|
||||||
|
{
|
||||||
|
System.Array.ForEach( _members, m => m.ReadMember( view ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteMembers( BitView view )
|
||||||
|
{
|
||||||
|
System.Array.ForEach( _members, m => m.WriteMember( view ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetClassDataType<T> where T:NetClassDefinition, new()
|
||||||
|
{
|
||||||
|
public T ReadData( BitView view )
|
||||||
|
{
|
||||||
|
var n = new T();
|
||||||
|
n.ReadMembers( view );
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, T t )
|
||||||
|
{
|
||||||
|
t.WriteMembers( view );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetClass<T>:NetMember where T:NetClassDefinition, new()
|
||||||
|
{
|
||||||
|
public T value;
|
||||||
|
|
||||||
|
public NetClass( T value )
|
||||||
|
{
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetClassDataType<T> dataType => Singleton<NetClassDataType<T>>.Get();
|
||||||
|
|
||||||
|
public override void ReadMember( BitView view )
|
||||||
|
{
|
||||||
|
var isNull = ! view.ReadBit();
|
||||||
|
|
||||||
|
if ( isNull )
|
||||||
|
{
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = dataType.ReadData( view );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteMember( BitView view )
|
||||||
|
{
|
||||||
|
view.WriteBit( value != null );
|
||||||
|
|
||||||
|
if ( value == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataType.WriteData( view, value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetMember
|
||||||
|
{
|
||||||
|
public virtual void ReadMember( BitView view )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void WriteMember( BitView view )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TypedNetMember<T>:NetMember
|
||||||
|
{
|
||||||
|
NetworkDataType<T> dataType;
|
||||||
|
public T value;
|
||||||
|
|
||||||
|
public TypedNetMember( NetworkDataType<T> dataType, T value )
|
||||||
|
{
|
||||||
|
this.dataType = dataType;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReadMember( BitView view )
|
||||||
|
{
|
||||||
|
value = dataType.ReadData( view );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteMember( BitView view )
|
||||||
|
{
|
||||||
|
dataType.WriteData( view, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public interface NetworkDataType<T>
|
||||||
|
{
|
||||||
|
T ReadData( BitView view );
|
||||||
|
void WriteData( BitView view, T value );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetBoolType:NetworkDataType<bool>
|
||||||
|
{
|
||||||
|
public bool ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadBit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, bool value )
|
||||||
|
{
|
||||||
|
view.WriteBit( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetBool:TypedNetMember<bool>
|
||||||
|
{
|
||||||
|
public NetBool( bool value ):base( Singleton<NetBoolType>.Get(), value ){}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetByteType:NetworkDataType<byte>
|
||||||
|
{
|
||||||
|
public byte ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, byte value )
|
||||||
|
{
|
||||||
|
view.WriteByte( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetByte:TypedNetMember<byte>
|
||||||
|
{
|
||||||
|
public NetByte( byte value ):base( Singleton<NetByteType>.Get(), value ){}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetFloatType:NetworkDataType<float>
|
||||||
|
{
|
||||||
|
public float ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, float value )
|
||||||
|
{
|
||||||
|
view.WriteFloat( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class NetFloat:TypedNetMember<float>
|
||||||
|
{
|
||||||
|
public NetFloat( float value ):base( Singleton<NetFloatType>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetIntType:NetworkDataType<int>
|
||||||
|
{
|
||||||
|
public int ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, int value )
|
||||||
|
{
|
||||||
|
view.WriteInt( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetInt:TypedNetMember<int>
|
||||||
|
{
|
||||||
|
public NetInt( int value ):base( Singleton<NetIntType>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetIntVL8Type:NetworkDataType<int>
|
||||||
|
{
|
||||||
|
public int ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadUIntVL8();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, int value )
|
||||||
|
{
|
||||||
|
view.WriteUIntVL8( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetIntVL8:TypedNetMember<int>
|
||||||
|
{
|
||||||
|
public NetIntVL8( int value ):base( Singleton<NetIntVL8Type>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetListType<T>:NetworkDataType<List<T>>
|
||||||
|
{
|
||||||
|
public NetworkDataType<T> dataType;
|
||||||
|
|
||||||
|
public List<T> ReadData( BitView view )
|
||||||
|
{
|
||||||
|
var num = view.ReadUIntVL8();
|
||||||
|
var list = new List<T>( num );
|
||||||
|
|
||||||
|
for ( int i = 0; i < num; i++ )
|
||||||
|
{
|
||||||
|
list.Add( dataType.ReadData( view ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, List<T> list )
|
||||||
|
{
|
||||||
|
view.WriteUIntVL8( list.Count );
|
||||||
|
|
||||||
|
for ( int i = 0; i < list.Count; i++ )
|
||||||
|
{
|
||||||
|
dataType.WriteData( view, list[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetList<T>:TypedNetMember<List<T>>
|
||||||
|
{
|
||||||
|
public NetList( List<T> value ):base( Singleton<NetListType<T>>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetQuaternionType:NetworkDataType<Quaternion>
|
||||||
|
{
|
||||||
|
public Quaternion ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadQuaternion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, Quaternion value )
|
||||||
|
{
|
||||||
|
view.WriteQuaternion( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetQuaternion:TypedNetMember<Quaternion>
|
||||||
|
{
|
||||||
|
public NetQuaternion( Quaternion value ):base( Singleton<NetQuaternionType>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetVector3Type:NetworkDataType<Vector3>
|
||||||
|
{
|
||||||
|
public Vector3 ReadData( BitView view )
|
||||||
|
{
|
||||||
|
return view.ReadVector3();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteData( BitView view, Vector3 value )
|
||||||
|
{
|
||||||
|
view.WriteVector3( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NetVector3:TypedNetMember<Vector3>
|
||||||
|
{
|
||||||
|
public NetVector3( Vector3 value ):base( Singleton<NetVector3Type>.Get(), value ){}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public partial class NetworkBackend:Node
|
||||||
|
{
|
||||||
|
protected NetworkSessionConnectionState _state;
|
||||||
|
protected string serverIP = "127.0.0.1";
|
||||||
|
protected int port = 1984;
|
||||||
|
protected int maxMembers = 32;
|
||||||
|
|
||||||
|
protected NetworkManager _manager;
|
||||||
|
protected ExtendedNetworkSessionManager _sessionManager;
|
||||||
|
protected ExtendedNetworkTransport _transport;
|
||||||
|
|
||||||
|
public void InitializeBackend(
|
||||||
|
NetworkManager manager,
|
||||||
|
ExtendedNetworkSessionManager sessionManager,
|
||||||
|
ExtendedNetworkTransport transport
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_manager = manager;
|
||||||
|
_sessionManager = sessionManager;
|
||||||
|
_transport = transport;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AssignSessionRequestVariables( NetworkSessionRequest request )
|
||||||
|
{
|
||||||
|
if ( request == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( request.serverIP != null )
|
||||||
|
{
|
||||||
|
serverIP = request.serverIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( request.port > 0 )
|
||||||
|
{
|
||||||
|
port = request.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( request.maxMembers > 0 )
|
||||||
|
{
|
||||||
|
maxMembers = request.maxMembers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void StartSession( NetworkSessionRequest sessionRequest )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void JoinSession( NetworkSessionRequest sessionRequest )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void LeaveSession()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SendMessage( byte[] bytes, List<int> targetMembers, bool reliable = true )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class NetworkManager:Node
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public NetworkBackend backend;
|
||||||
|
|
||||||
|
NetworkNodeMemberReferences _references = new NetworkNodeMemberReferences();
|
||||||
|
public NetworkNodeMemberReferences references => _references;
|
||||||
|
|
||||||
|
ExtendedNetworkTransport _transport = new ExtendedNetworkTransport();
|
||||||
|
public NetworkTransport transport => _transport;
|
||||||
|
|
||||||
|
ExtendedNetworkSessionManager _sessionManager = new ExtendedNetworkSessionManager();
|
||||||
|
public NetworkSessionManager sessionManager => _sessionManager;
|
||||||
|
|
||||||
|
bool _initialized = false;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onStartedSession;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onSessionMemberJoined;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Action onSessionMemberLeft;
|
||||||
|
|
||||||
|
public static NetworkManager Get()
|
||||||
|
{
|
||||||
|
return Unique<NetworkManager>.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsInSession => Get().sessionManager.isInSession;
|
||||||
|
public static int ownSessionMemberIndex => Get().sessionManager.ownMemberIndex;
|
||||||
|
public static int serverSessionMemberIndex =>Get().sessionManager.serverMemberIndex;
|
||||||
|
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
if ( _initialized )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJLog.Log( "InitializeBackend:" );
|
||||||
|
|
||||||
|
backend.InitializeBackend( this, _sessionManager, _transport );
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process( double delta )
|
||||||
|
{
|
||||||
|
if ( ! IsInSession )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_transport.ProcessQueuedMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class AddNetworkNodes:Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Node[] nodes;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
RJLog.Log( "AddNetworkNodes" );
|
||||||
|
|
||||||
|
for ( int i = 0; i < nodes.Length; i++ )
|
||||||
|
{
|
||||||
|
AddNodeAndChildren( nodes[ i ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddNodeAndChildren( Node root )
|
||||||
|
{
|
||||||
|
var walker = new NodesWalker();
|
||||||
|
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
var rf = nm.references;
|
||||||
|
|
||||||
|
walker.Iterate( root,
|
||||||
|
n =>
|
||||||
|
{
|
||||||
|
var isNetworkNode = typeof( INetworkNode ).IsAssignableFrom( n.GetType() );
|
||||||
|
|
||||||
|
if ( ! isNetworkNode )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var inn = (INetworkNode) n;
|
||||||
|
rf.AddMembersOf( inn );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public interface INetworkNode
|
||||||
|
{
|
||||||
|
List<NetworkNodeMember> GetNetworkNodeMembers();
|
||||||
|
|
||||||
|
NetworkTransportType GetNetworkType();
|
||||||
|
int GetNetworkOwner();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public partial class NetworkNode : Node, INetworkNode
|
||||||
|
{
|
||||||
|
[ExportGroup("Network Settings")]
|
||||||
|
[Export]
|
||||||
|
public NetworkTransportType networkType = NetworkTransportType.Never_Networked;
|
||||||
|
public NetworkTransportType GetNetworkType(){ return networkType; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public int networkOwner;
|
||||||
|
public int GetNetworkOwner(){ return networkOwner; }
|
||||||
|
|
||||||
|
|
||||||
|
protected List<NetworkNodeMember> _networkNodeMembers = null;
|
||||||
|
protected NetworkNodeSlot _networkNodeSlot = new NetworkNodeSlot();
|
||||||
|
|
||||||
|
public virtual List<NetworkNodeMember> GetNetworkNodeMembers()
|
||||||
|
{
|
||||||
|
if ( _networkNodeMembers != null )
|
||||||
|
{
|
||||||
|
return _networkNodeMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
_networkNodeMembers = CreateNetworkNodeMembers();
|
||||||
|
_networkNodeSlot.onMessage.AddAction( _OnNetworkMessageReceived );
|
||||||
|
|
||||||
|
InitializeNetworkMembers();
|
||||||
|
|
||||||
|
return _networkNodeMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual List<NetworkNodeMember> CreateNetworkNodeMembers()
|
||||||
|
{
|
||||||
|
return new List<NetworkNodeMember>(){ _networkNodeSlot };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void InitializeNetworkMembers()
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < _networkNodeMembers.Count; i++ )
|
||||||
|
{
|
||||||
|
_networkNodeMembers[ i ]._SetNode( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void _OnNetworkMessageReceived( NetworkMessageEvent m )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
|
||||||
|
public class NetworkNodeMember
|
||||||
|
{
|
||||||
|
protected int _networkID = -1;
|
||||||
|
public int networkID => _networkID;
|
||||||
|
public bool hasNetworkID => _networkID != -1;
|
||||||
|
|
||||||
|
public void _SetNetworkID ( int netID )
|
||||||
|
{
|
||||||
|
_networkID = netID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected INetworkNode _networkNode;
|
||||||
|
public INetworkNode networkNode => _networkNode;
|
||||||
|
|
||||||
|
|
||||||
|
protected NetworkTransportType customNetworkType = NetworkTransportType.Never_Networked;
|
||||||
|
protected bool hasCustomNetworkType = false;
|
||||||
|
public NetworkTransportType networkType => hasCustomNetworkType ? customNetworkType : networkNode.GetNetworkType();
|
||||||
|
|
||||||
|
public bool hasOwnedTransportType => NetworkTransportType.Owned_By_One == networkType;
|
||||||
|
|
||||||
|
public bool IsOwnedBy( int sessionMember )
|
||||||
|
{
|
||||||
|
return hasOwnedTransportType && networkNode.GetNetworkOwner() == sessionMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isOwnedLocally
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return IsOwnedBy( NetworkManager.ownSessionMemberIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanReceive()
|
||||||
|
{
|
||||||
|
return NetworkTransportSettings.CanReceive( networkType, networkNode.GetNetworkOwner() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanSend()
|
||||||
|
{
|
||||||
|
return NetworkTransportSettings.CanSend( networkType, networkNode.GetNetworkOwner() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void _SetNode( NetworkNode node )
|
||||||
|
{
|
||||||
|
_networkNode = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReceiveNetworkMessage( NetworkMessageEvent messageEvent )
|
||||||
|
{
|
||||||
|
if ( ! CanReceive() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnNetworkMessageReceived( messageEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnNetworkMessageReceived( NetworkMessageEvent messageEvent )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send( BitView view, List<int> targets = null, bool reliable = true )
|
||||||
|
{
|
||||||
|
if ( ! CanSend() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
var viewWithID = BitView.PrependID( networkID, view );
|
||||||
|
nm.transport.SendMessage( viewWithID, targets, reliable );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendWithID( BitView viewWithID, List<int> targets = null, bool reliable = true )
|
||||||
|
{
|
||||||
|
if ( ! CanSend() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
nm.transport.SendMessage( viewWithID, targets, reliable );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetworkNodeMemberReferences
|
||||||
|
{
|
||||||
|
Dictionary<int,NetworkNodeMember> referencesMap = new Dictionary<int, NetworkNodeMember>();
|
||||||
|
int counter = 1;
|
||||||
|
|
||||||
|
public NetworkNodeMember GetMember( int id )
|
||||||
|
{
|
||||||
|
if ( ! referencesMap.ContainsKey( id ) )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return referencesMap[ id ];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddMembersOf( INetworkNode node )
|
||||||
|
{
|
||||||
|
var members = node.GetNetworkNodeMembers();
|
||||||
|
|
||||||
|
for ( int i = 0; i < members.Count; i++ )
|
||||||
|
{
|
||||||
|
if ( members[ i ].networkType == NetworkTransportType.Never_Networked )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( members[ i ].hasNetworkID )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJLog.Log( "Networked member", HierarchyName.Of( (Node)node ), i );
|
||||||
|
|
||||||
|
var id = counter;
|
||||||
|
referencesMap[ id ] = members[ i ];
|
||||||
|
members[ i ]._SetNetworkID( id );
|
||||||
|
|
||||||
|
counter ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetworkNodeSlot:NetworkNodeMember
|
||||||
|
{
|
||||||
|
public EventSlot<NetworkMessageEvent> onMessage = new EventSlot<NetworkMessageEvent>();
|
||||||
|
|
||||||
|
protected override void OnNetworkMessageReceived( NetworkMessageEvent nme )
|
||||||
|
{
|
||||||
|
onMessage.DispatchEvent( nme );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class JoinSession:Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public NetworkManager networkingManager;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public NetworkSessionRequest sessionRequest;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
networkingManager.Initialize();
|
||||||
|
networkingManager.sessionManager.JoinSession( sessionRequest );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetworkSessionEvent
|
||||||
|
{
|
||||||
|
public long memberIndex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetworkSessionManager
|
||||||
|
{
|
||||||
|
protected bool _isInSession = false;
|
||||||
|
public bool isInSession => _isInSession;
|
||||||
|
|
||||||
|
protected string _sessionName = null;
|
||||||
|
public string sessionName => _sessionName;
|
||||||
|
|
||||||
|
protected int _serverMemberIndex = 0;
|
||||||
|
public int serverMemberIndex => _serverMemberIndex;
|
||||||
|
|
||||||
|
protected int _ownMemberIndex = -1;
|
||||||
|
public int ownMemberIndex => _ownMemberIndex;
|
||||||
|
|
||||||
|
public bool isServer => ownMemberIndex == serverMemberIndex;
|
||||||
|
|
||||||
|
protected List<NetworkSessionMember> _sessionMembers = new List<NetworkSessionMember>();
|
||||||
|
|
||||||
|
public EventSlot<NetworkSessionEvent> onSessionEntered = new EventSlot<NetworkSessionEvent>();
|
||||||
|
public EventSlot<NetworkSessionEvent> onSessionLeft = new EventSlot<NetworkSessionEvent>();
|
||||||
|
|
||||||
|
|
||||||
|
public void StartSession( NetworkSessionRequest sessionRequest )
|
||||||
|
{
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
|
||||||
|
if ( nm.backend == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJLog.Log( "StartSession" );
|
||||||
|
nm.backend.StartSession( sessionRequest );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void JoinSession( NetworkSessionRequest sessionRequest )
|
||||||
|
{
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
|
||||||
|
if ( nm.backend == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJLog.Log( "JoinSession" );
|
||||||
|
|
||||||
|
nm.backend.JoinSession( sessionRequest );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LeaveSession()
|
||||||
|
{
|
||||||
|
var nm = Unique<NetworkManager>.Get();
|
||||||
|
|
||||||
|
if ( nm.backend == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nm.backend.LeaveSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExtendedNetworkSessionManager:NetworkSessionManager
|
||||||
|
{
|
||||||
|
public void SetInSessionState( bool state = true )
|
||||||
|
{
|
||||||
|
_isInSession = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddMember( NetworkSessionMember member )
|
||||||
|
{
|
||||||
|
_sessionMembers.Add( member );
|
||||||
|
|
||||||
|
var nse = new NetworkSessionEvent();
|
||||||
|
nse.memberIndex = member.index;
|
||||||
|
|
||||||
|
onSessionEntered.DispatchEvent( nse );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveMember( long id )
|
||||||
|
{
|
||||||
|
var index = _sessionMembers.FindIndex( m => m.index == id );
|
||||||
|
|
||||||
|
if ( index == -1 )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_sessionMembers.RemoveAt( index );
|
||||||
|
|
||||||
|
var nse = new NetworkSessionEvent();
|
||||||
|
nse.memberIndex = id;
|
||||||
|
|
||||||
|
onSessionLeft.DispatchEvent( nse );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class NetworkSessionMember
|
||||||
|
{
|
||||||
|
long _index;
|
||||||
|
public long index => _index;
|
||||||
|
|
||||||
|
public string name;
|
||||||
|
|
||||||
|
public static NetworkSessionMember Create( long index )
|
||||||
|
{
|
||||||
|
var member = new NetworkSessionMember();
|
||||||
|
member._index = index;
|
||||||
|
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class NetworkSessionRequest:Resource
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public string sessionName = null;
|
||||||
|
[Export]
|
||||||
|
public int maxMembers = -1;
|
||||||
|
[Export]
|
||||||
|
public int port = 1984;
|
||||||
|
[Export]
|
||||||
|
public string serverIP = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public enum NetworkSessionConnectionState
|
||||||
|
{
|
||||||
|
Not_Connected,
|
||||||
|
Connecting_As_Server,
|
||||||
|
Connecting_As_Client,
|
||||||
|
Connected_As_Server,
|
||||||
|
Connected_As_Client
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class StartSession:Action
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public NetworkManager networkingManager;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public NetworkSessionRequest sessionRequest;
|
||||||
|
|
||||||
|
protected override void _OnTrigger()
|
||||||
|
{
|
||||||
|
RJLog.Log( "StartSession:" );
|
||||||
|
|
||||||
|
networkingManager.Initialize();
|
||||||
|
networkingManager.sessionManager.StartSession( sessionRequest );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class NetworkTransform3D:NetworkNode
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public NetworkTransform3DType type;
|
||||||
|
|
||||||
|
NetworkNodeSlot _positionSlot = new NetworkNodeSlot();
|
||||||
|
NetworkNodeSlot _rotationSlot = new NetworkNodeSlot();
|
||||||
|
NetworkNodeSlot _scaleSlot = new NetworkNodeSlot();
|
||||||
|
|
||||||
|
protected override List<NetworkNodeMember> CreateNetworkNodeMembers()
|
||||||
|
{
|
||||||
|
return new List<NetworkNodeMember>()
|
||||||
|
{
|
||||||
|
_networkNodeSlot,
|
||||||
|
_positionSlot,
|
||||||
|
_rotationSlot,
|
||||||
|
_scaleSlot
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 _sendPosition = Vector3.Zero;
|
||||||
|
Vector3 _sendRotation = Vector3.Zero;
|
||||||
|
Vector3 _sendScale = Vector3.One;
|
||||||
|
float _sendTime = 0;
|
||||||
|
bool _idle = true;
|
||||||
|
|
||||||
|
|
||||||
|
public override void _Process( double delta )
|
||||||
|
{
|
||||||
|
if ( ! NetworkManager.IsInSession )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! _networkNodeSlot.hasOwnedTransportType )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _networkNodeSlot.isOwnedLocally )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class NetworkTransform3DType:Resource
|
||||||
|
{
|
||||||
|
[ExportCategory("Position")]
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool positionX;
|
||||||
|
[Export]
|
||||||
|
public bool positionY;
|
||||||
|
[Export]
|
||||||
|
public bool positionZ;
|
||||||
|
|
||||||
|
|
||||||
|
[ExportCategory("Rotation")]
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool rotationX;
|
||||||
|
[Export]
|
||||||
|
public bool rotationY;
|
||||||
|
[Export]
|
||||||
|
public bool rotationZ;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue