using System ;
using System.Collections.Generic ;
using Unity.Profiling ;
using UnityEngine ;
namespace Fusion.Addons.SimpleKCC
{
[DisallowMultipleComponent]
[RequireComponent(typeof(Rigidbody))]
public sealed class KCCOffline : MonoBehaviour
{
internal const int CACHE_SIZE = 64 ;
internal const int HISTORY_SIZE = 60 ;
[SerializeField]
private KCCSettings _settings = new ( ) ;
private Transform _transform ;
private Rigidbody _rigidbody ;
private bool _isSpawned ;
private KCCCollider _collider = new ( ) ;
private KCCData _fixedData = new ( ) ;
private KCCData [ ] _historyData = new KCCData [ 60 ] ;
private KCCSettings _defaultSettings = new ( ) ;
private KCCOverlapInfo _extendedOverlapInfo = new ( 64 ) ;
private KCCOverlapInfo _trackOverlapInfo = new ( 64 ) ;
private List < Collider > _childColliders = new List < Collider > ( ) ;
private RaycastHit [ ] _raycastHits = new RaycastHit [ 64 ] ;
private Collider [ ] _hitColliders = new Collider [ 64 ] ;
private Collider [ ] _addColliders = new Collider [ 64 ] ;
private Collider [ ] _removeColliders = new Collider [ 64 ] ;
private KCCResolver _resolver = new ( 64 ) ;
private Vector3 _lastAntiJitterPosition ;
private Vector3 _predictionError ;
private static ProfilerMarker _fixedUpdateMarker = new ProfilerMarker ( "KCC.FixedUpdate" ) ;
public Func < KCCOffline , Collider , bool > ResolveCollision ;
internal bool IsSpawned = > _isSpawned ;
public bool IsGrounded = > Data . IsGrounded ;
public Vector3 RealVelocity = > Data . RealVelocity ;
public Vector3 Position = > Data . TargetPosition ;
public Quaternion LookRotation = > Data . LookRotation ;
public Vector3 LookDirection = > Data . LookDirection ;
public Quaternion TransformRotation = > Data . TransformRotation ;
public Vector3 TransformDirection = > Data . TransformDirection ;
public float RealSpeed = > Data . RealSpeed ;
public bool HasJumped = > Data . HasJumped ;
public bool IsActive = > Data . IsActive ;
internal KCCData Data = > _fixedData ;
internal KCCData FixedData = > _fixedData ;
public KCCSettings Settings = > _settings ;
public Transform Transform = > _transform ;
public CapsuleCollider Collider = > _collider . Collider ;
public Rigidbody Rigidbody = > _rigidbody ;
internal bool IsInFixedUpdate = > true ;
internal Vector3 PredictionError = > _predictionError ;
private event Action < KCCOffline > _onSpawn ;
internal void SynchronizeTransform ( bool synchronizePosition , bool synchronizeRotation , bool allowAntiJitter = true )
{
if ( IsInFixedUpdate )
{
allowAntiJitter = false ;
}
SynchronizeTransform ( Data , synchronizePosition , synchronizeRotation , allowAntiJitter ) ;
}
public void RefreshChildColliders ( )
{
_childColliders . Clear ( ) ;
GetComponentsInChildren ( includeInactive : true , _childColliders ) ;
int num = 0 ;
int num2 = _childColliders . Count - 1 ;
while ( num < = num2 )
{
Collider collider = _childColliders [ num ] ;
if ( collider . isTrigger | | collider = = _collider . Collider )
{
_childColliders [ num ] = _childColliders [ num2 ] ;
_childColliders . RemoveAt ( num2 ) ;
num2 - - ;
}
else
{
num + + ;
}
}
}
internal KCCData GetHistoryData ( int tick )
{
if ( tick < 0 )
{
return null ;
}
KCCData kCCData = _historyData [ tick % 60 ] ;
if ( kCCData ! = null & & kCCData . Tick = = tick )
{
return kCCData ;
}
return null ;
}
internal void InvokeOnSpawn ( Action < KCCOffline > callback )
{
if ( _isSpawned )
{
callback ( this ) ;
return ;
}
_onSpawn - = callback ;
_onSpawn + = callback ;
}
internal void ManualFixedUpdate ( )
{
if ( _isSpawned )
{
_fixedUpdateMarker . Begin ( ) ;
OnFixedUpdateInternal ( ) ;
_fixedUpdateMarker . End ( ) ;
}
}
private void Awake ( )
{
_transform = base . transform ;
_rigidbody = GetComponent < Rigidbody > ( ) ;
_rigidbody . isKinematic = true ;
RefreshCollider ( ) ;
Spawned ( ) ;
}
private void OnDestroy ( )
{
SetDefaults ( cleanup : true ) ;
}
private void OnDrawGizmosSelected ( )
{
if ( _settings ! = null )
{
float num = Mathf . Max ( 0.01f , _settings . Radius ) ;
float num2 = Mathf . Max ( num * 2f , _settings . Height ) ;
Vector3 position = base . transform . position ;
Color color = Gizmos . color ;
Vector3 vector = position + Vector3 . up * num ;
Vector3 vector2 = position + Vector3 . up * ( num2 - num ) ;
Vector3 vector3 = Vector3 . forward * num ;
Vector3 vector4 = Vector3 . back * num ;
Vector3 vector5 = Vector3 . left * num ;
Vector3 vector6 = Vector3 . right * num ;
Gizmos . color = Color . green ;
Gizmos . DrawWireSphere ( vector , num ) ;
Gizmos . DrawWireSphere ( vector2 , num ) ;
Gizmos . DrawLine ( vector + vector3 , vector2 + vector3 ) ;
Gizmos . DrawLine ( vector + vector4 , vector2 + vector4 ) ;
Gizmos . DrawLine ( vector + vector5 , vector2 + vector5 ) ;
Gizmos . DrawLine ( vector + vector6 , vector2 + vector6 ) ;
if ( _settings . Extent > 0f )
{
float radius = num + _settings . Extent ;
Gizmos . color = Color . yellow ;
Gizmos . DrawWireSphere ( vector , radius ) ;
Gizmos . DrawWireSphere ( vector2 , radius ) ;
}
Gizmos . color = color ;
}
}
public void Spawned ( )
{
if ( _isSpawned )
{
throw new InvalidOperationException ( "[" + base . name + "] KCC is already spawned!" ) ;
}
_defaultSettings . CopyFromOther ( _settings ) ;
SetDefaults ( cleanup : false ) ;
_isSpawned = true ;
// _isInFixedUpdate = true;
KCCUtility . GetClampedLookRotationAngles ( _transform . rotation , out var pitch , out var yaw ) ;
_fixedData = new ( ) ;
_fixedData . Frame = Time . frameCount ;
// _fixedData.Tick = base.Runner.Tick.Raw;
// _fixedData.Time = base.Runner.SimulationTime;
_fixedData . DeltaTime = Time . deltaTime ;
_fixedData . UpdateDeltaTime = _fixedData . DeltaTime ;
_fixedData . Gravity = Physics . gravity ;
_fixedData . MaxGroundAngle = 60f ;
_fixedData . MaxWallAngle = 5f ;
_fixedData . MaxHangAngle = 30f ;
_fixedData . BasePosition = _transform . position ;
_fixedData . DesiredPosition = _transform . position ;
_fixedData . TargetPosition = _transform . position ;
_fixedData . LookPitch = pitch ;
_fixedData . LookYaw = yaw ;
// if (!base.Object.HasStateAuthority)
// {
// ReadNetworkData();
SynchronizeTransform ( _fixedData , synchronizePosition : true , synchronizeRotation : true , allowAntiJitter : false ) ;
// }
// _renderData = new();
// _renderData.CopyFromOther(_fixedData);
// _lastRenderPosition = _renderData.TargetPosition;
// _lastAntiJitterPosition = _renderData.TargetPosition;
RefreshCollider ( ) ;
RefreshChildColliders ( ) ;
if ( this . _onSpawn ! = null )
{
try
{
this . _onSpawn ( this ) ;
}
catch ( Exception exception )
{
Debug . LogException ( exception ) ;
}
this . _onSpawn = null ;
}
}
private void OnFixedUpdateInternal ( )
{
if ( ! IsInFixedUpdate )
{
throw new InvalidOperationException ( "[" + base . name + "] KCC fixed update called from render update! This is not allowed." ) ;
}
RefreshCollider ( ) ;
MovePredicted ( _fixedData ) ;
if ( _fixedData . IsActive )
{
SynchronizeTransform ( _fixedData , synchronizePosition : true , synchronizeRotation : true , allowAntiJitter : false ) ;
}
}
private void MovePredicted ( KCCData data )
{
float time = data . Time ;
float deltaTime = data . DeltaTime ;
Vector3 targetPosition = data . TargetPosition ;
Vector3 targetPosition2 = data . TargetPosition ;
bool isGrounded = data . IsGrounded ;
bool isSteppingUp = data . IsSteppingUp ;
bool isSnappingToGround = data . IsSnappingToGround ;
data . DeltaTime = deltaTime ;
data . BasePosition = targetPosition ;
data . DesiredPosition = targetPosition2 ;
if ( ! data . IsActive )
{
data . ClearTransientProperties ( ) ;
ForceRemoveAllHits ( data ) ;
return ;
}
SetBaseProperties ( data ) ;
if ( ! data . IsActive )
{
data . ClearTransientProperties ( ) ;
ForceRemoveAllHits ( data ) ;
return ;
}
deltaTime = data . DeltaTime ;
targetPosition = data . BasePosition ;
if ( deltaTime < KCCSettings . ExtrapolationDeltaTimeThreshold )
{
Vector3 vector = data . DesiredVelocity ;
if ( data . RealVelocity . sqrMagnitude < = vector . sqrMagnitude )
{
vector = data . RealVelocity ;
}
targetPosition2 = targetPosition + vector * deltaTime ;
data . BasePosition = targetPosition ;
data . DesiredPosition = targetPosition2 ;
data . TargetPosition = targetPosition2 ;
return ;
}
EnvironmentProcessor . SetDynamicVelocity ( this , data ) ;
ForceRemoveAllHits ( data ) ;
float num = Mathf . Clamp01 ( deltaTime ) ;
Vector3 vector2 = data . DesiredVelocity * num + data . ExternalDelta ;
targetPosition2 = ( data . DesiredPosition = data . BasePosition + vector2 ) ;
data . TargetPosition = data . BasePosition ;
data . ExternalDelta = default ( Vector3 ) ;
bool flag = false ;
float num2 = Mathf . Clamp ( _settings . CCDRadiusMultiplier , 0.25f , 0.75f ) ;
float num3 = _settings . Radius * ( num2 + 0.1f ) ;
float num4 = _settings . Radius * num2 ;
Vector3 targetPosition3 = data . TargetPosition ;
while ( ! flag & & ! data . HasTeleported )
{
data . BasePosition = data . TargetPosition ;
float num5 = num ;
Vector3 vector3 = vector2 ;
float magnitude = vector3 . magnitude ;
if ( magnitude > num3 )
{
float num6 = num4 / magnitude ;
num5 * = num6 ;
vector3 * = num6 ;
}
else
{
flag = true ;
}
num - = num5 ;
vector2 - = vector3 ;
if ( num < = 0f )
{
num = 0f ;
}
data . Time = time - num ;
data . DeltaTime = num5 ;
data . DesiredPosition = data . BasePosition + vector3 ;
data . TargetPosition = data . DesiredPosition ;
data . WasGrounded = data . IsGrounded ;
data . WasSteppingUp = data . IsSteppingUp ;
data . WasSnappingToGround = data . IsSnappingToGround ;
ProcessMoveStep ( data ) ;
if ( ! data . HasTeleported )
{
targetPosition3 = data . TargetPosition ;
}
if ( data . HasTeleported )
{
UpdateHits ( data , null , EKCCHitsOverlapQuery . New ) ;
}
if ( flag & & ! data . ExternalDelta . IsZero ( ) )
{
vector2 + = data . ExternalDelta ;
data . ExternalDelta = default ( Vector3 ) ;
flag = false ;
}
}
data . Time = time ;
data . DeltaTime = deltaTime ;
data . BasePosition = targetPosition ;
data . DesiredPosition = targetPosition2 ;
data . WasGrounded = isGrounded ;
data . WasSteppingUp = isSteppingUp ;
data . WasSnappingToGround = isSnappingToGround ;
data . RealVelocity = ( targetPosition3 - data . BasePosition ) / data . DeltaTime ;
data . RealSpeed = data . RealVelocity . magnitude ;
Vector3 targetPosition4 = data . TargetPosition ;
if ( ! data . TargetPosition . IsEqual ( targetPosition4 ) )
{
UpdateHits ( data , null , EKCCHitsOverlapQuery . New ) ;
}
targetPosition4 = data . TargetPosition ;
if ( ! data . TargetPosition . IsEqual ( targetPosition4 ) )
{
UpdateHits ( data , null , EKCCHitsOverlapQuery . New ) ;
}
}
private void SetBaseProperties ( KCCData data )
{
data . HasTeleported = false ;
data . MaxPenetrationSteps = _settings . MaxPenetrationSteps ;
if ( data . Frame = = _fixedData . Frame )
{
data . JumpFrames = 0 ;
}
}
private void ProcessMoveStep ( KCCData data )
{
data . IsGrounded = false ;
data . IsSteppingUp = false ;
data . IsSnappingToGround = false ;
data . GroundNormal = default ( Vector3 ) ;
data . GroundTangent = default ( Vector3 ) ;
data . GroundPosition = default ( Vector3 ) ;
data . GroundDistance = 0f ;
data . GroundAngle = 0f ;
ForceRemoveAllHits ( data ) ;
bool flag = data . JumpFrames > 0 ;
if ( ( int ) _settings . CollisionLayerMask ! = 0 & & _collider . IsSpawned )
{
float radius = _settings . Radius ;
EKCCHitsOverlapQuery overlapQuery = EKCCHitsOverlapQuery . Default ;
CapsuleOverlap ( _extendedOverlapInfo , data , data . TargetPosition , _settings . Radius , _settings . Height , radius , _settings . CollisionLayerMask , QueryTriggerInteraction . Collide ) ;
data . TargetPosition = ResolvePenetration ( _extendedOverlapInfo , data , data . BasePosition , data . TargetPosition , ! flag , data . MaxPenetrationSteps , 3 , resolveTriggers : true ) ;
UpdateHits ( data , _extendedOverlapInfo , overlapQuery ) ;
}
if ( flag )
{
data . IsGrounded = false ;
}
EnvironmentProcessor . AfterMoveStep ( this , data ) ;
StepUpProcessor . AfterMoveStep ( this , data , _extendedOverlapInfo ) ;
GroundSnapProcessor . AfterMoveStep ( this , data , _extendedOverlapInfo ) ;
}
private void SynchronizeTransform ( KCCData data , bool synchronizePosition , bool synchronizeRotation , bool allowAntiJitter )
{
if ( synchronizePosition )
{
Vector3 vector = data . TargetPosition ;
_rigidbody . position = vector ;
if ( allowAntiJitter & & ! _settings . AntiJitterDistance . IsZero ( ) )
{
Vector3 vector2 = vector - _lastAntiJitterPosition ;
if ( vector2 . sqrMagnitude < _settings . TeleportThreshold * _settings . TeleportThreshold )
{
vector = _lastAntiJitterPosition ;
float num = Mathf . Abs ( vector2 . y ) ;
if ( num > 1E-06f )
{
vector . y + = vector2 . y * Mathf . Clamp01 ( ( num - _settings . AntiJitterDistance . y ) / num ) ;
}
Vector3 vector3 = vector2 . OnlyXZ ( ) ;
float num2 = Vector3 . Magnitude ( vector3 ) ;
if ( num2 > 1E-06f )
{
vector + = vector3 * Mathf . Clamp01 ( ( num2 - _settings . AntiJitterDistance . x ) / num2 ) ;
}
}
_lastAntiJitterPosition = vector ;
}
if ( synchronizeRotation )
{
_transform . SetPositionAndRotation ( vector , data . TransformRotation ) ;
}
else
{
_transform . position = vector ;
}
}
else if ( synchronizeRotation )
{
_transform . rotation = data . TransformRotation ;
}
}
private void RefreshCollider ( )
{
if ( _settings . Shape = = EKCCShape . None )
{
_collider . Destroy ( ) ;
return ;
}
_settings . Radius = Mathf . Max ( 0.01f , _settings . Radius ) ;
_settings . Height = Mathf . Max ( _settings . Radius * 2f , _settings . Height ) ;
_settings . Extent = Mathf . Max ( 0f , _settings . Extent ) ;
_collider . Update ( this ) ;
}
private void SetDefaults ( bool cleanup )
{
_fixedData . Clear ( ) ;
// _renderData.Clear();
Array . Clear ( _historyData , 0 , _historyData . Length ) ;
_extendedOverlapInfo . Reset ( deep : true ) ;
_trackOverlapInfo . Reset ( deep : true ) ;
_childColliders . Clear ( ) ;
Array . Clear ( _raycastHits , 0 , _raycastHits . Length ) ;
Array . Clear ( _hitColliders , 0 , _hitColliders . Length ) ;
Array . Clear ( _addColliders , 0 , _addColliders . Length ) ;
Array . Clear ( _removeColliders , 0 , _removeColliders . Length ) ;
// _raycastHits.Clear();
// _hitColliders.Clear();
// _addColliders.Clear();
// _removeColliders.Clear();
_rigidbody . isKinematic = true ;
// _lastRenderTime = 0f;
// _lastRenderPosition = default(Vector3);
_lastAntiJitterPosition = default ( Vector3 ) ;
_predictionError = default ( Vector3 ) ;
if ( cleanup )
{
_isSpawned = false ;
// _isInFixedUpdate = false;
_settings . CopyFromOther ( _defaultSettings ) ;
_collider . Destroy ( ) ;
this . _onSpawn = null ;
ResolveCollision = null ;
}
}
internal Vector3 ResolvePenetration ( KCCOverlapInfo overlapInfo , KCCData data , Vector3 basePosition , Vector3 targetPosition , bool probeGrounding , int maxSteps , int resolverIterations , bool resolveTriggers )
{
if ( _settings . SuppressConvexMeshColliders )
{
overlapInfo . ToggleConvexMeshColliders ( convex : false ) ;
}
if ( overlapInfo . ColliderHitCount = = 1 )
{
targetPosition = DepenetrateSingle ( overlapInfo , data , basePosition , targetPosition , probeGrounding , maxSteps ) ;
}
else if ( overlapInfo . ColliderHitCount > 1 )
{
targetPosition = DepenetrateMultiple ( overlapInfo , data , basePosition , targetPosition , probeGrounding , maxSteps , resolverIterations ) ;
}
RecalculateGroundProperties ( data ) ;
if ( resolveTriggers )
{
for ( int i = 0 ; i < overlapInfo . TriggerHitCount ; i + + )
{
KCCOverlapHit kCCOverlapHit = overlapInfo . TriggerHits [ i ] ;
kCCOverlapHit . Transform . GetPositionAndRotation ( out kCCOverlapHit . CachedPosition , out kCCOverlapHit . CachedRotation ) ;
kCCOverlapHit . CollisionType = ( ( kCCOverlapHit . IsWithinExtent = ( kCCOverlapHit . HasPenetration = Physics . ComputePenetration ( _collider . Collider , data . TargetPosition , Quaternion . identity , kCCOverlapHit . Collider , kCCOverlapHit . CachedPosition , kCCOverlapHit . CachedRotation , out var _ , out var distance ) ) ) ? ECollisionType . Trigger : ECollisionType . None ) ;
if ( distance > kCCOverlapHit . MaxPenetration )
{
kCCOverlapHit . MaxPenetration = distance ;
}
}
}
if ( _settings . SuppressConvexMeshColliders )
{
overlapInfo . ToggleConvexMeshColliders ( convex : true ) ;
}
return targetPosition ;
}
private Vector3 DepenetrateSingle ( KCCOverlapInfo overlapInfo , KCCData data , Vector3 basePosition , Vector3 targetPosition , bool probeGrounding , int maxSteps )
{
float num = Mathf . Cos ( Mathf . Clamp ( data . MaxGroundAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
float num2 = 0f - Mathf . Cos ( Mathf . Clamp ( 90f - data . MaxWallAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
float num3 = 0f - Mathf . Cos ( Mathf . Clamp ( 90f - data . MaxHangAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
Vector3 vector = Vector3 . up ;
float num4 = 0f ;
KCCOverlapHit kCCOverlapHit = overlapInfo . ColliderHits [ 0 ] ;
kCCOverlapHit . UpDirectionDot = float . MinValue ;
kCCOverlapHit . Transform . GetPositionAndRotation ( out kCCOverlapHit . CachedPosition , out kCCOverlapHit . CachedRotation ) ;
if ( maxSteps > 1 )
{
float num5 = 0.001f ;
float num6 = Vector3 . Distance ( basePosition , targetPosition ) ;
if ( num6 < ( float ) maxSteps * num5 )
{
maxSteps = Mathf . Max ( 1 , ( int ) ( num6 / num5 ) ) ;
}
}
if ( maxSteps < = 1 )
{
kCCOverlapHit . HasPenetration = Physics . ComputePenetration ( _collider . Collider , targetPosition , Quaternion . identity , kCCOverlapHit . Collider , kCCOverlapHit . CachedPosition , kCCOverlapHit . CachedRotation , out var direction , out var distance ) ;
if ( kCCOverlapHit . HasPenetration )
{
kCCOverlapHit . IsWithinExtent = true ;
if ( distance > kCCOverlapHit . MaxPenetration )
{
kCCOverlapHit . MaxPenetration = distance ;
}
float num7 = Vector3 . Dot ( direction , Vector3 . up ) ;
if ( num7 > kCCOverlapHit . UpDirectionDot )
{
kCCOverlapHit . UpDirectionDot = num7 ;
if ( num7 > = num )
{
kCCOverlapHit . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
vector = direction ;
}
else if ( num7 > 0f - num2 )
{
kCCOverlapHit . CollisionType = ECollisionType . Slope ;
}
else if ( num7 > = num2 )
{
kCCOverlapHit . CollisionType = ECollisionType . Wall ;
}
else if ( num7 > = num3 )
{
kCCOverlapHit . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit . CollisionType = ECollisionType . Top ;
}
}
if ( num7 > 0f & & num7 < num & & distance > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( ( targetPosition - basePosition ) . OnlyXZ ( ) , direction . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction , ref distance ) ;
}
targetPosition + = direction * distance ;
}
}
else
{
Vector3 vector2 = ( targetPosition - basePosition ) / maxSteps ;
Vector3 vector3 = basePosition ;
int num8 = maxSteps ;
while ( num8 > 0 )
{
num8 - - ;
vector3 + = vector2 ;
kCCOverlapHit . HasPenetration = Physics . ComputePenetration ( _collider . Collider , vector3 , Quaternion . identity , kCCOverlapHit . Collider , kCCOverlapHit . CachedPosition , kCCOverlapHit . CachedRotation , out var direction2 , out var distance2 ) ;
if ( ! kCCOverlapHit . HasPenetration )
{
continue ;
}
kCCOverlapHit . IsWithinExtent = true ;
if ( distance2 > kCCOverlapHit . MaxPenetration )
{
kCCOverlapHit . MaxPenetration = distance2 ;
}
float num9 = Vector3 . Dot ( direction2 , Vector3 . up ) ;
if ( num9 > kCCOverlapHit . UpDirectionDot )
{
kCCOverlapHit . UpDirectionDot = num9 ;
if ( num9 > = num )
{
kCCOverlapHit . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
vector = direction2 ;
}
else if ( num9 > 0f - num2 )
{
kCCOverlapHit . CollisionType = ECollisionType . Slope ;
}
else if ( num9 > = num2 )
{
kCCOverlapHit . CollisionType = ECollisionType . Wall ;
}
else if ( num9 > = num3 )
{
kCCOverlapHit . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit . CollisionType = ECollisionType . Top ;
}
}
if ( num9 > 0f & & num9 < num & & distance2 > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( vector2 . OnlyXZ ( ) , direction2 . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction2 , ref distance2 ) ;
}
vector3 + = direction2 * distance2 ;
}
targetPosition = vector3 ;
}
if ( kCCOverlapHit . UpDirectionDot = = float . MinValue )
{
kCCOverlapHit . UpDirectionDot = 0f ;
}
if ( probeGrounding & & ! data . IsGrounded )
{
if ( KCCPhysicsUtility . CheckGround ( _collider . Collider , targetPosition , kCCOverlapHit . Collider , kCCOverlapHit . CachedPosition , kCCOverlapHit . CachedRotation , _settings . Radius , _settings . Height , _settings . Extent , num , out var groundNormal , out var groundDistance , out var isWithinExtent ) )
{
data . IsGrounded = true ;
vector = groundNormal ;
num4 = groundDistance ;
kCCOverlapHit . IsWithinExtent = true ;
kCCOverlapHit . CollisionType = ECollisionType . Ground ;
}
else if ( isWithinExtent )
{
kCCOverlapHit . IsWithinExtent = true ;
if ( kCCOverlapHit . CollisionType = = ECollisionType . None )
{
kCCOverlapHit . CollisionType = ECollisionType . Slope ;
}
}
}
if ( data . IsGrounded )
{
data . GroundNormal = vector ;
data . GroundAngle = Vector3 . Angle ( vector , Vector3 . up ) ;
data . GroundPosition = targetPosition + new Vector3 ( 0f , _settings . Radius , 0f ) - vector * ( _settings . Radius + num4 ) ;
data . GroundDistance = num4 ;
}
return targetPosition ;
}
private Vector3 DepenetrateMultiple ( KCCOverlapInfo overlapInfo , KCCData data , Vector3 basePosition , Vector3 targetPosition , bool probeGrounding , int maxSteps , int resolverIterations )
{
float num = Mathf . Cos ( Mathf . Clamp ( data . MaxGroundAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
float num2 = 0f - Mathf . Cos ( Mathf . Clamp ( 90f - data . MaxWallAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
float num3 = 0f - Mathf . Cos ( Mathf . Clamp ( 90f - data . MaxHangAngle , 0f , 90f ) * ( MathF . PI / 180f ) ) ;
float num4 = 0f ;
float num5 = 0f ;
Vector3 other = default ( Vector3 ) ;
Vector3 vector = default ( Vector3 ) ;
Vector3 lhs = ( targetPosition - basePosition ) . OnlyXZ ( ) ;
for ( int i = 0 ; i < overlapInfo . ColliderHitCount ; i + + )
{
KCCOverlapHit kCCOverlapHit = overlapInfo . ColliderHits [ i ] ;
kCCOverlapHit . UpDirectionDot = float . MinValue ;
kCCOverlapHit . Transform . GetPositionAndRotation ( out kCCOverlapHit . CachedPosition , out kCCOverlapHit . CachedRotation ) ;
}
if ( maxSteps > 1 )
{
float num6 = 0.001f ;
float num7 = Vector3 . Distance ( basePosition , targetPosition ) ;
if ( num7 < ( float ) maxSteps * num6 )
{
maxSteps = Mathf . Max ( 1 , ( int ) ( num7 / num6 ) ) ;
}
}
if ( maxSteps < = 1 )
{
_resolver . Reset ( ) ;
for ( int j = 0 ; j < overlapInfo . ColliderHitCount ; j + + )
{
KCCOverlapHit kCCOverlapHit2 = overlapInfo . ColliderHits [ j ] ;
kCCOverlapHit2 . HasPenetration = Physics . ComputePenetration ( _collider . Collider , targetPosition , Quaternion . identity , kCCOverlapHit2 . Collider , kCCOverlapHit2 . CachedPosition , kCCOverlapHit2 . CachedRotation , out var direction , out var distance ) ;
if ( ! kCCOverlapHit2 . HasPenetration )
{
continue ;
}
kCCOverlapHit2 . IsWithinExtent = true ;
if ( distance > kCCOverlapHit2 . MaxPenetration )
{
kCCOverlapHit2 . MaxPenetration = distance ;
}
float num8 = Vector3 . Dot ( direction , Vector3 . up ) ;
if ( num8 > kCCOverlapHit2 . UpDirectionDot )
{
kCCOverlapHit2 . UpDirectionDot = num8 ;
if ( num8 > = num )
{
kCCOverlapHit2 . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
if ( num8 > = num5 )
{
num5 = num8 ;
other = direction ;
}
vector + = direction * num8 ;
}
else if ( num8 > 0f - num2 )
{
kCCOverlapHit2 . CollisionType = ECollisionType . Slope ;
}
else if ( num8 > = num2 )
{
kCCOverlapHit2 . CollisionType = ECollisionType . Wall ;
}
else if ( num8 > = num3 )
{
kCCOverlapHit2 . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit2 . CollisionType = ECollisionType . Top ;
}
}
if ( num8 > 0f & & num8 < num & & distance > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( lhs , direction . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction , ref distance ) ;
}
_resolver . AddCorrection ( direction , distance ) ;
}
int num9 = Mathf . Max ( 0 , resolverIterations ) ;
float num10 = 1f - ( float ) Mathf . Min ( num9 , 2 ) * 0.25f ;
if ( _resolver . Size = = 2 )
{
_resolver . GetCorrection ( 0 , out var direction2 ) ;
_resolver . GetCorrection ( 1 , out var direction3 ) ;
if ( Vector3 . Dot ( direction2 , direction3 ) > = 0f )
{
targetPosition + = _resolver . CalculateMinMax ( ) * num10 ;
}
else
{
targetPosition + = _resolver . CalculateBinary ( ) * num10 ;
}
}
else
{
targetPosition + = _resolver . CalculateGradientDescent ( 12 , 0.0001f ) * num10 ;
}
while ( num9 > 0 )
{
num9 - - ;
_resolver . Reset ( ) ;
for ( int k = 0 ; k < overlapInfo . ColliderHitCount ; k + + )
{
KCCOverlapHit kCCOverlapHit3 = overlapInfo . ColliderHits [ k ] ;
if ( ! Physics . ComputePenetration ( _collider . Collider , targetPosition , Quaternion . identity , kCCOverlapHit3 . Collider , kCCOverlapHit3 . CachedPosition , kCCOverlapHit3 . CachedRotation , out var direction4 , out var distance2 ) )
{
continue ;
}
kCCOverlapHit3 . IsWithinExtent = true ;
kCCOverlapHit3 . HasPenetration = true ;
if ( distance2 > kCCOverlapHit3 . MaxPenetration )
{
kCCOverlapHit3 . MaxPenetration = distance2 ;
}
float num11 = Vector3 . Dot ( direction4 , Vector3 . up ) ;
if ( num11 > kCCOverlapHit3 . UpDirectionDot )
{
kCCOverlapHit3 . UpDirectionDot = num11 ;
if ( num11 > = num )
{
kCCOverlapHit3 . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
if ( num11 > = num5 )
{
num5 = num11 ;
other = direction4 ;
}
vector + = direction4 * num11 ;
}
else if ( num11 > 0f - num2 )
{
kCCOverlapHit3 . CollisionType = ECollisionType . Slope ;
}
else if ( num11 > = num2 )
{
kCCOverlapHit3 . CollisionType = ECollisionType . Wall ;
}
else if ( num11 > = num3 )
{
kCCOverlapHit3 . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit3 . CollisionType = ECollisionType . Top ;
}
}
if ( num11 > 0f & & num11 < num & & distance2 > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( lhs , direction4 . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction4 , ref distance2 ) ;
}
_resolver . AddCorrection ( direction4 , distance2 ) ;
}
if ( _resolver . Size = = 0 )
{
break ;
}
switch ( num9 )
{
case 0 :
if ( _resolver . Size = = 2 )
{
_resolver . GetCorrection ( 0 , out var direction5 ) ;
_resolver . GetCorrection ( 1 , out var direction6 ) ;
if ( Vector3 . Dot ( direction5 , direction6 ) > = 0f )
{
targetPosition + = _resolver . CalculateGradientDescent ( 12 , 0.0001f ) ;
}
else
{
targetPosition + = _resolver . CalculateBinary ( ) ;
}
}
else
{
targetPosition + = _resolver . CalculateGradientDescent ( 12 , 0.0001f ) ;
}
break ;
case 1 :
targetPosition + = _resolver . CalculateMinMax ( ) * 0.75f ;
break ;
default :
targetPosition + = _resolver . CalculateMinMax ( ) * 0.5f ;
break ;
}
}
}
else
{
Vector3 vector2 = ( targetPosition - basePosition ) / maxSteps ;
Vector3 vector3 = basePosition ;
int num12 = maxSteps ;
while ( num12 > 1 )
{
num12 - - ;
vector3 + = vector2 ;
_resolver . Reset ( ) ;
for ( int l = 0 ; l < overlapInfo . ColliderHitCount ; l + + )
{
KCCOverlapHit kCCOverlapHit4 = overlapInfo . ColliderHits [ l ] ;
kCCOverlapHit4 . HasPenetration = Physics . ComputePenetration ( _collider . Collider , vector3 , Quaternion . identity , kCCOverlapHit4 . Collider , kCCOverlapHit4 . CachedPosition , kCCOverlapHit4 . CachedRotation , out var direction7 , out var distance3 ) ;
if ( ! kCCOverlapHit4 . HasPenetration )
{
continue ;
}
kCCOverlapHit4 . IsWithinExtent = true ;
if ( distance3 > kCCOverlapHit4 . MaxPenetration )
{
kCCOverlapHit4 . MaxPenetration = distance3 ;
}
float num13 = Vector3 . Dot ( direction7 , Vector3 . up ) ;
if ( num13 > kCCOverlapHit4 . UpDirectionDot )
{
kCCOverlapHit4 . UpDirectionDot = num13 ;
if ( num13 > = num )
{
kCCOverlapHit4 . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
if ( num13 > = num5 )
{
num5 = num13 ;
other = direction7 ;
}
vector + = direction7 * num13 ;
}
else if ( num13 > 0f - num2 )
{
kCCOverlapHit4 . CollisionType = ECollisionType . Slope ;
}
else if ( num13 > = num2 )
{
kCCOverlapHit4 . CollisionType = ECollisionType . Wall ;
}
else if ( num13 > = num3 )
{
kCCOverlapHit4 . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit4 . CollisionType = ECollisionType . Top ;
}
}
if ( num13 > 0f & & num13 < num & & distance3 > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( vector2 . OnlyXZ ( ) , direction7 . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction7 , ref distance3 ) ;
}
_resolver . AddCorrection ( direction7 , distance3 ) ;
}
if ( _resolver . Size = = 2 )
{
_resolver . GetCorrection ( 0 , out var direction8 ) ;
_resolver . GetCorrection ( 1 , out var direction9 ) ;
if ( Vector3 . Dot ( direction8 , direction9 ) > = 0f )
{
vector3 + = _resolver . CalculateMinMax ( ) ;
}
else
{
vector3 + = _resolver . CalculateBinary ( ) ;
}
}
else
{
vector3 + = _resolver . CalculateMinMax ( ) ;
}
}
num12 - - ;
vector3 + = vector2 ;
_resolver . Reset ( ) ;
for ( int m = 0 ; m < overlapInfo . ColliderHitCount ; m + + )
{
KCCOverlapHit kCCOverlapHit5 = overlapInfo . ColliderHits [ m ] ;
kCCOverlapHit5 . HasPenetration = Physics . ComputePenetration ( _collider . Collider , vector3 , Quaternion . identity , kCCOverlapHit5 . Collider , kCCOverlapHit5 . CachedPosition , kCCOverlapHit5 . CachedRotation , out var direction10 , out var distance4 ) ;
if ( ! kCCOverlapHit5 . HasPenetration )
{
continue ;
}
kCCOverlapHit5 . IsWithinExtent = true ;
if ( distance4 > kCCOverlapHit5 . MaxPenetration )
{
kCCOverlapHit5 . MaxPenetration = distance4 ;
}
float num14 = Vector3 . Dot ( direction10 , Vector3 . up ) ;
if ( num14 > kCCOverlapHit5 . UpDirectionDot )
{
kCCOverlapHit5 . UpDirectionDot = num14 ;
if ( num14 > = num )
{
kCCOverlapHit5 . CollisionType = ECollisionType . Ground ;
data . IsGrounded = true ;
if ( num14 > = num5 )
{
num5 = num14 ;
other = direction10 ;
}
vector + = direction10 * num14 ;
}
else if ( num14 > 0f - num2 )
{
kCCOverlapHit5 . CollisionType = ECollisionType . Slope ;
}
else if ( num14 > = num2 )
{
kCCOverlapHit5 . CollisionType = ECollisionType . Wall ;
}
else if ( num14 > = num3 )
{
kCCOverlapHit5 . CollisionType = ECollisionType . Hang ;
}
else
{
kCCOverlapHit5 . CollisionType = ECollisionType . Top ;
}
}
if ( num14 > 0f & & num14 < num & & distance4 > = 1E-06f & & data . DynamicVelocity . y < = 0f & & Vector3 . Dot ( vector2 . OnlyXZ ( ) , direction10 . OnlyXZ ( ) ) < 0f )
{
KCCPhysicsUtility . ProjectVerticalPenetration ( ref direction10 , ref distance4 ) ;
}
_resolver . AddCorrection ( direction10 , distance4 ) ;
}
if ( _resolver . Size = = 2 )
{
_resolver . GetCorrection ( 0 , out var direction11 ) ;
_resolver . GetCorrection ( 1 , out var direction12 ) ;
if ( Vector3 . Dot ( direction11 , direction12 ) > = 0f )
{
vector3 + = _resolver . CalculateMinMax ( ) ;
}
else
{
vector3 + = _resolver . CalculateBinary ( ) ;
}
}
else
{
vector3 + = _resolver . CalculateGradientDescent ( 12 , 0.0001f ) ;
}
targetPosition = vector3 ;
}
for ( int n = 0 ; n < overlapInfo . ColliderHitCount ; n + + )
{
KCCOverlapHit kCCOverlapHit6 = overlapInfo . ColliderHits [ n ] ;
if ( kCCOverlapHit6 . UpDirectionDot = = float . MinValue )
{
kCCOverlapHit6 . UpDirectionDot = 0f ;
}
}
if ( probeGrounding & & ! data . IsGrounded )
{
Vector3 vector4 = Vector3 . up ;
float num15 = 1000f ;
for ( int num16 = 0 ; num16 < overlapInfo . ColliderHitCount ; num16 + + )
{
KCCOverlapHit kCCOverlapHit7 = overlapInfo . ColliderHits [ num16 ] ;
if ( KCCPhysicsUtility . CheckGround ( _collider . Collider , targetPosition , kCCOverlapHit7 . Collider , kCCOverlapHit7 . CachedPosition , kCCOverlapHit7 . CachedRotation , _settings . Radius , _settings . Height , _settings . Extent , num , out var groundNormal , out var groundDistance , out var isWithinExtent ) )
{
data . IsGrounded = true ;
if ( groundDistance < num15 )
{
vector4 = groundNormal ;
num15 = groundDistance ;
}
kCCOverlapHit7 . IsWithinExtent = true ;
kCCOverlapHit7 . CollisionType = ECollisionType . Ground ;
}
else if ( isWithinExtent )
{
kCCOverlapHit7 . IsWithinExtent = true ;
if ( kCCOverlapHit7 . CollisionType = = ECollisionType . None )
{
kCCOverlapHit7 . CollisionType = ECollisionType . Slope ;
}
}
}
if ( data . IsGrounded )
{
other = vector4 ;
vector = vector4 ;
num4 = num15 ;
}
}
if ( data . IsGrounded )
{
if ( ! vector . IsEqual ( other ) )
{
vector . Normalize ( ) ;
}
data . GroundNormal = vector ;
data . GroundAngle = Vector3 . Angle ( data . GroundNormal , Vector3 . up ) ;
data . GroundPosition = targetPosition + new Vector3 ( 0f , _settings . Radius , 0f ) - data . GroundNormal * ( _settings . Radius + num4 ) ;
data . GroundDistance = num4 ;
}
return targetPosition ;
}
private static void RecalculateGroundProperties ( KCCData data )
{
if ( data . IsGrounded )
{
Vector3 projectedVector2 ;
if ( KCCPhysicsUtility . ProjectOnGround ( data . GroundNormal , data . GroundNormal . OnlyXZ ( ) , out var projectedVector ) )
{
data . GroundTangent = projectedVector . normalized ;
}
else if ( KCCPhysicsUtility . ProjectOnGround ( data . GroundNormal , data . DesiredVelocity . OnlyXZ ( ) , out projectedVector2 ) )
{
data . GroundTangent = projectedVector2 . normalized ;
}
else
{
data . GroundTangent = data . TransformDirection ;
}
}
}
public void SetActive ( bool isActive ) = > _fixedData . IsActive = isActive ;
public Vector2 GetLookRotation ( bool pitch = true , bool yaw = true ) = > Data . GetLookRotation ( pitch , yaw ) ;
public void AddLookRotation ( float pitchDelta , float yawDelta )
{
KCCData kCCData = _fixedData ;
kCCData . AddLookRotation ( pitchDelta , yawDelta ) ;
SynchronizeTransform ( kCCData , synchronizePosition : false , synchronizeRotation : true , allowAntiJitter : false ) ;
}
public void AddLookRotation ( float pitchDelta , float yawDelta , float minPitch , float maxPitch )
{
KCCData kCCData = _fixedData ;
kCCData . AddLookRotation ( pitchDelta , yawDelta , minPitch , maxPitch ) ;
SynchronizeTransform ( kCCData , synchronizePosition : false , synchronizeRotation : true , allowAntiJitter : false ) ;
}
public void AddLookRotation ( Vector2 lookRotationDelta )
{
AddLookRotation ( lookRotationDelta . x , lookRotationDelta . y ) ;
}
public void AddLookRotation ( Vector2 lookRotationDelta , float minPitch , float maxPitch )
{
AddLookRotation ( lookRotationDelta . x , lookRotationDelta . y , minPitch , maxPitch ) ;
}
public void SetLookRotation ( float pitch , float yaw )
{
KCCData kCCData = _fixedData ;
kCCData . SetLookRotation ( pitch , yaw ) ;
SynchronizeTransform ( kCCData , synchronizePosition : false , synchronizeRotation : true , allowAntiJitter : false ) ;
}
public void SetLookRotation ( Vector2 lookRotation ) = > SetLookRotation ( lookRotation . x , lookRotation . y ) ;
public void SetLookRotation ( Quaternion lookRotation , bool preservePitch = false , bool preserveYaw = false )
{
KCCData kCCData = _fixedData ;
kCCData . SetLookRotation ( lookRotation , preservePitch , preserveYaw ) ;
SynchronizeTransform ( kCCData , synchronizePosition : false , synchronizeRotation : true , allowAntiJitter : false ) ;
}
public void SetPosition ( Vector3 position )
{
KCCData kCCData = _fixedData ;
kCCData . BasePosition = position ;
kCCData . DesiredPosition = position ;
kCCData . TargetPosition = position ;
kCCData . HasTeleported = true ;
kCCData . IsSteppingUp = false ;
kCCData . IsSnappingToGround = false ;
SynchronizeTransform ( kCCData , synchronizePosition : true , synchronizeRotation : false , allowAntiJitter : false ) ;
}
public void SetShape ( EKCCShape shape , float radius = 0f , float height = 0f )
{
_settings . Shape = shape ;
if ( radius > 0f )
{
_settings . Radius = radius ;
}
if ( height > 0f )
{
_settings . Height = height ;
}
RefreshCollider ( ) ;
}
public void SetTrigger ( bool isTrigger )
{
_settings . IsTrigger = isTrigger ;
RefreshCollider ( ) ;
}
public void SetRadius ( float radius )
{
if ( ! ( radius < = 0f ) )
{
_settings . Radius = radius ;
RefreshCollider ( ) ;
}
}
public void SetHeight ( float height )
{
if ( ! ( height < = 0f ) )
{
_settings . Height = height ;
RefreshCollider ( ) ;
}
}
public void SetColliderLayer ( int layer )
{
_settings . ColliderLayer = layer ;
RefreshCollider ( ) ;
}
public void SetCollisionLayerMask ( LayerMask layerMask )
{
_settings . CollisionLayerMask = layerMask ;
}
private void RestoreHistoryData ( KCCData historyData )
{
if ( _fixedData . IsGrounded )
{
_fixedData . IsGrounded = historyData . IsGrounded ;
_fixedData . WasGrounded = historyData . WasGrounded ;
}
}
internal bool SphereOverlap ( KCCOverlapInfo overlapInfo , Vector3 position , float radius , QueryTriggerInteraction triggerInteraction )
{
return SphereOverlap ( overlapInfo , Data , position , radius , 0f , _settings . CollisionLayerMask , triggerInteraction ) ;
}
internal bool CapsuleOverlap ( KCCOverlapInfo overlapInfo , Vector3 position , float radius , float height , QueryTriggerInteraction triggerInteraction )
{
return CapsuleOverlap ( overlapInfo , Data , position , radius , height , 0f , _settings . CollisionLayerMask , triggerInteraction ) ;
}
internal bool RayCast ( KCCShapeCastInfo shapeCastInfo , Vector3 position , Vector3 direction , float maxDistance , QueryTriggerInteraction triggerInteraction )
{
return RayCast ( shapeCastInfo , Data , position , direction , maxDistance , _settings . CollisionLayerMask , triggerInteraction ) ;
}
internal bool SphereCast ( KCCShapeCastInfo shapeCastInfo , Vector3 position , float radius , Vector3 direction , float maxDistance , QueryTriggerInteraction triggerInteraction , bool trackInitialOverlaps = true )
{
return SphereCast ( shapeCastInfo , Data , position , radius , 0f , direction , maxDistance , _settings . CollisionLayerMask , triggerInteraction , trackInitialOverlaps ) ;
}
internal bool CapsuleCast ( KCCShapeCastInfo shapeCastInfo , Vector3 position , float radius , float height , Vector3 direction , float maxDistance , QueryTriggerInteraction triggerInteraction , bool trackInitialOverlaps = true )
{
return CapsuleCast ( shapeCastInfo , Data , position , radius , height , 0f , direction , maxDistance , _settings . CollisionLayerMask , triggerInteraction , trackInitialOverlaps ) ;
}
internal void UpdateHits ( KCCOverlapInfo baseOverlapInfo , EKCCHitsOverlapQuery overlapQuery )
{
UpdateHits ( Data , baseOverlapInfo , overlapQuery ) ;
}
internal bool IsValidHitCollider ( Collider hitCollider )
{
if ( hitCollider = = null )
{
return false ;
}
return IsValidHitCollider ( Data , hitCollider ) ;
}
private bool SphereOverlap ( KCCOverlapInfo overlapInfo , KCCData data , Vector3 position , float radius , float extent , LayerMask layerMask , QueryTriggerInteraction triggerInteraction )
{
overlapInfo . Reset ( deep : false ) ;
overlapInfo . Position = position ;
overlapInfo . Radius = radius ;
overlapInfo . Height = 0f ;
overlapInfo . Extent = extent ;
overlapInfo . LayerMask = layerMask ;
overlapInfo . TriggerInteraction = triggerInteraction ;
// Collider[] hitColliders = _hitColliders;
Collider [ ] hitColliders = Physics . OverlapSphere ( position , radius + extent , layerMask , triggerInteraction ) ;
for ( int i = 0 ; i < hitColliders . Length ; i + + )
{
Collider overlapCollider = hitColliders [ i ] ;
if ( IsValidHitColliderUnsafe ( data , overlapCollider ) )
{
overlapInfo . AddHit ( overlapCollider ) ;
}
}
return overlapInfo . AllHitCount > 0 ;
}
private bool CapsuleOverlap ( KCCOverlapInfo overlapInfo , KCCData data , Vector3 position , float radius , float height , float extent , LayerMask layerMask , QueryTriggerInteraction triggerInteraction )
{
overlapInfo . Reset ( deep : false ) ;
overlapInfo . Position = position ;
overlapInfo . Radius = radius ;
overlapInfo . Height = height ;
overlapInfo . Extent = extent ;
overlapInfo . LayerMask = layerMask ;
overlapInfo . TriggerInteraction = triggerInteraction ;
Vector3 point = position + new Vector3 ( 0f , height - radius , 0f ) ;
Vector3 point2 = position + new Vector3 ( 0f , radius , 0f ) ;
// Collider[] hitColliders = _hitColliders;
Collider [ ] hitColliders = Physics . OverlapCapsule ( point2 , point , radius + extent , layerMask , triggerInteraction ) ;
for ( int i = 0 ; i < hitColliders . Length ; i + + )
{
Collider overlapCollider = hitColliders [ i ] ;
if ( IsValidHitColliderUnsafe ( data , overlapCollider ) )
{
overlapInfo . AddHit ( overlapCollider ) ;
}
}
return overlapInfo . AllHitCount > 0 ;
}
private bool RayCast ( KCCShapeCastInfo shapeCastInfo , KCCData data , Vector3 position , Vector3 direction , float maxDistance , LayerMask layerMask , QueryTriggerInteraction triggerInteraction )
{
shapeCastInfo . Reset ( deep : false ) ;
shapeCastInfo . Position = position ;
shapeCastInfo . Direction = direction ;
shapeCastInfo . MaxDistance = maxDistance ;
shapeCastInfo . LayerMask = layerMask ;
shapeCastInfo . TriggerInteraction = triggerInteraction ;
// RaycastHit[] raycastHits = _raycastHits;
// if(Physics.Raycast(position, direction, out RaycastHit hit, maxDistance, layerMask, triggerInteraction))
// // int num = base.Runner.GetPhysicsScene().Raycast(position, direction, raycastHits, maxDistance, layerMask, triggerInteraction);
// for (int i = 0; i < hit.; i++)
// {
// RaycastHit raycastHit = raycastHits[i];
// if (IsValidHitColliderUnsafe(data, raycastHit.collider))
// {
// shapeCastInfo.AddHit(raycastHit);
// }
// }
// return shapeCastInfo.AllHitCount > 0;
return Physics . Raycast ( position , direction , maxDistance , layerMask , triggerInteraction ) ;
}
private bool SphereCast ( KCCShapeCastInfo shapeCastInfo , KCCData data , Vector3 position , float radius , float extent , Vector3 direction , float maxDistance , LayerMask layerMask , QueryTriggerInteraction triggerInteraction , bool trackInitialOverlaps )
{
shapeCastInfo . Reset ( deep : false ) ;
shapeCastInfo . Position = position ;
shapeCastInfo . Radius = radius ;
shapeCastInfo . Extent = extent ;
shapeCastInfo . Direction = direction ;
shapeCastInfo . MaxDistance = maxDistance ;
shapeCastInfo . LayerMask = layerMask ;
shapeCastInfo . TriggerInteraction = triggerInteraction ;
RaycastHit [ ] raycastHits = _raycastHits ;
return Physics . SphereCast ( position , radius + extent , direction , out RaycastHit info , maxDistance , layerMask , triggerInteraction ) ;
// int num = base.Runner.GetPhysicsScene().SphereCast(position, radius + extent, direction, raycastHits, maxDistance, layerMask, triggerInteraction);
// for (int i = 0; i < num; i++)
// {
// RaycastHit raycastHit = raycastHits[i];
// if ((trackInitialOverlaps || !(raycastHit.distance <= 0f) || !raycastHit.point.Equals(default(Vector3))) && IsValidHitColliderUnsafe(data, raycastHit.collider))
// {
// shapeCastInfo.AddHit(raycastHit);
// }
// }
// return shapeCastInfo.AllHitCount > 0;
}
private bool CapsuleCast ( KCCShapeCastInfo shapeCastInfo , KCCData data , Vector3 position , float radius , float height , float extent , Vector3 direction , float maxDistance , LayerMask layerMask , QueryTriggerInteraction triggerInteraction , bool trackInitialOverlaps )
{
shapeCastInfo . Reset ( deep : false ) ;
shapeCastInfo . Position = position ;
shapeCastInfo . Radius = radius ;
shapeCastInfo . Height = height ;
shapeCastInfo . Extent = extent ;
shapeCastInfo . Position = position ;
shapeCastInfo . Direction = direction ;
shapeCastInfo . MaxDistance = maxDistance ;
shapeCastInfo . LayerMask = layerMask ;
shapeCastInfo . TriggerInteraction = triggerInteraction ;
Vector3 point = position + new Vector3 ( 0f , height - radius , 0f ) ;
Vector3 point2 = position + new Vector3 ( 0f , radius , 0f ) ;
// RaycastHit[] raycastHits = _raycastHits;
return Physics . CapsuleCast ( point2 , point , radius + extent , direction , out RaycastHit info , maxDistance , layerMask , triggerInteraction ) ;
// int num = base.Runner.GetPhysicsScene().CapsuleCast(point2, point, radius + extent, direction, raycastHits, maxDistance, layerMask, triggerInteraction);
// for (int i = 0; i < num; i++)
// {
// RaycastHit raycastHit = raycastHits[i];
// if ((trackInitialOverlaps || !(raycastHit.distance <= 0f) || !raycastHit.point.Equals(default(Vector3))) && IsValidHitColliderUnsafe(data, raycastHit.collider))
// {
// shapeCastInfo.AddHit(raycastHit);
// }
// }
// return shapeCastInfo.AllHitCount > 0;
}
private void UpdateHits ( KCCData data , KCCOverlapInfo baseOverlapInfo , EKCCHitsOverlapQuery overlapQuery )
{
if ( overlapQuery switch
{
EKCCHitsOverlapQuery . Default = > baseOverlapInfo ? . AllHitsWithinExtent ( ) ? ? false ,
EKCCHitsOverlapQuery . Reuse = > baseOverlapInfo ! = null ,
EKCCHitsOverlapQuery . New = > false ,
_ = > throw new NotImplementedException ( "overlapQuery" ) ,
} )
{
_trackOverlapInfo . CopyFromOther ( baseOverlapInfo ) ;
}
else
{
CapsuleOverlap ( _trackOverlapInfo , data , data . TargetPosition , _settings . Radius , _settings . Height , _settings . Extent , _settings . CollisionLayerMask , QueryTriggerInteraction . Collide ) ;
if ( baseOverlapInfo ! = null )
{
for ( int i = 0 ; i < _trackOverlapInfo . AllHitCount ; i + + )
{
KCCOverlapHit kCCOverlapHit = _trackOverlapInfo . AllHits [ i ] ;
for ( int j = 0 ; j < baseOverlapInfo . AllHitCount ; j + + )
{
KCCOverlapHit kCCOverlapHit2 = baseOverlapInfo . AllHits [ j ] ;
if ( ( object ) kCCOverlapHit . Collider = = kCCOverlapHit2 . Collider )
{
kCCOverlapHit . CopyFromOther ( kCCOverlapHit2 ) ;
}
}
}
}
}
data . Hits . Clear ( ) ;
int k = 0 ;
for ( int allHitCount = _trackOverlapInfo . AllHitCount ; k < allHitCount ; k + + )
{
data . Hits . Add ( _trackOverlapInfo . AllHits [ k ] ) ;
}
}
private void ForceRemoveAllHits ( KCCData data )
{
_trackOverlapInfo . Reset ( deep : false ) ;
_extendedOverlapInfo . Reset ( deep : false ) ;
data . Hits . Clear ( ) ;
}
private bool IsValidHitCollider ( KCCData data , Collider hitCollider )
{
if ( hitCollider = = _collider . Collider )
{
return false ;
}
int i = 0 ;
for ( int count = _childColliders . Count ; i < count ; i + + )
{
if ( hitCollider = = _childColliders [ i ] )
{
return false ;
}
}
int num = 1 < < hitCollider . gameObject . layer ;
if ( ( ( int ) _settings . CollisionLayerMask & num ) ! = num )
{
return false ;
}
if ( ResolveCollision ! = null )
{
try
{
return ResolveCollision ( this , hitCollider ) ;
}
catch ( Exception exception )
{
Debug . LogException ( exception ) ;
}
}
return true ;
}
private bool IsValidHitColliderUnsafe ( KCCData data , Collider overlapCollider )
{
if ( ( object ) overlapCollider = = _collider . Collider )
{
return false ;
}
int i = 0 ;
for ( int count = _childColliders . Count ; i < count ; i + + )
{
if ( ( object ) overlapCollider = = _childColliders [ i ] )
{
return false ;
}
}
if ( ResolveCollision ! = null )
{
try
{
return ResolveCollision ( this , overlapCollider ) ;
}
catch ( Exception exception )
{
Debug . LogException ( exception ) ;
}
}
return true ;
}
public void SetMaxGroundAngle ( float maxGroundAngle )
{
if ( IsSpawned )
{
Data . MaxGroundAngle = maxGroundAngle ;
}
}
public void SetGravity ( float gravity )
{
if ( IsSpawned )
{
Data . Gravity = Vector3 . up * gravity ;
}
}
public void Move ( Vector3 kinematicVelocity = default ( Vector3 ) , float jumpImpulse = 0f )
{
if ( IsSpawned )
{
if ( ! IsInFixedUpdate )
{
throw new InvalidOperationException ( "[" + base . name + "] Move can be invoked only from within fixed update!" ) ;
}
FixedData . KinematicVelocity = kinematicVelocity ;
FixedData . JumpImpulse + = Vector3 . up * jumpImpulse ;
ManualFixedUpdate ( ) ;
}
}
public bool ProjectOnGround ( Vector3 vector , out Vector3 projectedVector )
{
KCCData data = Data ;
if ( data . IsGrounded )
{
return KCCPhysicsUtility . ProjectOnGround ( data . GroundNormal , vector , out projectedVector ) ;
}
projectedVector = default ( Vector3 ) ;
return false ;
}
}
}