Player/Camera Updates
This commit is contained in:
parent
3b74292b2c
commit
af3786e6b4
|
@ -98,7 +98,8 @@ namespace Rokojori
|
||||||
List<HighlightAnimation> _active = new List<HighlightAnimation>();
|
List<HighlightAnimation> _active = new List<HighlightAnimation>();
|
||||||
|
|
||||||
public void Highlight( HighlightActionType type, Node3D[] targets )
|
public void Highlight( HighlightActionType type, Node3D[] targets )
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( HighlightActionType.Start == type )
|
if ( HighlightActionType.Start == type )
|
||||||
{
|
{
|
||||||
StartHighlight( targets );
|
StartHighlight( targets );
|
||||||
|
@ -131,6 +132,7 @@ namespace Rokojori
|
||||||
var outlineMaterial = new OutlineMaterial();
|
var outlineMaterial = new OutlineMaterial();
|
||||||
outlineMaterial.albedo.Set( colorTransparent );
|
outlineMaterial.albedo.Set( colorTransparent );
|
||||||
material = outlineMaterial;
|
material = outlineMaterial;
|
||||||
|
outlineMaterial.size.Set( 2 );
|
||||||
|
|
||||||
outlineMaterial.opacityModulationDuration.Set( opacityModulationDuration );
|
outlineMaterial.opacityModulationDuration.Set( opacityModulationDuration );
|
||||||
outlineMaterial.opacityModulationStrength.Set( opacityModulationStrength );
|
outlineMaterial.opacityModulationStrength.Set( opacityModulationStrength );
|
||||||
|
|
|
@ -31,5 +31,5 @@ opacityModulationStrength = 0.75
|
||||||
opacityModulationDuration = 1.0
|
opacityModulationDuration = 1.0
|
||||||
opacityModulationTransition = 1.0
|
opacityModulationTransition = 1.0
|
||||||
outlineMaterialMode = 0
|
outlineMaterialMode = 0
|
||||||
overlayOpacity = 0.01
|
overlayOpacity = 0.1
|
||||||
overlayMaterialMode = 0
|
overlayMaterialMode = 0
|
||||||
|
|
|
@ -23,7 +23,17 @@ namespace Rokojori
|
||||||
return exp.ComputeDuration();
|
return exp.ComputeDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static float ComputeCoefficientForFramesAdaptiveTreshold( int numFrames )
|
||||||
|
{
|
||||||
|
var fps60 = 1f/60f;
|
||||||
|
var treshold = MathX.MapClamped( numFrames, 400, 600, fps60/50, fps60/2 );
|
||||||
|
|
||||||
|
return ComputeCoefficientForFrames( numFrames, treshold );
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public static float ComputeCoefficientForFrames( int numFrames, float treshold = 1f/60f * 0.02f )
|
public static float ComputeCoefficientForFrames( int numFrames, float treshold = 1f/60f * 0.02f )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,12 @@ namespace Rokojori
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class FrameSmoothing: Smoothing
|
public partial class FrameSmoothing: Smoothing
|
||||||
{
|
{
|
||||||
[Export( PropertyHint.Range, "0,600")]
|
[Export( PropertyHint.Range, "0,1800")]
|
||||||
public float frames = 10;
|
public float frames = 10;
|
||||||
|
|
||||||
protected override float _ComputeInterpolationAmount( float delta )
|
protected override float _ComputeInterpolationAmount( float delta )
|
||||||
{
|
{
|
||||||
frames = Mathf.Clamp( frames, 0, 600 );
|
frames = Mathf.Clamp( frames, 0, 1800 );
|
||||||
|
|
||||||
if ( frames <= 0 )
|
if ( frames <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ namespace Rokojori
|
||||||
|
|
||||||
public static float ComputeCoefficientInt( float delta, int frames )
|
public static float ComputeCoefficientInt( float delta, int frames )
|
||||||
{
|
{
|
||||||
frames = Mathf.Clamp( frames, 0, 600 );
|
frames = Mathf.Clamp( frames, 0, 1800 );
|
||||||
|
|
||||||
if ( frames <= 0 )
|
if ( frames <= 0 )
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,20 +11,13 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public string path;
|
public string path;
|
||||||
|
|
||||||
[Export]
|
[ExportToolButton( "Compute")]
|
||||||
public bool compute
|
public Callable ComputeButton => Callable.From( Compute );
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if ( ! value )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameSmoothingTable.ComputeAndSaveTable( path );
|
async void Compute()
|
||||||
}
|
{
|
||||||
}
|
await FrameSmoothingTable.ComputeAndSaveTable( this, path );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,12 +9,44 @@ namespace Rokojori
|
||||||
public partial class Smoothing: Resource
|
public partial class Smoothing: Resource
|
||||||
{
|
{
|
||||||
float _currentFloat = 0;
|
float _currentFloat = 0;
|
||||||
|
public void SetCurrent( float value )
|
||||||
|
{
|
||||||
|
_currentFloat = value;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 _currentVector2 = Vector2.Zero;
|
Vector2 _currentVector2 = Vector2.Zero;
|
||||||
Vector3 _currentVector3 = Vector3.Zero;
|
Vector3 _currentVector3 = Vector3.Zero;
|
||||||
Vector4 _currentVector4 = Vector4.Zero;
|
Vector4 _currentVector4 = Vector4.Zero;
|
||||||
|
|
||||||
|
public void SetCurrent( Vector2 value )
|
||||||
|
{
|
||||||
|
_currentVector2 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrent( Vector3 value )
|
||||||
|
{
|
||||||
|
_currentVector3 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrent( Vector4 value )
|
||||||
|
{
|
||||||
|
_currentVector4 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Quaternion _currentQuaternion = Quaternion.Identity;
|
Quaternion _currentQuaternion = Quaternion.Identity;
|
||||||
|
|
||||||
|
public void SetCurrent( Quaternion quaternion )
|
||||||
|
{
|
||||||
|
_currentQuaternion = quaternion;
|
||||||
|
}
|
||||||
|
|
||||||
Color _currentColor = Colors.Black;
|
Color _currentColor = Colors.Black;
|
||||||
|
|
||||||
|
public void SetCurrent( Color color )
|
||||||
|
{
|
||||||
|
_currentColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
public float Smooth( float nextValue, float delta )
|
public float Smooth( float nextValue, float delta )
|
||||||
{
|
{
|
||||||
|
@ -29,7 +61,16 @@ namespace Rokojori
|
||||||
return sm.Smooth( value, delta );
|
return sm.Smooth( value, delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 Smooth( Vector2 nextValue, float delta )
|
public static float ApplyWith( Smoothing sm, float oldValue, float nextValue, float delta )
|
||||||
|
{
|
||||||
|
if ( sm == null ){ return nextValue; }
|
||||||
|
|
||||||
|
sm._currentFloat = oldValue;
|
||||||
|
|
||||||
|
return sm.Smooth( nextValue, delta );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 Smooth( Vector2 nextValue, float delta )
|
||||||
{
|
{
|
||||||
_currentVector2 = _currentVector2.Lerp( nextValue, _ComputeInterpolationAmount( delta ) );
|
_currentVector2 = _currentVector2.Lerp( nextValue, _ComputeInterpolationAmount( delta ) );
|
||||||
|
|
||||||
|
@ -42,6 +83,30 @@ namespace Rokojori
|
||||||
return sm.Smooth( value, delta );
|
return sm.Smooth( value, delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float ApplyDegrees( Smoothing sm, float value, float delta )
|
||||||
|
{
|
||||||
|
var newV = MathX.RadiansToVector2( MathX.DegreesToRadians * value );
|
||||||
|
|
||||||
|
return MathX.RadiansToDegrees * MathX.Vector2ToRadians( Apply( sm, newV, delta ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float ApplyDegreesWith( Smoothing sm, float oldValue, float nextValue, float delta )
|
||||||
|
{
|
||||||
|
var oldV = MathX.RadiansToVector2( MathX.DegreesToRadians * oldValue );
|
||||||
|
var newV = MathX.RadiansToVector2( MathX.DegreesToRadians * nextValue );
|
||||||
|
|
||||||
|
return MathX.RadiansToDegrees * MathX.Vector2ToRadians( ApplyWith( sm, oldV, newV, delta ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 ApplyWith( Smoothing sm, Vector2 oldValue, Vector2 nextValue, float delta )
|
||||||
|
{
|
||||||
|
if ( sm == null ){ return nextValue; }
|
||||||
|
|
||||||
|
sm._currentVector2 = oldValue;
|
||||||
|
|
||||||
|
return sm.Smooth( nextValue, delta );
|
||||||
|
}
|
||||||
|
|
||||||
public Vector3 Smooth( Vector3 nextValue, float delta )
|
public Vector3 Smooth( Vector3 nextValue, float delta )
|
||||||
{
|
{
|
||||||
_currentVector3 = _currentVector3.Lerp( nextValue, _ComputeInterpolationAmount( delta ) );
|
_currentVector3 = _currentVector3.Lerp( nextValue, _ComputeInterpolationAmount( delta ) );
|
||||||
|
@ -70,7 +135,8 @@ namespace Rokojori
|
||||||
|
|
||||||
public Quaternion Smooth( Quaternion nextValue, float delta )
|
public Quaternion Smooth( Quaternion nextValue, float delta )
|
||||||
{
|
{
|
||||||
_currentQuaternion = _currentQuaternion.Slerp( nextValue, _ComputeInterpolationAmount( delta ) );
|
_currentQuaternion = _currentQuaternion.GetNormalized();
|
||||||
|
_currentQuaternion = _currentQuaternion.Slerp( nextValue.GetNormalized(), _ComputeInterpolationAmount( delta ) );
|
||||||
|
|
||||||
return _currentQuaternion;
|
return _currentQuaternion;
|
||||||
}
|
}
|
||||||
|
@ -109,16 +175,18 @@ namespace Rokojori
|
||||||
var duration = 0f;
|
var duration = 0f;
|
||||||
var lastValue = value;
|
var lastValue = value;
|
||||||
|
|
||||||
var maxDuration = 30;
|
var maxDuration = 120;
|
||||||
|
|
||||||
while ( value > tresholdValue && duration < maxDuration )
|
Safe.While(
|
||||||
{
|
()=> value > tresholdValue && duration < maxDuration,
|
||||||
lastValue = value;
|
()=>
|
||||||
value = Smooth( 0, delta );
|
{
|
||||||
|
lastValue = value;
|
||||||
|
value = Smooth( 0, delta );
|
||||||
|
|
||||||
duration += delta;
|
duration += delta;
|
||||||
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
_currentFloat = cached;
|
_currentFloat = cached;
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,22 @@ namespace Rokojori
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitializeCamera()
|
||||||
|
{
|
||||||
|
var cameraManager = this.Get<VirtualCamera3DManager>();
|
||||||
|
var camera = this.Get<Camera3D>();
|
||||||
|
|
||||||
|
cameraManager.camera = camera;
|
||||||
|
var slot = cameraManager.CreateChild<VirtualCamera3DSlot>();
|
||||||
|
slot.camera = this.Get<MouseEditorCamera>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,6 +13,11 @@ namespace Rokojori
|
||||||
return Directory.Exists( path );
|
return Directory.Exists( path );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool FileExists( string path )
|
||||||
|
{
|
||||||
|
return File.Exists( path );
|
||||||
|
}
|
||||||
|
|
||||||
public static void CreateDirectory( string path )
|
public static void CreateDirectory( string path )
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory( path );
|
Directory.CreateDirectory( path );
|
||||||
|
|
|
@ -9,6 +9,16 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
public static class Nodes
|
public static class Nodes
|
||||||
{
|
{
|
||||||
|
public static T Get<T>( this Node node ) where T:Node
|
||||||
|
{
|
||||||
|
return GetAnyChild<T>( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T GetChild<T>( this Node node ) where T:Node
|
||||||
|
{
|
||||||
|
return GetDirectChild<T>( node );
|
||||||
|
}
|
||||||
|
|
||||||
public static void CopyData<T>( T from, T to ) where T:Node
|
public static void CopyData<T>( T from, T to ) where T:Node
|
||||||
{
|
{
|
||||||
var memberInfos = ReflectionHelper.GetDataMemberInfos<T>( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
|
var memberInfos = ReflectionHelper.GetDataMemberInfos<T>( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Caster:Node3D
|
public partial class Caster:Node3D
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class CharacterController:Node
|
public partial class CharacterController:Node
|
||||||
{
|
{
|
||||||
|
@ -28,14 +29,10 @@ namespace Rokojori
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float rotationSmoothingDuration = 0;
|
public Smoothing rotationSmoothing;
|
||||||
|
|
||||||
Smoother rotationSmoother = new Smoother();
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float positionSmoothingDuration = 0;
|
public Smoothing positionSmoothing;
|
||||||
|
|
||||||
Smoother positionSmoother = new Smoother();
|
|
||||||
|
|
||||||
public float delta = 0;
|
public float delta = 0;
|
||||||
|
|
||||||
|
@ -49,22 +46,24 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( CharacterUpdateMode.Process == characterUpdateMode )
|
if ( CharacterUpdateMode.Process == characterUpdateMode )
|
||||||
{
|
{
|
||||||
this.delta = (float)delta;
|
this.delta = (float) delta;
|
||||||
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, a => Action.Trigger( a ) );
|
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, Action.Trigger );
|
||||||
}
|
}
|
||||||
|
|
||||||
// positionSmoother.CopyPosition( graphics, body, rotationSmoothingDuration, delta );
|
// positionSmoother.CopyPosition( graphics, body, rotationSmoothingDuration, delta );
|
||||||
// rotationSmoother.CopyRotation( graphics, body, positionSmoothingDuration, delta );
|
// rotationSmoother.CopyRotation( graphics, body, positionSmoothingDuration, delta );
|
||||||
|
|
||||||
Pose.CopyTo( body, graphics );
|
graphics.GlobalPosition = Smoothing.Apply( positionSmoothing, body.GlobalPosition, this.delta );
|
||||||
|
graphics.SetGlobalQuaternion( Smoothing.Apply( rotationSmoothing, body.GetGlobalQuaternion(), this.delta ) );
|
||||||
|
// Pose.CopyTo( body, graphics );
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _PhysicsProcess( double delta )
|
public override void _PhysicsProcess( double delta )
|
||||||
{
|
{
|
||||||
if ( CharacterUpdateMode.Physics_Process == characterUpdateMode )
|
if ( CharacterUpdateMode.Physics_Process == characterUpdateMode )
|
||||||
{
|
{
|
||||||
this.delta = (float)delta;
|
this.delta = (float) delta;
|
||||||
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, a => Action.Trigger( a ) );
|
Nodes.ForEachDirectChild<CharacterControllerAction>( actionsContainer, Action.Trigger );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class CharacterControllerAction:Action
|
public partial class CharacterControllerAction:Action
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,30 +5,18 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class CharacterMovement:CharacterControllerAction
|
public partial class CharacterMovement:CharacterControllerAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public float onFloorMultiply = 0f;
|
public float onFloorMultiply = 1f;
|
||||||
|
|
||||||
[Export]
|
|
||||||
public bool overwriteVelocity = true;
|
|
||||||
|
|
||||||
[ExportGroup( "Actions" )]
|
|
||||||
[Export]
|
|
||||||
public Action onMoving;
|
|
||||||
[Export]
|
|
||||||
public Action onIdle;
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Action onForward;
|
public float inAirMultiply = 0.01f;
|
||||||
[Export]
|
|
||||||
public Action onBackwards;
|
|
||||||
[Export]
|
|
||||||
public Action onStrafeLeft;
|
|
||||||
[Export]
|
|
||||||
public Action onStrafeRight;
|
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public CameraTargetOffset cameraTargetOffset;
|
||||||
|
|
||||||
[ExportGroup( "Direction Source" )]
|
[ExportGroup( "Direction Source" )]
|
||||||
[Export]
|
[Export]
|
||||||
|
@ -39,34 +27,28 @@ namespace Rokojori
|
||||||
None,
|
None,
|
||||||
Zero_Y_And_Normalize,
|
Zero_Y_And_Normalize,
|
||||||
Project_On_TransformPlane
|
Project_On_TransformPlane
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export]
|
[ExportGroup("Movement")]
|
||||||
public DirectionProcessing directionProcessing;
|
|
||||||
|
|
||||||
[ExportGroup( "Moving" )]
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float moveSpeed;
|
public float moveSpeed;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor forward;
|
public CharacterMovementType controllerMovementType;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor backwards;
|
public CharacterMovementType mouseKeyboardMovementType;
|
||||||
|
|
||||||
[ExportGroup( "Strafing" )]
|
|
||||||
[Export]
|
|
||||||
public float strafeSpeed;
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor strafeLeft;
|
public CharacterMovementType currentMovementType;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor strafeRight;
|
public Smoothing onFloorMovementSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool useBodyDirection = true;
|
public Smoothing inAirMovementSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
|
||||||
[ExportGroup( "Rotation" )]
|
[ExportGroup( "Rotation" )]
|
||||||
|
|
||||||
|
@ -74,74 +56,73 @@ namespace Rokojori
|
||||||
public bool adjustRotation = true;
|
public bool adjustRotation = true;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Curve forwardToRotation = MathX.Curve( 0, 1 );
|
public Curve forwardToRotationSmoothingFrames = MathX.Curve( 0, 1 );
|
||||||
|
|
||||||
[Export( PropertyHint.Range, "0,1")]
|
[Export(PropertyHint.Range, "0,600")]
|
||||||
public float rotationSmoothingCoefficient = 0.1f;
|
public int airRotationSmoothingFrames = 120;
|
||||||
Smoother rotationSmoother = new Smoother();
|
|
||||||
|
|
||||||
|
FrameSmoothing rotationSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
protected CharacterMovementData characterMovementData = new CharacterMovementData();
|
||||||
|
|
||||||
protected override void _OnTrigger()
|
protected override void _OnTrigger()
|
||||||
{
|
{
|
||||||
if ( ! body.IsOnFloor() )
|
var onFloor = body.IsOnFloor();
|
||||||
|
|
||||||
|
characterMovementData.Reset( this );
|
||||||
|
|
||||||
|
if ( currentMovementType == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var movement = Vector3.Zero;
|
currentMovementType.ProcessMovement( characterMovementData );
|
||||||
|
|
||||||
var fw = Sensors.GetValue( forward );
|
if ( cameraTargetOffset != null )
|
||||||
var bw = Sensors.GetValue( backwards );
|
|
||||||
|
|
||||||
var fbAxis = Sensors.PolarAxis( backwards, forward );
|
|
||||||
|
|
||||||
var dir = directionSource != null ? directionSource : body;
|
|
||||||
var forwardDirection = dir.GlobalForward();
|
|
||||||
var rightDirection = useBodyDirection ? body.GlobalRight() : dir.GlobalRight();
|
|
||||||
|
|
||||||
if ( DirectionProcessing.Zero_Y_And_Normalize == directionProcessing )
|
|
||||||
{
|
{
|
||||||
forwardDirection.Y = 0;
|
cameraTargetOffset.SetMovingForward( characterMovementData.isMovingForward ? 1f : 0f );
|
||||||
rightDirection.Y = 0;
|
|
||||||
}
|
}
|
||||||
else if ( DirectionProcessing.Project_On_TransformPlane == directionProcessing )
|
|
||||||
{
|
|
||||||
var bodyPlane = Plane3.CreateFromNode3D( body );
|
|
||||||
forwardDirection = bodyPlane.ConstrainToPlane( forwardDirection + body.GlobalPosition ) - body.GlobalPosition;
|
|
||||||
rightDirection = bodyPlane.ConstrainToPlane( rightDirection + body.GlobalPosition ) - body.GlobalPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
forwardDirection = forwardDirection.Normalized();
|
|
||||||
rightDirection = rightDirection.Normalized();
|
|
||||||
|
|
||||||
movement += forwardDirection * Sensors.PolarAxis( backwards, forward ) * moveSpeed;
|
var movementMultiply = onFloor ? onFloorMultiply : inAirMultiply;
|
||||||
|
|
||||||
movement += rightDirection * Sensors.PolarAxis( strafeLeft, strafeRight ) * strafeSpeed ;
|
|
||||||
|
|
||||||
|
characterMovementData.movement *= movementMultiply;
|
||||||
|
|
||||||
|
|
||||||
if ( body.IsOnFloor() )
|
|
||||||
{
|
|
||||||
movement *= onFloorMultiply;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( adjustRotation )
|
if ( adjustRotation )
|
||||||
{
|
{
|
||||||
var currentRotation = body.GetGlobalQuaternion();
|
var nextRotation = Math3D.LookRotation( characterMovementData.forwardDirection );
|
||||||
var nextRotation = Math3D.LookRotation( forwardDirection );
|
var speed = MathX.Clamp01( characterMovementData.movement.Length() / moveSpeed );
|
||||||
|
|
||||||
var sm = 1f - rotationSmoothingCoefficient;
|
if ( speed > 0 )
|
||||||
sm = sm * sm;
|
{
|
||||||
|
Quaternion rotation;
|
||||||
|
|
||||||
var speed = MathX.Clamp01( movement.Length() / moveSpeed ) * Mathf.Max( fw, bw );
|
if ( onFloor )
|
||||||
|
{
|
||||||
sm *= forwardToRotation.Sample( speed );
|
rotationSmoothing.frames = Mathf.Round( forwardToRotationSmoothingFrames.Sample( speed ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rotationSmoothing.frames = airRotationSmoothingFrames;
|
||||||
|
}
|
||||||
|
|
||||||
var rotation = rotationSmoother.SmoothWithCoefficient( currentRotation, nextRotation, sm, controller.delta );
|
rotation = rotationSmoothing.Smooth( nextRotation, controller.delta );
|
||||||
body.SetGlobalQuaternion( rotation );
|
body.SetGlobalQuaternion( rotation );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Velocity( movement, overwriteVelocity );
|
var smoothedMovement = Vector3.Zero;
|
||||||
|
|
||||||
|
if ( onFloor )
|
||||||
|
{
|
||||||
|
smoothedMovement = onFloorMovementSmoothing.Smooth( characterMovementData.movement, controller.delta );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
smoothedMovement = inAirMovementSmoothing.Smooth( characterMovementData.movement, controller.delta );
|
||||||
|
}
|
||||||
|
|
||||||
|
Velocity( smoothedMovement, onFloor );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public enum CharacterDirectionProcessing
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Zero_Y_And_Normalize,
|
||||||
|
Project_On_TransformPlane
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://823d4vtyx5d3
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class CharacterMovementData
|
||||||
|
{
|
||||||
|
public CharacterMovement characterMovement;
|
||||||
|
public Vector3 movement;
|
||||||
|
public Vector3 forwardDirection;
|
||||||
|
public bool isMovingForward;
|
||||||
|
|
||||||
|
public void Reset( CharacterMovement characterMovement )
|
||||||
|
{
|
||||||
|
this.characterMovement = characterMovement;
|
||||||
|
movement = Vector3.Zero;
|
||||||
|
forwardDirection = Vector3.Forward;
|
||||||
|
isMovingForward = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bh7oo1wqi4cau
|
|
@ -0,0 +1,17 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class CharacterMovementType:Resource
|
||||||
|
{
|
||||||
|
public virtual void ProcessMovement( CharacterMovementData characterMovementData )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dco3ngscxqjf5
|
|
@ -0,0 +1,78 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class StrafeMovementType:CharacterMovementType
|
||||||
|
{
|
||||||
|
public enum StrafeDirectionSource
|
||||||
|
{
|
||||||
|
Character_Movement_Direction_Source,
|
||||||
|
Character_Controller_Body
|
||||||
|
}
|
||||||
|
|
||||||
|
[ExportGroup( "Movement" )]
|
||||||
|
[Export]
|
||||||
|
public Sensor forward;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor backwards;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public CharacterDirectionProcessing directionProcessing;
|
||||||
|
|
||||||
|
[ExportGroup( "Strafing" )]
|
||||||
|
[Export]
|
||||||
|
public float strafeSpeedMultiply = 1.0f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor strafeLeft;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor strafeRight;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public StrafeDirectionSource strafeDirectionSource = StrafeDirectionSource.Character_Controller_Body;
|
||||||
|
|
||||||
|
public override void ProcessMovement( CharacterMovementData characterMovementData )
|
||||||
|
{
|
||||||
|
var characterMovement = characterMovementData.characterMovement;
|
||||||
|
var directionSource = characterMovement.directionSource;
|
||||||
|
var body = characterMovement.body;
|
||||||
|
|
||||||
|
var dir = directionSource != null ? directionSource : body;
|
||||||
|
var forwardDirection = dir.GlobalForward();
|
||||||
|
var rightDirection = StrafeDirectionSource.Character_Controller_Body == strafeDirectionSource ?
|
||||||
|
body.GlobalRight() : dir.GlobalRight();
|
||||||
|
|
||||||
|
if ( CharacterDirectionProcessing.Zero_Y_And_Normalize == directionProcessing )
|
||||||
|
{
|
||||||
|
forwardDirection.Y = 0;
|
||||||
|
rightDirection.Y = 0;
|
||||||
|
}
|
||||||
|
else if ( CharacterDirectionProcessing.Project_On_TransformPlane == directionProcessing )
|
||||||
|
{
|
||||||
|
var bodyPlane = Plane3.CreateFromNode3D( body );
|
||||||
|
forwardDirection = bodyPlane.ConstrainToPlane( forwardDirection + body.GlobalPosition ) - body.GlobalPosition;
|
||||||
|
rightDirection = bodyPlane.ConstrainToPlane( rightDirection + body.GlobalPosition ) - body.GlobalPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
forwardDirection = forwardDirection.Normalized();
|
||||||
|
rightDirection = rightDirection.Normalized();
|
||||||
|
|
||||||
|
var movement = forwardDirection * Sensors.PolarAxis( backwards, forward ) * characterMovement.moveSpeed;
|
||||||
|
|
||||||
|
movement += rightDirection * Sensors.PolarAxis( strafeLeft, strafeRight ) * characterMovement.moveSpeed * strafeSpeedMultiply ;
|
||||||
|
|
||||||
|
characterMovementData.movement = movement;
|
||||||
|
characterMovementData.isMovingForward = forward.isActive;
|
||||||
|
characterMovementData.forwardDirection = forwardDirection;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b37sjsfvphc8b
|
|
@ -0,0 +1,105 @@
|
||||||
|
using Godot;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot.Collections;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class TurnMovementType:CharacterMovementType
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public CharacterDirectionProcessing directionProcessing;
|
||||||
|
|
||||||
|
[ExportGroup( "Movement" )]
|
||||||
|
[Export]
|
||||||
|
public Sensor up;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor down;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor left;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor right;
|
||||||
|
|
||||||
|
[ExportGroup( "Strafing" )]
|
||||||
|
[Export]
|
||||||
|
public bool useBodyDirection = true;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor strafeBack;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor strafeLeft;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor strafeRight;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float strafeBackSpeedMultiply = 1.0f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float strafeSidewardsSpeedMultiply = 1.0f;
|
||||||
|
|
||||||
|
public override void ProcessMovement( CharacterMovementData characterMovementData )
|
||||||
|
{
|
||||||
|
var characterMovement = characterMovementData.characterMovement;
|
||||||
|
var directionSource = characterMovement.directionSource;
|
||||||
|
var body = characterMovement.body;
|
||||||
|
|
||||||
|
var dir = directionSource != null ? directionSource : body;
|
||||||
|
var forwardDirection = dir.GlobalForward();
|
||||||
|
var rightDirection = dir.GlobalRight();
|
||||||
|
var forwardStrafe = useBodyDirection ? body.GlobalForward() : dir.GlobalForward();
|
||||||
|
var rightStrafe = useBodyDirection ? body.GlobalRight() : dir.GlobalRight();
|
||||||
|
|
||||||
|
if ( CharacterDirectionProcessing.Zero_Y_And_Normalize == directionProcessing )
|
||||||
|
{
|
||||||
|
forwardDirection.Y = 0;
|
||||||
|
rightDirection.Y = 0;
|
||||||
|
}
|
||||||
|
else if ( CharacterDirectionProcessing.Project_On_TransformPlane == directionProcessing )
|
||||||
|
{
|
||||||
|
var bodyPlane = Plane3.CreateFromNode3D( body );
|
||||||
|
forwardDirection = bodyPlane.ConstrainToPlane( forwardDirection + body.GlobalPosition ) - body.GlobalPosition;
|
||||||
|
rightDirection = bodyPlane.ConstrainToPlane( rightDirection + body.GlobalPosition ) - body.GlobalPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
forwardDirection = forwardDirection.Normalized();
|
||||||
|
rightDirection = rightDirection.Normalized();
|
||||||
|
|
||||||
|
|
||||||
|
var direction = Sensors.FourDirectional( left, right, up, down );
|
||||||
|
|
||||||
|
var movement = forwardDirection * - direction.Y * characterMovement.moveSpeed;
|
||||||
|
|
||||||
|
movement += rightDirection * direction.X * characterMovement.moveSpeed;
|
||||||
|
|
||||||
|
var turningForwardDirection = movement.Normalized();
|
||||||
|
|
||||||
|
if ( Sensors.IsActive( strafeBack ) )
|
||||||
|
{
|
||||||
|
movement += -Sensors.GetValue( strafeBack ) * forwardStrafe * characterMovement.moveSpeed * strafeBackSpeedMultiply;
|
||||||
|
turningForwardDirection = forwardDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Sensors.IsActive( strafeLeft ) || Sensors.IsActive( strafeRight ) )
|
||||||
|
{
|
||||||
|
var strafeStrength = Sensors.PolarAxis( strafeLeft, strafeRight );
|
||||||
|
movement += strafeStrength * rightStrafe * characterMovement.moveSpeed * strafeSidewardsSpeedMultiply;
|
||||||
|
turningForwardDirection = forwardDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
movement = movement.ConstrainLength( characterMovement.moveSpeed );
|
||||||
|
|
||||||
|
characterMovementData.movement = movement;
|
||||||
|
characterMovementData.isMovingForward = ! Math3D.FacingSameDirection( turningForwardDirection, forwardDirection );
|
||||||
|
characterMovementData.forwardDirection = turningForwardDirection;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://kodskdb1mcd4
|
|
@ -5,6 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Gravity:CharacterControllerAction
|
public partial class Gravity:CharacterControllerAction
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class GroundReset:CharacterControllerAction
|
public partial class GroundReset:CharacterControllerAction
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,29 +5,43 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class Jump:CharacterControllerAction
|
public partial class Jump:CharacterControllerAction
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor button;
|
public Sensor button;
|
||||||
|
|
||||||
[Export]
|
[ExportGroup( "Jump Impulse")]
|
||||||
public float jumpStrength;
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float maxJumpDuration;
|
public float jumpImpulseStrength;
|
||||||
|
|
||||||
[Export]
|
[Export( PropertyHint.Range, "0,100" )]
|
||||||
public Curve jumpCurveStrength = MathX.Curve( 1, 0 );
|
public float velocityToJumpDirection = 0.5f;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float jumpedDuration;
|
public float velocityTresholdForJumpDirection = 1f;
|
||||||
|
|
||||||
|
|
||||||
|
[ExportGroup( "Air Control")]
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool canJump = false;
|
public Curve airControlCurveStrength = MathX.Curve( 1, 0 );
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool jumping = false;
|
public float airMaxControlStrength;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float maxAirControlDuration;
|
||||||
|
|
||||||
|
float jumpedDuration;
|
||||||
|
|
||||||
|
bool canJump = false;
|
||||||
|
|
||||||
|
bool jumping = false;
|
||||||
|
|
||||||
|
bool needsToRelease = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +49,11 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
if ( body.IsOnFloor() )
|
if ( body.IsOnFloor() )
|
||||||
{
|
{
|
||||||
jumping = false;
|
if ( jumping )
|
||||||
|
{
|
||||||
|
jumping = false;
|
||||||
|
needsToRelease = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! ( jumping || body.IsOnFloor() ) )
|
if ( ! ( jumping || body.IsOnFloor() ) )
|
||||||
|
@ -46,6 +64,12 @@ namespace Rokojori
|
||||||
if ( ! button.isActive )
|
if ( ! button.isActive )
|
||||||
{
|
{
|
||||||
jumping = false;
|
jumping = false;
|
||||||
|
needsToRelease = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( needsToRelease )
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,17 +77,33 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
jumping = true;
|
jumping = true;
|
||||||
jumpedDuration = 0;
|
jumpedDuration = 0;
|
||||||
|
|
||||||
|
var jumpDirection = Vector3.Up * jumpImpulseStrength;
|
||||||
|
|
||||||
|
if ( body.Velocity.Length() > velocityTresholdForJumpDirection )
|
||||||
|
{
|
||||||
|
var xz = body.Velocity;
|
||||||
|
xz.Y = 0;
|
||||||
|
// xz = xz.Normalized();
|
||||||
|
|
||||||
|
jumpDirection += xz * velocityToJumpDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetVelocity( jumpDirection );
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jumpedDuration += controller.delta;
|
jumpedDuration += controller.delta;
|
||||||
|
|
||||||
canJump = jumpedDuration < maxJumpDuration;
|
canJump = jumpedDuration < maxAirControlDuration;
|
||||||
|
|
||||||
|
|
||||||
if ( jumpedDuration < maxJumpDuration )
|
if ( canJump )
|
||||||
{
|
{
|
||||||
var jumpStrengthMultiply = jumpCurveStrength.Sample( jumpedDuration / maxJumpDuration );
|
var jumpStrengthMultiply = airControlCurveStrength.Sample( jumpedDuration / maxAirControlDuration );
|
||||||
AddVelocity( Vector3.Up * jumpStrength );
|
AddVelocity( Vector3.Up * airMaxControlStrength * jumpStrengthMultiply );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class MoveAndSlide:CharacterControllerAction
|
public partial class MoveAndSlide:CharacterControllerAction
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,10 +21,17 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D grabOffset;
|
public Node3D grabOffset;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing positionSmoothing;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing rotationSmoothing;
|
||||||
|
|
||||||
[ExportGroup("Read Only")]
|
[ExportGroup("Read Only")]
|
||||||
[Export]
|
[Export]
|
||||||
public Grabbable grabbable;
|
public Grabbable grabbable;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
@ -59,7 +66,7 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var grabbable = Nodes.Find<Grabbable>( pointable.GetParent() );
|
grabbable = Nodes.Find<Grabbable>( pointable.GetParent() );
|
||||||
|
|
||||||
if ( grabbable == null )
|
if ( grabbable == null )
|
||||||
{
|
{
|
||||||
|
@ -75,7 +82,9 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
positionSmoothing.SetCurrent( grabbable.grabTarget.GlobalPosition );
|
||||||
|
rotationSmoothing.SetCurrent( grabbable.grabTarget.GetGlobalQuaternion() );
|
||||||
UpdateGrabbable();
|
UpdateGrabbable();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -87,9 +96,11 @@ namespace Rokojori
|
||||||
_callback = null;
|
_callback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateGrabbable()
|
void UpdateGrabbable()
|
||||||
{
|
{
|
||||||
|
// this.LogInfo( "Grabbing", HierarchyName.Of( grabbable ) );
|
||||||
|
grabbable.grabTarget.GlobalPosition = Smoothing.Apply( positionSmoothing, grabOffset.GlobalPosition, timeLine.delta );
|
||||||
|
grabbable.grabTarget.SetGlobalQuaternion( Smoothing.Apply( rotationSmoothing, grabOffset.GetGlobalQuaternion(), timeLine.delta ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class MultiRayCaster:Caster
|
public partial class MultiRayCaster:Caster
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,9 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 to;
|
public Vector3 to;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node collider;
|
||||||
|
|
||||||
public override int NumColliders()
|
public override int NumColliders()
|
||||||
{
|
{
|
||||||
return numCollisions;
|
return numCollisions;
|
||||||
|
@ -59,7 +62,15 @@ namespace Rokojori
|
||||||
ResolveCollisions();
|
ResolveCollisions();
|
||||||
SortCollisions();
|
SortCollisions();
|
||||||
|
|
||||||
|
var nextCollider = NumColliders() == 0 ? null : GetCollider( 0 );
|
||||||
|
|
||||||
|
if ( nextCollider != collider )
|
||||||
|
{
|
||||||
|
collider = nextCollider;
|
||||||
|
|
||||||
|
// this.LogInfo( "New Collider:", HierarchyName.Of( collider ) );
|
||||||
|
}
|
||||||
|
|
||||||
Action.Trigger( afterProcess );
|
Action.Trigger( afterProcess );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ using System.Collections.Generic;
|
||||||
using Godot.Collections;
|
using Godot.Collections;
|
||||||
|
|
||||||
namespace Rokojori
|
namespace Rokojori
|
||||||
{
|
{
|
||||||
|
[Tool]
|
||||||
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Pointer.svg")]
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Pointer.svg")]
|
||||||
public partial class Pointer:Node3D
|
public partial class Pointer:Node3D
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,11 @@ namespace Rokojori
|
||||||
return LookingAtEachOtherAngle( lookDirectionA, lookDirectionB ) > 0;
|
return LookingAtEachOtherAngle( lookDirectionA, lookDirectionB ) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool FacingSameDirection( Vector3 lookDirectionA, Vector3 lookDirectionB )
|
||||||
|
{
|
||||||
|
return ! LookingAtEachOther( lookDirectionA, lookDirectionB );
|
||||||
|
}
|
||||||
|
|
||||||
public static bool LookingTowards( Vector3 from, Vector3 fromDirection, Vector3 to )
|
public static bool LookingTowards( Vector3 from, Vector3 fromDirection, Vector3 to )
|
||||||
{
|
{
|
||||||
return LookingAtEachOther( fromDirection, to - from );
|
return LookingAtEachOther( fromDirection, to - from );
|
||||||
|
@ -103,11 +108,26 @@ namespace Rokojori
|
||||||
return v.X == 0 && v.Y == 0 && v.Z == 0;
|
return v.X == 0 && v.Y == 0 && v.Z == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Vector3 ConstrainLength( this Vector3 v, float maxLength )
|
||||||
|
{
|
||||||
|
var length = v.Length();
|
||||||
|
|
||||||
|
if ( length <= maxLength )
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.Normalized() * maxLength;
|
||||||
|
}
|
||||||
|
|
||||||
public static Vector3 ComputeNormalFast( Vector3 a, Vector3 b, Vector3 c )
|
public static Vector3 ComputeNormalFast( Vector3 a, Vector3 b, Vector3 c )
|
||||||
{
|
{
|
||||||
return Math3D.Cross( c - b , a - b ).Normalized();
|
return Math3D.Cross( c - b , a - b ).Normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static Vector3 ComputeNormal( Vector3 a, Vector3 b, Vector3 c )
|
public static Vector3 ComputeNormal( Vector3 a, Vector3 b, Vector3 c )
|
||||||
{
|
{
|
||||||
var cross = Math3D.Cross( c - b , a - b );
|
var cross = Math3D.Cross( c - b , a - b );
|
||||||
|
@ -440,7 +460,12 @@ namespace Rokojori
|
||||||
|
|
||||||
public static float GlobalYaw( Vector3 direction )
|
public static float GlobalYaw( Vector3 direction )
|
||||||
{
|
{
|
||||||
return Mathf.Atan2( direction.Z, direction.X );
|
return ( Mathf.Pi * 2.0f - Mathf.Atan2( direction.Z, direction.X ) ) - Mathf.Pi / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float GlobalYawDegrees( Vector3 direction )
|
||||||
|
{
|
||||||
|
return Mathf.RadToDeg( GlobalYaw( direction ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float GlobalPitch( Vector3 direction )
|
public static float GlobalPitch( Vector3 direction )
|
||||||
|
@ -451,6 +476,11 @@ namespace Rokojori
|
||||||
return Mathf.Atan2( y, xz );
|
return Mathf.Atan2( y, xz );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float GlobalPitchDegrees( Vector3 direction )
|
||||||
|
{
|
||||||
|
return Mathf.RadToDeg( GlobalPitch( direction ) );
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetGlobalQuaternion( this Node3D node, Quaternion quaternion )
|
public static void SetGlobalQuaternion( this Node3D node, Quaternion quaternion )
|
||||||
{
|
{
|
||||||
var localScale = node.Scale;
|
var localScale = node.Scale;
|
||||||
|
@ -620,6 +650,38 @@ namespace Rokojori
|
||||||
node.GlobalPosition = gp;
|
node.GlobalPosition = gp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetLocalX( this Node3D node, float x )
|
||||||
|
{
|
||||||
|
var gp = node.Position;
|
||||||
|
|
||||||
|
gp.X = x;
|
||||||
|
|
||||||
|
node.Position = gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLocalY( this Node3D node, float y )
|
||||||
|
{
|
||||||
|
var gp = node.Position;
|
||||||
|
|
||||||
|
gp.Y = y;
|
||||||
|
|
||||||
|
node.Position = gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetLocalZ( this Node3D node, float z )
|
||||||
|
{
|
||||||
|
var gp = node.Position;
|
||||||
|
|
||||||
|
gp.Z = z;
|
||||||
|
|
||||||
|
node.Position = gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 GetOrientationBasedGlobalOffset( this Node3D node, Vector3 offset )
|
||||||
|
{
|
||||||
|
return offset.X * node.GlobalRight() + offset.Y * node.GlobalUp() + offset.Z * node.GlobalForward();
|
||||||
|
}
|
||||||
|
|
||||||
public static Vector3 Average( List<Vector3> vectors )
|
public static Vector3 Average( List<Vector3> vectors )
|
||||||
{
|
{
|
||||||
var average = Vector3.Zero;
|
var average = Vector3.Zero;
|
||||||
|
|
|
@ -96,6 +96,21 @@ namespace Rokojori
|
||||||
return Mathf.Abs( AngleDelta( degreesA, degreesB ) );
|
return Mathf.Abs( AngleDelta( degreesA, degreesB ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float NormalizeAngle( float degrees )
|
||||||
|
{
|
||||||
|
while ( degrees > 180 )
|
||||||
|
{
|
||||||
|
degrees -= 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( degrees < -180 )
|
||||||
|
{
|
||||||
|
degrees += 360;
|
||||||
|
}
|
||||||
|
|
||||||
|
return degrees;
|
||||||
|
}
|
||||||
|
|
||||||
public static float Smoothstep ( float edge0, float edge1, float x )
|
public static float Smoothstep ( float edge0, float edge1, float x )
|
||||||
{
|
{
|
||||||
x = MathX.Clamp01( ( x - edge0 ) / ( edge1 - edge0 ) );
|
x = MathX.Clamp01( ( x - edge0 ) / ( edge1 - edge0 ) );
|
||||||
|
@ -118,6 +133,17 @@ namespace Rokojori
|
||||||
return Mathf.Floor( value / snappingDistance ) * snappingDistance;
|
return Mathf.Floor( value / snappingDistance ) * snappingDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector2 RadiansToVector2( float angle )
|
||||||
|
{
|
||||||
|
return new Vector2( Mathf.Cos( angle ), Mathf.Sin( angle ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float Vector2ToRadians( Vector2 circle )
|
||||||
|
{
|
||||||
|
return Mathf.Atan2( circle.Y, circle.X );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public const float DegreesToRadians = Mathf.Pi / 180f;
|
public const float DegreesToRadians = Mathf.Pi / 180f;
|
||||||
public const float RadiansToDegrees = 180f / Mathf.Pi;
|
public const float RadiansToDegrees = 180f / Mathf.Pi;
|
||||||
|
|
||||||
|
|
|
@ -27,23 +27,9 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public MeshInstance3D output;
|
public MeshInstance3D output;
|
||||||
|
|
||||||
[Export]
|
|
||||||
public bool update = false;
|
[ExportToolButton( "Update")]
|
||||||
|
public Callable UpdateButton => Callable.From( () => Create() );
|
||||||
[Export]
|
|
||||||
public bool updateAlways = false;
|
|
||||||
|
|
||||||
public override void _Process( double delta )
|
|
||||||
{
|
|
||||||
if ( ! ( update || updateAlways ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
update = false;
|
|
||||||
|
|
||||||
Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public float X()
|
public float X()
|
||||||
|
@ -148,6 +134,11 @@ namespace Rokojori
|
||||||
|
|
||||||
mg.AddQuad( 20, 21, 22, 23, true );
|
mg.AddQuad( 20, 21, 22, 23, true );
|
||||||
|
|
||||||
|
if ( output == null )
|
||||||
|
{
|
||||||
|
output = this.CreateChild<MeshInstance3D>();
|
||||||
|
}
|
||||||
|
|
||||||
output.Mesh = mg.GenerateMesh();
|
output.Mesh = mg.GenerateMesh();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
[gd_resource type="Resource" script_class="GamePadAxisSensor" load_steps=2 format=3 uid="uid://dbha8dmhxgm05"]
|
[gd_resource type="Resource" script_class="GamePadAxisSensor" load_steps=2 format=3 uid="uid://dbha8dmhxgm05"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadAxisSensor.cs" id="1_yy4wi"]
|
[ext_resource type="Script" uid="uid://cb81s7ud1de7h" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadAxisSensor.cs" id="1_yy4wi"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_yy4wi")
|
script = ExtResource("1_yy4wi")
|
||||||
axis = 0
|
axis = 1
|
||||||
type = 1
|
type = 1
|
||||||
continous = true
|
continous = true
|
||||||
_value = 0.0
|
_value = 0.0
|
|
@ -0,0 +1,9 @@
|
||||||
|
[gd_resource type="Resource" script_class="GamePadAxisSensor" load_steps=2 format=3 uid="uid://ck7woerh7mhp"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cb81s7ud1de7h" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadAxisSensor.cs" id="1_nrdau"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1_nrdau")
|
||||||
|
axis = 3
|
||||||
|
type = 1
|
||||||
|
continous = true
|
|
@ -1,13 +0,0 @@
|
||||||
[gd_resource type="Resource" script_class="GamePadAxisSensor" load_steps=2 format=3 uid="uid://ck7woerh7mhp"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadAxisSensor.cs" id="1_nrdau"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
script = ExtResource("1_nrdau")
|
|
||||||
axis = 3
|
|
||||||
type = 1
|
|
||||||
continous = true
|
|
||||||
_value = 0.0
|
|
||||||
_wasActive = false
|
|
||||||
_active = false
|
|
||||||
_activeTreshold = 0.5
|
|
|
@ -1,12 +1,8 @@
|
||||||
[gd_resource type="Resource" script_class="GamePadButtonSensor" load_steps=2 format=3 uid="uid://jvwwq6guhl77"]
|
[gd_resource type="Resource" script_class="GamePadButtonSensor" load_steps=2 format=3 uid="uid://jvwwq6guhl77"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadButtonSensor.cs" id="1_4da72"]
|
[ext_resource type="Script" uid="uid://0ji11kv86cpk" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadButtonSensor.cs" id="1_4da72"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_4da72")
|
script = ExtResource("1_4da72")
|
||||||
button = 1
|
button = 2
|
||||||
continous = false
|
continous = false
|
||||||
_value = 0.0
|
|
||||||
_wasActive = false
|
|
||||||
_active = false
|
|
||||||
_activeTreshold = 0.5
|
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
[gd_resource type="Resource" script_class="GamePadButtonSensor" load_steps=2 format=3 uid="uid://dpwq5eyla8rob"]
|
[gd_resource type="Resource" script_class="GamePadButtonSensor" load_steps=2 format=3 uid="uid://dpwq5eyla8rob"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadButtonSensor.cs" id="1_yv1r0"]
|
[ext_resource type="Script" uid="uid://0ji11kv86cpk" path="res://addons/rokojori_action_library/Runtime/Sensors/GamePadButtonSensor.cs" id="1_yv1r0"]
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("1_yv1r0")
|
script = ExtResource("1_yv1r0")
|
||||||
button = 2
|
button = 3
|
||||||
continous = false
|
continous = false
|
||||||
_value = 0.0
|
|
||||||
_wasActive = false
|
|
||||||
_active = false
|
|
||||||
_activeTreshold = 0.5
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
[gd_resource type="Resource" script_class="SensorGroup" load_steps=28 format=3 uid="uid://bv40lrpi3831d"]
|
[gd_resource type="Resource" script_class="SensorGroup" load_steps=28 format=3 uid="uid://bv40lrpi3831d"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://addons/rokojori_action_library/Runtime/Sensors/SensorGroup.cs" id="1_k6ypa"]
|
[ext_resource type="Script" uid="uid://da4bhmvkury2" path="res://addons/rokojori_action_library/Runtime/Sensors/SensorGroup.cs" id="1_k6ypa"]
|
||||||
[ext_resource type="Resource" uid="uid://5gnh5dmv1p21" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick X-Negative.tres" id="2_1ywmr"]
|
[ext_resource type="Resource" uid="uid://5gnh5dmv1p21" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Left -X.tres" id="2_1ywmr"]
|
||||||
[ext_resource type="Resource" uid="uid://dsrf03g6mgu5t" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick X-Positive.tres" id="3_1yuu5"]
|
[ext_resource type="Resource" uid="uid://dsrf03g6mgu5t" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Right +X.tres" id="3_1yuu5"]
|
||||||
[ext_resource type="Resource" uid="uid://dbha8dmhxgm05" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Y-Negative.tres" id="4_ehig4"]
|
[ext_resource type="Resource" uid="uid://dbha8dmhxgm05" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Up -Y.tres" id="4_ehig4"]
|
||||||
[ext_resource type="Resource" uid="uid://cyyy0ycusgil3" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Y-Positive.tres" id="5_adyq7"]
|
[ext_resource type="Resource" uid="uid://cyyy0ycusgil3" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Left-Joystick Down +Y.tres" id="5_adyq7"]
|
||||||
[ext_resource type="Resource" uid="uid://b16mtcrpm1f6i" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick X-Negative.tres" id="6_g7fxo"]
|
[ext_resource type="Resource" uid="uid://b16mtcrpm1f6i" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Left -X.tres" id="6_g7fxo"]
|
||||||
[ext_resource type="Resource" uid="uid://d05w143o644d3" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick X-Positive.tres" id="7_b0v3q"]
|
[ext_resource type="Resource" uid="uid://d05w143o644d3" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Right +X.tres" id="7_b0v3q"]
|
||||||
[ext_resource type="Resource" uid="uid://ck7woerh7mhp" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Y-Negative.tres" id="8_ljqng"]
|
[ext_resource type="Resource" uid="uid://ck7woerh7mhp" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Up -Y.tres" id="8_ljqng"]
|
||||||
[ext_resource type="Resource" uid="uid://6emg8n3qxhlv" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Y-Positive.tres" id="9_qkgw5"]
|
[ext_resource type="Resource" uid="uid://6emg8n3qxhlv" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Right-Joystick Down +Y.tres" id="9_qkgw5"]
|
||||||
[ext_resource type="Resource" uid="uid://cs12bjge707ri" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Trigger Left, LT, PS L2, Nin ZL.tres" id="10_t2i3f"]
|
[ext_resource type="Resource" uid="uid://cs12bjge707ri" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Trigger Left, LT, PS L2, Nin ZL.tres" id="10_t2i3f"]
|
||||||
[ext_resource type="Resource" uid="uid://cy3ja8squnin6" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Trigger Right, RT, PS R2, Nin ZR.tres" id="11_u6ig2"]
|
[ext_resource type="Resource" uid="uid://cy3ja8squnin6" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Axis/Trigger Right, RT, PS R2, Nin ZR.tres" id="11_u6ig2"]
|
||||||
[ext_resource type="Resource" uid="uid://dffkdky8iowro" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Buttons/Button A, PS Cross, Nin B.tres" id="12_0r6yt"]
|
[ext_resource type="Resource" uid="uid://dffkdky8iowro" path="res://addons/rokojori_action_library/Runtime/Sensors/Default-Sensors/Gamepad/Buttons/Button A, PS Cross, Nin B.tres" id="12_0r6yt"]
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/SensorGroup.svg")]
|
||||||
|
public partial class HoldSensor : Sensor
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Sensor holdButton;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool negateHoldButton;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor triggerButton;
|
||||||
|
|
||||||
|
protected override void UpdateValue()
|
||||||
|
{
|
||||||
|
if ( holdButton == null || triggerButton == null )
|
||||||
|
{
|
||||||
|
SetFloatValue( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var holdButtonValue = holdButton.isActive;
|
||||||
|
|
||||||
|
if ( negateHoldButton )
|
||||||
|
{
|
||||||
|
holdButtonValue = ! holdButtonValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! holdButtonValue )
|
||||||
|
{
|
||||||
|
SetFloatValue( 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetFloatValue( triggerButton.value );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return RJLog.GetInfo( this, holdButton, triggerButton );
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public InputIcon[] inputIcons = [];
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool useInputIconsFromSensors = true;
|
||||||
|
|
||||||
|
public override List<InputIcon> GetInputIcons()
|
||||||
|
{
|
||||||
|
var list = Lists.From( inputIcons );
|
||||||
|
|
||||||
|
if ( useInputIconsFromSensors )
|
||||||
|
{
|
||||||
|
if ( holdButton != null )
|
||||||
|
{
|
||||||
|
list.AddRange( holdButton.GetInputIcons() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( triggerButton != null )
|
||||||
|
{
|
||||||
|
list.AddRange( triggerButton.GetInputIcons() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b3c1sl7uhvqu8
|
|
@ -17,18 +17,13 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public bool continous = false;
|
public bool continous = false;
|
||||||
|
|
||||||
[ExportGroup("Read Only")]
|
protected float _value = 0;
|
||||||
[Export]
|
|
||||||
public float _value = 0;
|
|
||||||
|
|
||||||
[Export]
|
protected bool _wasActive = false;
|
||||||
public bool _wasActive = false;
|
|
||||||
|
|
||||||
[Export]
|
protected bool _active = false;
|
||||||
public bool _active = false;
|
|
||||||
|
|
||||||
[Export]
|
protected float _activeTreshold = 0.5f;
|
||||||
public float _activeTreshold = 0.5f;
|
|
||||||
|
|
||||||
public void ProcessSensor( SensorRunner runner, float delta )
|
public void ProcessSensor( SensorRunner runner, float delta )
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,16 +35,22 @@ namespace Rokojori
|
||||||
|
|
||||||
[ExportGroup("Read Only")]
|
[ExportGroup("Read Only")]
|
||||||
[Export]
|
[Export]
|
||||||
public SensorDevice[] deviceList = new SensorDevice[]{};
|
public SensorDevice[] deviceList =[];
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float[] deviceLastInputTimeStamp = new float[]{};
|
public float[] deviceLastInputTimeStamp = [];
|
||||||
|
|
||||||
[ExportGroup("Testing")]
|
[ExportGroup("Testing")]
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public SensorDevice testingLastActiveDevice;
|
public SensorDevice testingLastActiveDevice;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool showRegistratedSensors = true;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Sensor[] registratedSensors = [];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +67,12 @@ namespace Rokojori
|
||||||
DateTime _startTime;
|
DateTime _startTime;
|
||||||
|
|
||||||
|
|
||||||
|
public bool isMouseKeyboardLastActive => lastActiveDevice == mouseKeyboardDevice ||
|
||||||
|
lastActiveDevice == mouseDevice ||
|
||||||
|
lastActiveDevice == keyboardDevice;
|
||||||
|
|
||||||
|
public bool isControllerLastActive => lastActiveDevice == gamePadDevice;
|
||||||
|
|
||||||
public SensorDevice lastActiveDevice
|
public SensorDevice lastActiveDevice
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -175,8 +187,11 @@ namespace Rokojori
|
||||||
runners.ForEach( r => r.Update( (float) delta ) );
|
runners.ForEach( r => r.Update( (float) delta ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Register( Sensor s, SensorInputHandler sih )
|
public void Register( Sensor s, SensorInputHandler sih )
|
||||||
{
|
{
|
||||||
|
this.LogInfo( "Registrating", s );
|
||||||
|
|
||||||
var sensorRunner = sensorToRunner[ s ];
|
var sensorRunner = sensorToRunner[ s ];
|
||||||
|
|
||||||
if ( sensorRunner.listeners.Contains( sih ) )
|
if ( sensorRunner.listeners.Contains( sih ) )
|
||||||
|
@ -185,6 +200,8 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
|
|
||||||
sensorRunner.listeners.Add( sih );
|
sensorRunner.listeners.Add( sih );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unregister( Sensor s, SensorInputHandler sih )
|
public void Unregister( Sensor s, SensorInputHandler sih )
|
||||||
|
@ -196,6 +213,11 @@ namespace Rokojori
|
||||||
public static void Register( SensorInputHandler handler, params Sensor[] sensors )
|
public static void Register( SensorInputHandler handler, params Sensor[] sensors )
|
||||||
{
|
{
|
||||||
var sm = Unique<SensorManager>.Get();
|
var sm = Unique<SensorManager>.Get();
|
||||||
|
|
||||||
|
if ( sm == null )
|
||||||
|
{
|
||||||
|
Nodes.ForEachInScene<Node>( n => n.LogInfo() );
|
||||||
|
}
|
||||||
|
|
||||||
foreach ( var s in sensors )
|
foreach ( var s in sensors )
|
||||||
{
|
{
|
||||||
|
@ -241,6 +263,11 @@ namespace Rokojori
|
||||||
|
|
||||||
sensorsSet.Add( s );
|
sensorsSet.Add( s );
|
||||||
runners.Add( new SensorRunner( s ) );
|
runners.Add( new SensorRunner( s ) );
|
||||||
|
|
||||||
|
if ( showRegistratedSensors )
|
||||||
|
{
|
||||||
|
registratedSensors = Arrays.Add( registratedSensors, s );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet<object> _scannedObjects = new HashSet<object>();
|
HashSet<object> _scannedObjects = new HashSet<object>();
|
||||||
|
@ -257,6 +284,19 @@ namespace Rokojori
|
||||||
|
|
||||||
var sensors = ReflectionHelper.GetDataMemberValues<Sensor>( obj );
|
var sensors = ReflectionHelper.GetDataMemberValues<Sensor>( obj );
|
||||||
|
|
||||||
|
if ( sensors.Count > 0 )
|
||||||
|
{
|
||||||
|
if ( obj is Node n )
|
||||||
|
{
|
||||||
|
n.LogInfo( sensors );
|
||||||
|
}
|
||||||
|
else if ( obj is Resource r )
|
||||||
|
{
|
||||||
|
r.LogInfo( sensors );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sensors.ForEach(
|
sensors.ForEach(
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
|
@ -309,12 +349,12 @@ namespace Rokojori
|
||||||
|
|
||||||
foreach ( var n in autoScanForSensors )
|
foreach ( var n in autoScanForSensors )
|
||||||
{
|
{
|
||||||
Nodes.ForEach<Node>( n, cn=> AddSensorsFrom( cn ) );
|
Nodes.ForEach<Node>( n, AddSensorsFrom );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( autoScanParent )
|
if ( autoScanParent )
|
||||||
{
|
{
|
||||||
Nodes.ForEach<Node>( GetParent(), cn=> AddSensorsFrom( cn ) );
|
Nodes.ForEach<Node>( GetParent(), AddSensorsFrom );
|
||||||
}
|
}
|
||||||
|
|
||||||
runners.ForEach(
|
runners.ForEach(
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/SensorManager.svg")]
|
||||||
|
public partial class SensorViewer: Node
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public Sensor sensor;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float value;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool active;
|
||||||
|
|
||||||
|
|
||||||
|
public override void _Process(double delta)
|
||||||
|
{
|
||||||
|
if ( sensor == null )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = sensor.value;
|
||||||
|
active = sensor.isActive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bodk4mqlebnwi
|
|
@ -34,5 +34,23 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
return GetValue( negative, -scale, deadZone ) + GetValue( positive, scale, deadZone );
|
return GetValue( negative, -scale, deadZone ) + GetValue( positive, scale, deadZone );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector2 FourDirectional( Sensor left, Sensor right, Sensor up, Sensor down, bool normalize = true, float deadZone = 0.3f )
|
||||||
|
{
|
||||||
|
var x = PolarAxis( left, right, 1, deadZone );
|
||||||
|
var y = PolarAxis( up, down, 1, deadZone );
|
||||||
|
|
||||||
|
|
||||||
|
var v = new Vector2( x, y );
|
||||||
|
|
||||||
|
if ( normalize && v.Length() > 1 )
|
||||||
|
{
|
||||||
|
v = v.Normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,9 @@ namespace Rokojori
|
||||||
public Action action;
|
public Action action;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
this.LogInfo( "Root" );
|
||||||
|
|
||||||
SensorManager.Register( this, sensor );
|
SensorManager.Register( this, sensor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,4 +72,19 @@ float angleDelta( float degreesA, float degreesB )
|
||||||
float angleDelta = degreesB - degreesA;
|
float angleDelta = degreesB - degreesA;
|
||||||
angleDelta = mod( angleDelta + 180.0, 360.0 ) - 180.0;
|
angleDelta = mod( angleDelta + 180.0, 360.0 ) - 180.0;
|
||||||
return angleDelta;
|
return angleDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
float snapRounded( float value, float snappingDistance )
|
||||||
|
{
|
||||||
|
return round( value / snappingDistance ) * snappingDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float snapCeiled( float value, float snappingDistance )
|
||||||
|
{
|
||||||
|
return ceil( value / snappingDistance ) * snappingDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float snapFloored( float value, float snappingDistance )
|
||||||
|
{
|
||||||
|
return floor( value / snappingDistance ) * snappingDistance;
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Noise.gdshaderinc"
|
// #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Noise.gdshaderinc"
|
||||||
|
|
||||||
|
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc"
|
||||||
|
|
||||||
float random( vec2 uv )
|
float random( vec2 uv )
|
||||||
{
|
{
|
||||||
return fract( sin( dot( uv.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453123 );
|
return fract( sin( dot( uv.xy, vec2( 12.9898, 78.233 ) ) ) * 43758.5453123 );
|
||||||
|
@ -7,9 +9,16 @@ float random( vec2 uv )
|
||||||
|
|
||||||
vec2 random_v2( vec2 uv )
|
vec2 random_v2( vec2 uv )
|
||||||
{
|
{
|
||||||
return vec2( fract( sin( dot( uv.xy, vec2( 12.9898,78.233 ) ) ) * 43758.5453123 ) );
|
uv = vec2
|
||||||
|
(
|
||||||
|
dot(uv, vec2( 127.1,311.7 ) ),
|
||||||
|
dot(uv, vec2( 269.5,183.3 ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
return -1.0 + 2.0 * fract( sin( uv ) * 43758.5453123 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vec3 random_v3( vec3 uvw )
|
vec3 random_v3( vec3 uvw )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -20,7 +29,20 @@ vec3 random_v3( vec3 uvw )
|
||||||
return -1.0 + 2.0 * fract(sin(uvw) * 43758.5453123);
|
return -1.0 + 2.0 * fract(sin(uvw) * 43758.5453123);
|
||||||
}
|
}
|
||||||
|
|
||||||
float perlin( vec2 uv )
|
// float perlin( vec2 uv )
|
||||||
|
// {
|
||||||
|
// vec2 uv_index = floor(uv);
|
||||||
|
// vec2 uv_fract = fract(uv);
|
||||||
|
|
||||||
|
// vec2 blur = smoothstep(0.0, 1.0, uv_fract);
|
||||||
|
|
||||||
|
// return mix( mix( dot( random_v2(uv_index + vec2(0.0,0.0) ), uv_fract - vec2(0.0,0.0) ),
|
||||||
|
// dot( random_v2(uv_index + vec2(1.0,0.0) ), uv_fract - vec2(1.0,0.0) ), blur.x),
|
||||||
|
// mix( dot( random_v2(uv_index + vec2(0.0,1.0) ), uv_fract - vec2(0.0,1.0) ),
|
||||||
|
// dot( random_v2(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) + 0.5;
|
||||||
|
// }
|
||||||
|
|
||||||
|
float perlin(vec2 uv)
|
||||||
{
|
{
|
||||||
vec2 uv_index = floor(uv);
|
vec2 uv_index = floor(uv);
|
||||||
vec2 uv_fract = fract(uv);
|
vec2 uv_fract = fract(uv);
|
||||||
|
@ -33,6 +55,61 @@ float perlin( vec2 uv )
|
||||||
dot( random_v2(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) + 0.5;
|
dot( random_v2(uv_index + vec2(1.0,1.0) ), uv_fract - vec2(1.0,1.0) ), blur.x), blur.y) + 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float perlinOctaves( vec2 uv, int octaves, float scale, float gain )
|
||||||
|
{
|
||||||
|
float s = 1.0;
|
||||||
|
float g = 1.0;
|
||||||
|
|
||||||
|
float v = perlin( uv * s ) * g;
|
||||||
|
float n = 1.0;
|
||||||
|
|
||||||
|
for ( int i = 0; i < octaves; i++ )
|
||||||
|
{
|
||||||
|
s *= scale;
|
||||||
|
g *= gain;
|
||||||
|
|
||||||
|
v += perlin( uv * s ) * g;
|
||||||
|
n += g;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v / n;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 seamLessCoordinate( vec2 uv, vec2 seamRange, vec2 seamFade, vec2 type )
|
||||||
|
{
|
||||||
|
return mod( uv - seamFade * type, seamRange );
|
||||||
|
}
|
||||||
|
|
||||||
|
float perlinOctavesSeamless( vec2 uv, int octaves, float scale, float gain, vec2 seamRange, vec2 seamFade )
|
||||||
|
{
|
||||||
|
// uv = mod( uv , seamRange );
|
||||||
|
seamFade *= seamRange;
|
||||||
|
vec2 fading = mod( uv, seamRange ) ;
|
||||||
|
fading.x = normalizeToRange01( fading.x, seamRange.x - seamFade.x, seamRange.x );
|
||||||
|
fading.y = normalizeToRange01( fading.y, seamRange.y - seamFade.y, seamRange.y );
|
||||||
|
|
||||||
|
|
||||||
|
// 0, seamRange - seamFade, seamRange
|
||||||
|
//
|
||||||
|
|
||||||
|
vec2 p00 = seamLessCoordinate( uv, seamRange, seamFade, vec2( 0.0, 0.0 ) );
|
||||||
|
vec2 p10 = seamLessCoordinate( uv, seamRange, seamFade, vec2( 1.0, 0.0 ) );
|
||||||
|
vec2 p01 = seamLessCoordinate( uv, seamRange, seamFade, vec2( 0.0, 1.0 ) );
|
||||||
|
vec2 p11 = seamLessCoordinate( uv, seamRange, seamFade, vec2( 1.0, 1.0 ) );
|
||||||
|
|
||||||
|
float n00 = perlinOctaves( p00, octaves, scale, gain );
|
||||||
|
float n10 = perlinOctaves( p10, octaves, scale, gain );
|
||||||
|
float n01 = perlinOctaves( p01, octaves, scale, gain );
|
||||||
|
float n11 = perlinOctaves( p11, octaves, scale, gain );
|
||||||
|
|
||||||
|
float n0 = mix( n00, n10, fading.x );
|
||||||
|
float n1 = mix( n01, n11, fading.x );
|
||||||
|
|
||||||
|
return mix( n0, n1, fading.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
float perlin3D( vec3 uvw )
|
float perlin3D( vec3 uvw )
|
||||||
{
|
{
|
||||||
vec3 gridIndex = floor( uvw );
|
vec3 gridIndex = floor( uvw );
|
||||||
|
|
|
@ -43,11 +43,12 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
low = tweened;
|
low = tweened;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
high = tweened;
|
high = tweened;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( validateLimits != null && ! validateLimits( low, high ) )
|
if ( validateLimits != null && ! validateLimits( low, high ) )
|
||||||
{
|
{
|
||||||
throw new Exception( "Limit validation failed" );
|
throw new Exception( "Limit validation failed" );
|
||||||
|
|
|
@ -39,6 +39,20 @@ namespace Rokojori
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<double> WaitIfExceeded( double last, Node node, double waitTime = Async.waitTime )
|
||||||
|
{
|
||||||
|
var now = Time.GetTicksMsec() / 1000.0;
|
||||||
|
|
||||||
|
if ( ( now - last ) > waitTime )
|
||||||
|
{
|
||||||
|
await node.RequestNextFrame();
|
||||||
|
|
||||||
|
return Time.GetTicksMsec() / 1000.0;;
|
||||||
|
}
|
||||||
|
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
public static double DoIfExceeded( double last, System.Action action, double waitTime = Async.waitTime )
|
public static double DoIfExceeded( double last, System.Action action, double waitTime = Async.waitTime )
|
||||||
{
|
{
|
||||||
var now = Time.GetTicksMsec() / 1000.0;
|
var now = Time.GetTicksMsec() / 1000.0;
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
public class Safe
|
public class Safe
|
||||||
{
|
{
|
||||||
static readonly int maxWhileIterations = 2000 * 1000;
|
static readonly int maxWhileIterations = 1000 * 1000;
|
||||||
|
|
||||||
public static void While( Func<bool> condition, System.Action action, System.Action onTooManyIterations = null )
|
public static void While( Func<bool> condition, System.Action action, System.Action onTooManyIterations = null )
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class CameraTargetOffset:Node3D
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public float cameraTargetMinOffsetZ = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float cameraTargetMaxOffsetZ = 10;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing cameraTargetOffsetZSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float cameraTargetMinOffsetY = 1.7f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float cameraTargetMaxOffsetY = 2f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing cameraTargetOffsetYSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
protected float nextZ = 0;
|
||||||
|
protected float nextY = 0;
|
||||||
|
|
||||||
|
public virtual void SetMovingForward( float movingForward )
|
||||||
|
{
|
||||||
|
nextZ = Mathf.Lerp( cameraTargetMinOffsetZ, cameraTargetMaxOffsetZ, movingForward );
|
||||||
|
nextY = Mathf.Lerp( cameraTargetMinOffsetY, cameraTargetMaxOffsetY, movingForward );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process( double delta )
|
||||||
|
{
|
||||||
|
var smoothedOffsetZ = cameraTargetOffsetZSmoothing.Smooth( nextZ, (float)delta );
|
||||||
|
this.SetLocalZ( smoothedOffsetZ );
|
||||||
|
|
||||||
|
|
||||||
|
var smoothedOffsetY = cameraTargetOffsetYSmoothing.Smooth( nextY, (float)delta );
|
||||||
|
this.SetLocalY( smoothedOffsetY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bk5eoi53m08jh
|
|
@ -14,6 +14,9 @@ namespace Rokojori
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
public Node3D target;
|
public Node3D target;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing targetFollowSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
[ExportGroup("Yaw")]
|
[ExportGroup("Yaw")]
|
||||||
|
|
||||||
|
@ -26,14 +29,39 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public Sensor yawNegativeAxis;
|
public Sensor yawNegativeAxis;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool roundYaw = false;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public int roundedYawResolution = 64;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float yaw = 0;
|
public float yaw = 0;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float yawSmoothingDuration = 0.1f;
|
public Smoothing yawSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public bool yawGoesBehindPlayer = true;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing yawToBehingSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float yawBehindDelayDuration = 5;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float yawGoesBehindActivation = 0.1f;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float behindYaw = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float currentYaw = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float bcDelta = 0;
|
||||||
|
|
||||||
Smoother yawSmoother = new Smoother();
|
|
||||||
|
|
||||||
[ExportGroup("Pitch")]
|
[ExportGroup("Pitch")]
|
||||||
|
|
||||||
|
@ -58,27 +86,44 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public float maxPitch = 80;
|
public float maxPitch = 80;
|
||||||
|
|
||||||
|
public float normalizedPitch => MathX.NormalizeClamped( pitch, minPitch, maxPitch );
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float pitchSmoothingDuration = 0.1f;
|
public Smoothing pitchSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
Smoother pitchSmoother = new Smoother();
|
[Export]
|
||||||
|
public bool pitchGoesBackToCenter = true;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Smoothing toCenterPitchSmoothing = new FrameSmoothing();
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float centerPitchDelayDuration = 5;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float centerPitch = 30;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public float centerPitchActivation = 0.1f;
|
||||||
|
|
||||||
|
[ExportGroup("Distance")]
|
||||||
[Export]
|
[Export]
|
||||||
public Curve distanceForPitch = MathX.Curve( 1, 1 );
|
public Curve distanceForPitch = MathX.Curve( 1, 1 );
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public float distanceScale = 1;
|
public float distanceScale = 1;
|
||||||
|
|
||||||
[ExportGroup("Offset")]
|
[ExportGroup("Camera Offset")]
|
||||||
[Export]
|
[Export]
|
||||||
public Vector3 offset;
|
public Vector3 offset;
|
||||||
|
|
||||||
Smoother distanceSmoother = new Smoother();
|
|
||||||
|
|
||||||
float smoothedYaw = 0;
|
float smoothedYaw = 0;
|
||||||
float smoothedPitch = 0;
|
float smoothedPitch = 0;
|
||||||
float smoothedDistance = 0;
|
float smoothedDistance = 0;
|
||||||
|
|
||||||
|
float _centerPitchActivation = 0;
|
||||||
|
float _yawBehindActivation = 0;
|
||||||
|
|
||||||
public override void _Process( double delta )
|
public override void _Process( double delta )
|
||||||
{
|
{
|
||||||
|
@ -87,38 +132,97 @@ namespace Rokojori
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
behindYaw = Math3D.GlobalYawDegrees( target.GlobalForward() * -1 );
|
||||||
|
behindYaw = MathX.NormalizeAngle( behindYaw );
|
||||||
|
|
||||||
|
currentYaw = MathX.NormalizeAngle( yaw );
|
||||||
|
|
||||||
|
bcDelta = MathX.NormalizeAngle( MathX.AngleDelta( behindYaw, currentYaw ) );
|
||||||
|
|
||||||
|
var targetPosition = Smoothing.Apply( targetFollowSmoothing, target.GlobalPosition, (float) delta );
|
||||||
|
|
||||||
|
|
||||||
var yawAxis = Sensors.PolarAxis( yawNegativeAxis, yawPositiveAxis );
|
var yawAxis = Sensors.PolarAxis( yawNegativeAxis, yawPositiveAxis );
|
||||||
var pitchAxis = Sensors.PolarAxis( pitchNegativeAxis, pitchPositiveAxis );
|
var pitchAxis = Sensors.PolarAxis( pitchNegativeAxis, pitchPositiveAxis );
|
||||||
|
|
||||||
|
|
||||||
yaw += yawAxis * yawSpeed * (float)delta;
|
yaw += yawAxis * yawSpeed * (float)delta;
|
||||||
|
|
||||||
|
if ( yawGoesBehindPlayer )
|
||||||
|
{
|
||||||
|
if ( Mathf.Abs( yawAxis ) < yawGoesBehindActivation )
|
||||||
|
{
|
||||||
|
_yawBehindActivation += (float)delta;
|
||||||
|
|
||||||
|
if ( yawGoesBehindPlayer && _yawBehindActivation > yawBehindDelayDuration )
|
||||||
|
{
|
||||||
|
yaw = Smoothing.ApplyDegreesWith( yawToBehingSmoothing, yaw, behindYaw, (float) delta );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_yawBehindActivation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// yaw = MathX.Repeat( yaw, 360f );
|
// yaw = MathX.Repeat( yaw, 360f );
|
||||||
|
|
||||||
if ( pitchIsRelative )
|
if ( pitchIsRelative )
|
||||||
{
|
{
|
||||||
pitch += pitchAxis * pitchSpeed * (float)delta;
|
pitch += pitchAxis * pitchSpeed * (float)delta;
|
||||||
pitch = Mathf.Clamp( pitch, minPitch, maxPitch );
|
pitch = Mathf.Clamp( pitch, minPitch, maxPitch );
|
||||||
|
|
||||||
|
if ( Mathf.Abs( pitchAxis ) < centerPitchActivation )
|
||||||
|
{
|
||||||
|
_centerPitchActivation += (float)delta;
|
||||||
|
|
||||||
|
if ( _centerPitchActivation > centerPitchDelayDuration )
|
||||||
|
{
|
||||||
|
pitch = Smoothing.ApplyWith( toCenterPitchSmoothing, pitch, centerPitch, (float) delta );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_centerPitchActivation = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pitch = Mathf.Remap( pitchAxis, -1, 1, minPitch, maxPitch );
|
pitch = Mathf.Remap( pitchAxis, -1, 1, minPitch, maxPitch );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( Mathf.Abs( yaw - smoothedYaw ) > 180 )
|
// if ( Mathf.Abs( yaw - smoothedYaw ) > 180 )
|
||||||
{
|
// {
|
||||||
if ( yaw > smoothedYaw )
|
// if ( yaw > smoothedYaw )
|
||||||
{
|
// {
|
||||||
smoothedYaw += 360;
|
// smoothedYaw += 360;
|
||||||
}
|
// }
|
||||||
else if ( yaw < smoothedYaw )
|
// else if ( yaw < smoothedYaw )
|
||||||
{
|
// {
|
||||||
smoothedYaw -= 360;
|
// smoothedYaw -= 360;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
var appliedYaw = yaw;
|
||||||
|
|
||||||
|
// if ( roundYaw )
|
||||||
|
// {
|
||||||
|
// appliedYaw = MathX.SnapRounded( yaw, 360f/roundedYawResolution );
|
||||||
|
// }
|
||||||
|
|
||||||
|
smoothedYaw = Smoothing.ApplyDegrees( yawSmoothing, appliedYaw, (float) delta );
|
||||||
|
|
||||||
|
|
||||||
|
smoothedPitch = Smoothing.Apply( pitchSmoothing, pitch, (float) delta );
|
||||||
|
|
||||||
|
// if ( pitchGoesBackToCenter )
|
||||||
|
// {
|
||||||
|
// pitch = toCenterPitchSmoothing.Smooth( centerPitch, (float) delta );
|
||||||
|
// }
|
||||||
|
|
||||||
smoothedYaw = yaw;
|
|
||||||
smoothedPitch = pitchSmoother.SmoothForDuration( smoothedPitch, pitch, pitchSmoothingDuration, (float) delta );
|
|
||||||
|
|
||||||
// RJLog.Log( "Pitch", smoothedPitch );
|
// RJLog.Log( "Pitch", smoothedPitch );
|
||||||
|
|
||||||
|
@ -126,11 +230,11 @@ namespace Rokojori
|
||||||
// smoothedPitch = pitch;
|
// smoothedPitch = pitch;
|
||||||
var distance = distanceForPitch.Sample( MathX.NormalizeClamped( pitch, minPitch, maxPitch ) ) * distanceScale;
|
var distance = distanceForPitch.Sample( MathX.NormalizeClamped( pitch, minPitch, maxPitch ) ) * distanceScale;
|
||||||
|
|
||||||
GlobalPosition = target.GlobalPosition + Math3D.YawPitchRotation( smoothedYaw, smoothedPitch ) * Vector3.Forward * distance + offset;
|
GlobalPosition = targetPosition + Math3D.YawPitchRotation( smoothedYaw, smoothedPitch ) * Vector3.Forward * distance;
|
||||||
|
|
||||||
LookAt( target.GlobalPosition + offset, Vector3.Up, true );
|
LookAt( targetPosition, Vector3.Up, true );
|
||||||
|
|
||||||
|
GlobalPosition += this.GetOrientationBasedGlobalOffset( offset );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class ThirdPersonCameraTargetOffset:CameraTargetOffset
|
||||||
|
{
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public ThirdPersonCamera thirdPersonCamera;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Curve pitchMultiply;
|
||||||
|
|
||||||
|
|
||||||
|
public override void SetMovingForward( float movingForward )
|
||||||
|
{
|
||||||
|
if ( pitchMultiply != null && thirdPersonCamera != null )
|
||||||
|
{
|
||||||
|
var normalizedPitch = thirdPersonCamera.normalizedPitch;
|
||||||
|
var sampledPitchMultiply = pitchMultiply.Sample( normalizedPitch );
|
||||||
|
movingForward *= sampledPitchMultiply;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nextZ = Mathf.Lerp( cameraTargetMinOffsetZ, cameraTargetMaxOffsetZ, movingForward );
|
||||||
|
nextY = Mathf.Lerp( cameraTargetMinOffsetY, cameraTargetMaxOffsetY, movingForward );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://s7mi8hpmma3e
|
|
@ -21,6 +21,7 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public bool active = false;
|
public bool active = false;
|
||||||
|
|
||||||
|
|
||||||
public static VirtualCamera3DManager Get()
|
public static VirtualCamera3DManager Get()
|
||||||
{
|
{
|
||||||
return Unique<VirtualCamera3DManager>.Get();
|
return Unique<VirtualCamera3DManager>.Get();
|
||||||
|
|
Loading…
Reference in New Issue