You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1645 lines
65 KiB
C#

2 weeks ago
2 weeks ago
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;
}
}
}