1.0.0-pre.15.1 update
This commit is contained in:
Родитель
2bf2a4d905
Коммит
ace434248f
|
@ -201,11 +201,11 @@ MonoBehaviour:
|
|||
Tag05: 0
|
||||
Tag06: 0
|
||||
Tag07: 0
|
||||
InterpolatePosition: 0
|
||||
InterpolatePosition: 1
|
||||
InterpolateRotation: 0
|
||||
EvaluateGrounding: 1
|
||||
SnapToGround: 1
|
||||
GroundSnappingDistance: 0.3
|
||||
GroundSnappingDistance: 0.5
|
||||
EnhancedGroundPrecision: 0
|
||||
MaxGroundedSlopeAngle: 60
|
||||
DetectMovementCollisions: 1
|
||||
|
@ -236,6 +236,7 @@ MonoBehaviour:
|
|||
StepHandling: 1
|
||||
MaxStepHeight: 0.5
|
||||
ExtraStepChecksDistance: 0.1
|
||||
CharacterWidthForStepGroundingCheck: 1
|
||||
PreventGroundingWhenMovingTowardsNoGrounding: 1
|
||||
HasMaxDownwardSlopeChangeAngle: 0
|
||||
MaxDownwardSlopeChangeAngle: 90
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Physics.Authoring;
|
|||
using Unity.Physics.Extensions;
|
||||
using Unity.Physics.Systems;
|
||||
using Unity.Transforms;
|
||||
using UnityEngine;
|
||||
using Material = Unity.Physics.Material;
|
||||
using RaycastHit = Unity.Physics.RaycastHit;
|
||||
|
||||
|
@ -333,18 +334,51 @@ namespace Rival
|
|||
[Serializable]
|
||||
public struct BasicStepAndSlopeHandlingParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not step handling logic is enabled
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Step Handling")]
|
||||
[UnityEngine.Tooltip("Whether or not step handling logic is enabled")]
|
||||
public bool StepHandling;
|
||||
/// <summary>
|
||||
/// Max height that the character can step on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max height that the character can step on")]
|
||||
public float MaxStepHeight;
|
||||
/// <summary>
|
||||
/// Horizontal offset distance of extra downwards raycasts used to detect grounding around a step
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Horizontal offset distance of extra downwards raycasts used to detect grounding around a step")]
|
||||
public float ExtraStepChecksDistance;
|
||||
/// <summary>
|
||||
/// Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.")]
|
||||
public float CharacterWidthForStepGroundingCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from "snapping" onto the ledge as it moves off of it
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Slope Changes")]
|
||||
[UnityEngine.Tooltip("Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from \"snapping\" onto the ledge as it moves off of it")]
|
||||
public bool PreventGroundingWhenMovingTowardsNoGrounding;
|
||||
/// <summary>
|
||||
/// Whether or not the character has a max slope change that it can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Whether or not the character has a max slope change that it can stay grounded on")]
|
||||
public bool HasMaxDownwardSlopeChangeAngle;
|
||||
/// <summary>
|
||||
/// Max slope change that the character can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max slope change that the character can stay grounded on")]
|
||||
[UnityEngine.Range(0f, 180f)]
|
||||
public float MaxDownwardSlopeChangeAngle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Misc")]
|
||||
[UnityEngine.Tooltip("Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope")]
|
||||
public bool ConstrainVelocityToGroundPlane;
|
||||
|
||||
public static BasicStepAndSlopeHandlingParameters GetDefault()
|
||||
|
@ -354,6 +388,7 @@ namespace Rival
|
|||
StepHandling = false,
|
||||
MaxStepHeight = 0.5f,
|
||||
ExtraStepChecksDistance = 0.1f,
|
||||
CharacterWidthForStepGroundingCheck = 1f,
|
||||
|
||||
PreventGroundingWhenMovingTowardsNoGrounding = true,
|
||||
HasMaxDownwardSlopeChangeAngle = false,
|
||||
|
@ -1448,7 +1483,6 @@ namespace Rival
|
|||
characterBody.IsGrounded,
|
||||
characterBody.RelativeVelocity,
|
||||
isGroundedOnMovementHit);
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(currentCharacterHit));
|
||||
|
||||
processor.OnMovementHit(
|
||||
ref context,
|
||||
|
@ -1918,6 +1952,7 @@ namespace Rival
|
|||
float maxStepHeight,
|
||||
float extraStepChecksDistance) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
|
||||
KinematicCharacterBody characterBody = CharacterBody.ValueRO;
|
||||
KinematicCharacterProperties characterProperties = CharacterProperties.ValueRO;
|
||||
|
||||
|
@ -2045,7 +2080,7 @@ namespace Rival
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the stepping-up-a-step logic during character movement iterations
|
||||
/// </summary>
|
||||
|
@ -2060,6 +2095,7 @@ namespace Rival
|
|||
/// <param name="hitDistance"></param>
|
||||
/// <param name="stepHandling"></param>
|
||||
/// <param name="maxStepHeight"></param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <param name="hasSteppedUp"></param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
|
@ -2075,6 +2111,7 @@ namespace Rival
|
|||
float hitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck,
|
||||
out bool hasSteppedUp) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
hasSteppedUp = false;
|
||||
|
@ -2086,7 +2123,8 @@ namespace Rival
|
|||
if (characterProperties.EvaluateGrounding &&
|
||||
stepHandling &&
|
||||
!hit.IsGroundedOnHit &&
|
||||
maxStepHeight > 0f)
|
||||
maxStepHeight > 0f &&
|
||||
!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
float3 startPositionOfUpCheck = characterPosition;
|
||||
float3 upCheckDirection = characterBody.GroundingUp;
|
||||
|
@ -2119,7 +2157,7 @@ namespace Rival
|
|||
{
|
||||
float3 startPositionOfForwardCheck = startPositionOfUpCheck + (upCheckDirection * upStepHitDistance);
|
||||
float distanceOverStep = math.length(math.projectsafe(remainingMovementDirection * (remainingMovementLength - hitDistance), hit.Normal));
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * remainingMovementLength);
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * (remainingMovementLength + Constants.CollisionOffset));
|
||||
float minimumDistanceOverStep = Constants.CollisionOffset * 3f;
|
||||
if (distanceOverStep < minimumDistanceOverStep)
|
||||
{
|
||||
|
@ -2185,22 +2223,53 @@ namespace Rival
|
|||
}
|
||||
|
||||
if (isGroundedOnStepHit)
|
||||
{
|
||||
float steppedHeight = upStepHitDistance - downStepHitDistance;
|
||||
|
||||
if (steppedHeight > Constants.CollisionOffset)
|
||||
{
|
||||
float hitHeight = upStepHitDistance - downStepHitDistance;
|
||||
float steppedHeight = hitHeight;
|
||||
steppedHeight = math.max(0f, steppedHeight + Constants.CollisionOffset);
|
||||
|
||||
// Add slope & character width consideration to stepped height
|
||||
if(characterWidthForStepGroundingCheck > 0f)
|
||||
{
|
||||
// Find the effective slope normal
|
||||
float3 forwardSlopeCheckDirection = -math.normalizesafe(math.cross(math.cross(characterBody.GroundingUp, stepHit.Normal), stepHit.Normal));
|
||||
|
||||
if (RaycastClosestCollisions(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
stepHit.Position + (characterBody.GroundingUp * Constants.CollisionOffset) + (forwardSlopeCheckDirection * Constants.CollisionOffset),
|
||||
-characterBody.GroundingUp,
|
||||
maxStepHeight,
|
||||
characterProperties.ShouldIgnoreDynamicBodies(),
|
||||
out RaycastHit forwardSlopeCheckHit,
|
||||
out float forwardSlopeCheckHitDistance))
|
||||
{
|
||||
float3 effectiveSlopeNormal = forwardSlopeCheckHit.SurfaceNormal;
|
||||
float slopeRadians = MathUtilities.AngleRadians(characterBody.GroundingUp, effectiveSlopeNormal);
|
||||
float extraHeightFromAngleAndCharacterWidth = math.tan(slopeRadians) * characterWidthForStepGroundingCheck * 0.5f;
|
||||
steppedHeight += extraHeightFromAngleAndCharacterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (steppedHeight < maxStepHeight)
|
||||
{
|
||||
// Step up
|
||||
characterPosition += characterBody.GroundingUp * steppedHeight;
|
||||
characterPosition += characterBody.GroundingUp * hitHeight;
|
||||
characterPosition += forwardCheckDirection * forwardStepHitDistance;
|
||||
|
||||
characterBody.IsGrounded = true;
|
||||
characterBody.GroundHit = stepHit;
|
||||
|
||||
// Project vel
|
||||
float3 characterVelocityBeforeHit = characterBody.RelativeVelocity;
|
||||
characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, characterBody.GroundingUp);
|
||||
remainingMovementDirection = math.normalizesafe(characterBody.RelativeVelocity);
|
||||
remainingMovementLength -= forwardStepHitDistance;
|
||||
|
||||
// Replace hit with step hit
|
||||
hit = KinematicCharacterUtilities.CreateCharacterHit(stepHit, characterBody.IsGrounded, characterVelocityBeforeHit, isGroundedOnStepHit);
|
||||
hit.CharacterVelocityAfterHit = characterBody.RelativeVelocity;
|
||||
|
||||
hasSteppedUp = true;
|
||||
}
|
||||
|
@ -2542,19 +2611,23 @@ namespace Rival
|
|||
if (!isGroundedOnSlope && stepAndSlopeHandling.StepHandling && stepAndSlopeHandling.MaxStepHeight > 0f)
|
||||
{
|
||||
bool hitIsOnCharacterBottom = math.dot(characterBody.GroundingUp, hit.Normal) > Constants.DotProductSimilarityEpsilon;
|
||||
if (hitIsOnCharacterBottom ||
|
||||
(groundingEvaluationType != (int)GroundingEvaluationType.MovementHit && groundingEvaluationType != (int)GroundingEvaluationType.InitialOverlaps))
|
||||
if (hitIsOnCharacterBottom &&
|
||||
(groundingEvaluationType == (int)GroundingEvaluationType.GroundProbing || groundingEvaluationType == (int)GroundingEvaluationType.StepUpHit))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
// Prevent step grounding detection on dynamic bodies, to prevent cases of character stepping onto sphere rolling towards it
|
||||
if (!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return isGroundedOnSlope || isGroundedOnSteps;
|
||||
}
|
||||
|
||||
|
@ -2666,7 +2739,7 @@ namespace Rival
|
|||
ProjectVelocityOnSingleHit(ref velocity, ref characterIsGrounded, ref characterGroundHit, in firstHit, characterBody.GroundingUp);
|
||||
velocityDirection = math.normalizesafe(velocity);
|
||||
|
||||
// Original velocity direction will act as a plane constaint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
// Original velocity direction will act as a plane constraint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
KinematicVelocityProjectionHit originalVelocityHit = default;
|
||||
originalVelocityHit.Normal = characterIsGrounded ? math.normalizesafe(MathUtilities.ProjectOnPlane(originalVelocityDirection, characterBody.GroundingUp)) : originalVelocityDirection;
|
||||
|
||||
|
@ -2760,6 +2833,7 @@ namespace Rival
|
|||
/// <param name="movementHitDistance"> Distance of the hit </param>
|
||||
/// <param name="stepHandling"> Whether step-handling is enabled or not </param>
|
||||
/// <param name="maxStepHeight"> Maximum height of steps that can be stepped on </param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
public void Default_OnMovementHit<T, C>(
|
||||
|
@ -2774,7 +2848,8 @@ namespace Rival
|
|||
float3 originalVelocityDirection,
|
||||
float movementHitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck = 0f) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
bool hasSteppedUp = false;
|
||||
|
||||
|
@ -2794,8 +2869,12 @@ namespace Rival
|
|||
movementHitDistance,
|
||||
stepHandling,
|
||||
maxStepHeight,
|
||||
characterWidthForStepGroundingCheck,
|
||||
out hasSteppedUp);
|
||||
}
|
||||
|
||||
// Add velocityProjection hits only after potential correction from step handling
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(hit));
|
||||
|
||||
if (!hasSteppedUp)
|
||||
{
|
||||
|
@ -2814,7 +2893,7 @@ namespace Rival
|
|||
ref characterBody.GroundHit,
|
||||
in VelocityProjectionHits,
|
||||
originalVelocityDirection);
|
||||
|
||||
|
||||
// Recalculate remaining movement after projection
|
||||
float projectedVelocityLengthFactor = math.length(characterBody.RelativeVelocity) / math.length(velocityBeforeProjection);
|
||||
remainingMovementLength *= projectedVelocityLengthFactor;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Rival
|
|||
// Grounding
|
||||
EvaluateGrounding = true,
|
||||
SnapToGround = true,
|
||||
GroundSnappingDistance = 0.3f,
|
||||
GroundSnappingDistance = 0.5f,
|
||||
EnhancedGroundPrecision = false,
|
||||
MaxGroundedSlopeAngle = 60f,
|
||||
|
||||
|
|
|
@ -270,22 +270,25 @@ namespace Rival
|
|||
float3 relativeVelocityAToB = pointVelocityB - pointVelocityA;
|
||||
float relativeVelocityOnNormal = math.dot(relativeVelocityAToB, collisionNormalBToA);
|
||||
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
if (invEffectiveMass > 0f)
|
||||
if (relativeVelocityOnNormal > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
if (invEffectiveMass > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -1,5 +1,5 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e157296f77a4d34488f1881ea5841589
|
||||
guid: 2ce285599b88d544892bbcced8e8f6ff
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
|
Двоичные данные
Basic/Assets/SceneDependencyCache/0bf34e36e06c4b3f4c6b92a995b2e8e8.sceneWithBuildSettings
Normal file
Двоичные данные
Basic/Assets/SceneDependencyCache/0bf34e36e06c4b3f4c6b92a995b2e8e8.sceneWithBuildSettings
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0bf34e36e06c4b3f4c6b92a995b2e8e8
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -221,7 +221,8 @@ public readonly partial struct BasicCharacterAspect : IAspect, IKinematicCharact
|
|||
originalVelocityDirection,
|
||||
hitDistance,
|
||||
characterComponent.StepAndSlopeHandling.StepHandling,
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight);
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight,
|
||||
characterComponent.StepAndSlopeHandling.CharacterWidthForStepGroundingCheck);
|
||||
}
|
||||
|
||||
public void OverrideDynamicHitMasses(
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3b39867e89a9a6545ba64408193c1916
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -3,7 +3,7 @@
|
|||
--- !u!129 &1
|
||||
PlayerSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 24
|
||||
serializedVersion: 25
|
||||
productGUID: 23030eb1e4488734a94a1e4570b334b0
|
||||
AndroidProfiler: 0
|
||||
AndroidFilterTouchesWhenObscured: 0
|
||||
|
@ -135,7 +135,6 @@ PlayerSettings:
|
|||
bundleVersion: 0.1
|
||||
preloadedAssets:
|
||||
- {fileID: 0}
|
||||
- {fileID: 11400000, guid: 7f47cca94c9d75843932abe26966e773, type: 2}
|
||||
metroInputSource: 0
|
||||
wsaTransparentSwapchain: 0
|
||||
m_HolographicPauseOnTrackingLoss: 1
|
||||
|
@ -288,6 +287,7 @@ PlayerSettings:
|
|||
- m_BuildTarget: WebGL
|
||||
m_StaticBatching: 0
|
||||
m_DynamicBatching: 0
|
||||
m_BuildTargetShaderSettings: []
|
||||
m_BuildTargetGraphicsJobs:
|
||||
- m_BuildTarget: MacStandaloneSupport
|
||||
m_GraphicsJobs: 0
|
||||
|
@ -337,6 +337,8 @@ PlayerSettings:
|
|||
m_APIs: 0200000015000000
|
||||
m_Automatic: 0
|
||||
m_BuildTargetVRSettings: []
|
||||
m_DefaultShaderChunkSizeInMB: 16
|
||||
m_DefaultShaderChunkCount: 0
|
||||
openGLRequireES31: 0
|
||||
openGLRequireES31AEP: 0
|
||||
openGLRequireES32: 0
|
||||
|
@ -634,6 +636,7 @@ PlayerSettings:
|
|||
webGLMemoryLinearGrowthStep: 16
|
||||
webGLMemoryGeometricGrowthStep: 0.2
|
||||
webGLMemoryGeometricGrowthCap: 96
|
||||
webGLPowerPreference: 2
|
||||
scriptingDefineSymbols:
|
||||
Standalone: DOTS_ADD_PARTIAL_KEYWORD
|
||||
additionalCompilerArguments: {}
|
||||
|
@ -649,7 +652,7 @@ PlayerSettings:
|
|||
suppressCommonWarnings: 1
|
||||
allowUnsafeCode: 1
|
||||
useDeterministicCompilation: 1
|
||||
enableRoslynAnalyzers: 1
|
||||
selectedPlatform: 0
|
||||
additionalIl2CppArgs:
|
||||
scriptingRuntimeVersion: 1
|
||||
gcIncremental: 1
|
||||
|
@ -726,8 +729,13 @@ PlayerSettings:
|
|||
luminVersion:
|
||||
m_VersionCode: 1
|
||||
m_VersionName:
|
||||
hmiPlayerDataPath:
|
||||
hmiForceSRGBBlit: 1
|
||||
embeddedLinuxEnableGamepadInput: 1
|
||||
hmiCpuConfiguration:
|
||||
apiCompatibilityLevel: 6
|
||||
activeInputHandler: 2
|
||||
windowsGamepadBackendHint: 0
|
||||
cloudProjectId:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
qualitySettingsNames: []
|
||||
|
@ -735,10 +743,6 @@ PlayerSettings:
|
|||
organizationId:
|
||||
cloudEnabled: 0
|
||||
legacyClampBlendShapeWeights: 0
|
||||
playerDataPath:
|
||||
forceSRGBBlit: 1
|
||||
enableGamepadInput: 1
|
||||
cpuConfiguration:
|
||||
hmiLoadingImage: {fileID: 0}
|
||||
virtualTexturingSupportEnabled: 0
|
||||
insecureHttpOption: 0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2022.2.0f1
|
||||
m_EditorVersionWithRevision: 2022.2.0f1 (35dcd44975df)
|
||||
m_EditorVersion: 2022.2.1f1
|
||||
m_EditorVersionWithRevision: 2022.2.1f1 (4fead5835099)
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Physics.Authoring;
|
|||
using Unity.Physics.Extensions;
|
||||
using Unity.Physics.Systems;
|
||||
using Unity.Transforms;
|
||||
using UnityEngine;
|
||||
using Material = Unity.Physics.Material;
|
||||
using RaycastHit = Unity.Physics.RaycastHit;
|
||||
|
||||
|
@ -333,18 +334,51 @@ namespace Rival
|
|||
[Serializable]
|
||||
public struct BasicStepAndSlopeHandlingParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not step handling logic is enabled
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Step Handling")]
|
||||
[UnityEngine.Tooltip("Whether or not step handling logic is enabled")]
|
||||
public bool StepHandling;
|
||||
/// <summary>
|
||||
/// Max height that the character can step on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max height that the character can step on")]
|
||||
public float MaxStepHeight;
|
||||
/// <summary>
|
||||
/// Horizontal offset distance of extra downwards raycasts used to detect grounding around a step
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Horizontal offset distance of extra downwards raycasts used to detect grounding around a step")]
|
||||
public float ExtraStepChecksDistance;
|
||||
/// <summary>
|
||||
/// Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.")]
|
||||
public float CharacterWidthForStepGroundingCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from "snapping" onto the ledge as it moves off of it
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Slope Changes")]
|
||||
[UnityEngine.Tooltip("Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from \"snapping\" onto the ledge as it moves off of it")]
|
||||
public bool PreventGroundingWhenMovingTowardsNoGrounding;
|
||||
/// <summary>
|
||||
/// Whether or not the character has a max slope change that it can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Whether or not the character has a max slope change that it can stay grounded on")]
|
||||
public bool HasMaxDownwardSlopeChangeAngle;
|
||||
/// <summary>
|
||||
/// Max slope change that the character can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max slope change that the character can stay grounded on")]
|
||||
[UnityEngine.Range(0f, 180f)]
|
||||
public float MaxDownwardSlopeChangeAngle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Misc")]
|
||||
[UnityEngine.Tooltip("Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope")]
|
||||
public bool ConstrainVelocityToGroundPlane;
|
||||
|
||||
public static BasicStepAndSlopeHandlingParameters GetDefault()
|
||||
|
@ -354,6 +388,7 @@ namespace Rival
|
|||
StepHandling = false,
|
||||
MaxStepHeight = 0.5f,
|
||||
ExtraStepChecksDistance = 0.1f,
|
||||
CharacterWidthForStepGroundingCheck = 1f,
|
||||
|
||||
PreventGroundingWhenMovingTowardsNoGrounding = true,
|
||||
HasMaxDownwardSlopeChangeAngle = false,
|
||||
|
@ -1448,7 +1483,6 @@ namespace Rival
|
|||
characterBody.IsGrounded,
|
||||
characterBody.RelativeVelocity,
|
||||
isGroundedOnMovementHit);
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(currentCharacterHit));
|
||||
|
||||
processor.OnMovementHit(
|
||||
ref context,
|
||||
|
@ -1918,6 +1952,7 @@ namespace Rival
|
|||
float maxStepHeight,
|
||||
float extraStepChecksDistance) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
|
||||
KinematicCharacterBody characterBody = CharacterBody.ValueRO;
|
||||
KinematicCharacterProperties characterProperties = CharacterProperties.ValueRO;
|
||||
|
||||
|
@ -2045,7 +2080,7 @@ namespace Rival
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the stepping-up-a-step logic during character movement iterations
|
||||
/// </summary>
|
||||
|
@ -2060,6 +2095,7 @@ namespace Rival
|
|||
/// <param name="hitDistance"></param>
|
||||
/// <param name="stepHandling"></param>
|
||||
/// <param name="maxStepHeight"></param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <param name="hasSteppedUp"></param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
|
@ -2075,6 +2111,7 @@ namespace Rival
|
|||
float hitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck,
|
||||
out bool hasSteppedUp) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
hasSteppedUp = false;
|
||||
|
@ -2086,7 +2123,8 @@ namespace Rival
|
|||
if (characterProperties.EvaluateGrounding &&
|
||||
stepHandling &&
|
||||
!hit.IsGroundedOnHit &&
|
||||
maxStepHeight > 0f)
|
||||
maxStepHeight > 0f &&
|
||||
!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
float3 startPositionOfUpCheck = characterPosition;
|
||||
float3 upCheckDirection = characterBody.GroundingUp;
|
||||
|
@ -2119,7 +2157,7 @@ namespace Rival
|
|||
{
|
||||
float3 startPositionOfForwardCheck = startPositionOfUpCheck + (upCheckDirection * upStepHitDistance);
|
||||
float distanceOverStep = math.length(math.projectsafe(remainingMovementDirection * (remainingMovementLength - hitDistance), hit.Normal));
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * remainingMovementLength);
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * (remainingMovementLength + Constants.CollisionOffset));
|
||||
float minimumDistanceOverStep = Constants.CollisionOffset * 3f;
|
||||
if (distanceOverStep < minimumDistanceOverStep)
|
||||
{
|
||||
|
@ -2185,22 +2223,53 @@ namespace Rival
|
|||
}
|
||||
|
||||
if (isGroundedOnStepHit)
|
||||
{
|
||||
float steppedHeight = upStepHitDistance - downStepHitDistance;
|
||||
|
||||
if (steppedHeight > Constants.CollisionOffset)
|
||||
{
|
||||
float hitHeight = upStepHitDistance - downStepHitDistance;
|
||||
float steppedHeight = hitHeight;
|
||||
steppedHeight = math.max(0f, steppedHeight + Constants.CollisionOffset);
|
||||
|
||||
// Add slope & character width consideration to stepped height
|
||||
if(characterWidthForStepGroundingCheck > 0f)
|
||||
{
|
||||
// Find the effective slope normal
|
||||
float3 forwardSlopeCheckDirection = -math.normalizesafe(math.cross(math.cross(characterBody.GroundingUp, stepHit.Normal), stepHit.Normal));
|
||||
|
||||
if (RaycastClosestCollisions(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
stepHit.Position + (characterBody.GroundingUp * Constants.CollisionOffset) + (forwardSlopeCheckDirection * Constants.CollisionOffset),
|
||||
-characterBody.GroundingUp,
|
||||
maxStepHeight,
|
||||
characterProperties.ShouldIgnoreDynamicBodies(),
|
||||
out RaycastHit forwardSlopeCheckHit,
|
||||
out float forwardSlopeCheckHitDistance))
|
||||
{
|
||||
float3 effectiveSlopeNormal = forwardSlopeCheckHit.SurfaceNormal;
|
||||
float slopeRadians = MathUtilities.AngleRadians(characterBody.GroundingUp, effectiveSlopeNormal);
|
||||
float extraHeightFromAngleAndCharacterWidth = math.tan(slopeRadians) * characterWidthForStepGroundingCheck * 0.5f;
|
||||
steppedHeight += extraHeightFromAngleAndCharacterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (steppedHeight < maxStepHeight)
|
||||
{
|
||||
// Step up
|
||||
characterPosition += characterBody.GroundingUp * steppedHeight;
|
||||
characterPosition += characterBody.GroundingUp * hitHeight;
|
||||
characterPosition += forwardCheckDirection * forwardStepHitDistance;
|
||||
|
||||
characterBody.IsGrounded = true;
|
||||
characterBody.GroundHit = stepHit;
|
||||
|
||||
// Project vel
|
||||
float3 characterVelocityBeforeHit = characterBody.RelativeVelocity;
|
||||
characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, characterBody.GroundingUp);
|
||||
remainingMovementDirection = math.normalizesafe(characterBody.RelativeVelocity);
|
||||
remainingMovementLength -= forwardStepHitDistance;
|
||||
|
||||
// Replace hit with step hit
|
||||
hit = KinematicCharacterUtilities.CreateCharacterHit(stepHit, characterBody.IsGrounded, characterVelocityBeforeHit, isGroundedOnStepHit);
|
||||
hit.CharacterVelocityAfterHit = characterBody.RelativeVelocity;
|
||||
|
||||
hasSteppedUp = true;
|
||||
}
|
||||
|
@ -2542,19 +2611,23 @@ namespace Rival
|
|||
if (!isGroundedOnSlope && stepAndSlopeHandling.StepHandling && stepAndSlopeHandling.MaxStepHeight > 0f)
|
||||
{
|
||||
bool hitIsOnCharacterBottom = math.dot(characterBody.GroundingUp, hit.Normal) > Constants.DotProductSimilarityEpsilon;
|
||||
if (hitIsOnCharacterBottom ||
|
||||
(groundingEvaluationType != (int)GroundingEvaluationType.MovementHit && groundingEvaluationType != (int)GroundingEvaluationType.InitialOverlaps))
|
||||
if (hitIsOnCharacterBottom &&
|
||||
(groundingEvaluationType == (int)GroundingEvaluationType.GroundProbing || groundingEvaluationType == (int)GroundingEvaluationType.StepUpHit))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
// Prevent step grounding detection on dynamic bodies, to prevent cases of character stepping onto sphere rolling towards it
|
||||
if (!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return isGroundedOnSlope || isGroundedOnSteps;
|
||||
}
|
||||
|
||||
|
@ -2666,7 +2739,7 @@ namespace Rival
|
|||
ProjectVelocityOnSingleHit(ref velocity, ref characterIsGrounded, ref characterGroundHit, in firstHit, characterBody.GroundingUp);
|
||||
velocityDirection = math.normalizesafe(velocity);
|
||||
|
||||
// Original velocity direction will act as a plane constaint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
// Original velocity direction will act as a plane constraint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
KinematicVelocityProjectionHit originalVelocityHit = default;
|
||||
originalVelocityHit.Normal = characterIsGrounded ? math.normalizesafe(MathUtilities.ProjectOnPlane(originalVelocityDirection, characterBody.GroundingUp)) : originalVelocityDirection;
|
||||
|
||||
|
@ -2760,6 +2833,7 @@ namespace Rival
|
|||
/// <param name="movementHitDistance"> Distance of the hit </param>
|
||||
/// <param name="stepHandling"> Whether step-handling is enabled or not </param>
|
||||
/// <param name="maxStepHeight"> Maximum height of steps that can be stepped on </param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
public void Default_OnMovementHit<T, C>(
|
||||
|
@ -2774,7 +2848,8 @@ namespace Rival
|
|||
float3 originalVelocityDirection,
|
||||
float movementHitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck = 0f) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
bool hasSteppedUp = false;
|
||||
|
||||
|
@ -2794,8 +2869,12 @@ namespace Rival
|
|||
movementHitDistance,
|
||||
stepHandling,
|
||||
maxStepHeight,
|
||||
characterWidthForStepGroundingCheck,
|
||||
out hasSteppedUp);
|
||||
}
|
||||
|
||||
// Add velocityProjection hits only after potential correction from step handling
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(hit));
|
||||
|
||||
if (!hasSteppedUp)
|
||||
{
|
||||
|
@ -2814,7 +2893,7 @@ namespace Rival
|
|||
ref characterBody.GroundHit,
|
||||
in VelocityProjectionHits,
|
||||
originalVelocityDirection);
|
||||
|
||||
|
||||
// Recalculate remaining movement after projection
|
||||
float projectedVelocityLengthFactor = math.length(characterBody.RelativeVelocity) / math.length(velocityBeforeProjection);
|
||||
remainingMovementLength *= projectedVelocityLengthFactor;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Rival
|
|||
// Grounding
|
||||
EvaluateGrounding = true,
|
||||
SnapToGround = true,
|
||||
GroundSnappingDistance = 0.3f,
|
||||
GroundSnappingDistance = 0.5f,
|
||||
EnhancedGroundPrecision = false,
|
||||
MaxGroundedSlopeAngle = 60f,
|
||||
|
||||
|
|
|
@ -270,22 +270,25 @@ namespace Rival
|
|||
float3 relativeVelocityAToB = pointVelocityB - pointVelocityA;
|
||||
float relativeVelocityOnNormal = math.dot(relativeVelocityAToB, collisionNormalBToA);
|
||||
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
if (invEffectiveMass > 0f)
|
||||
if (relativeVelocityOnNormal > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
if (invEffectiveMass > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -222,7 +222,8 @@ public readonly partial struct FirstPersonCharacterAspect : IAspect, IKinematicC
|
|||
originalVelocityDirection,
|
||||
hitDistance,
|
||||
characterComponent.StepAndSlopeHandling.StepHandling,
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight);
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight,
|
||||
characterComponent.StepAndSlopeHandling.CharacterWidthForStepGroundingCheck);
|
||||
}
|
||||
|
||||
public void OverrideDynamicHitMasses(
|
||||
|
|
|
@ -192,7 +192,7 @@ public partial struct ServerGameSystem : ISystem
|
|||
// Accept join request
|
||||
Entity joinRequestAcceptedEntity = state.EntityManager.CreateEntity();
|
||||
ecb.AddComponent(joinRequestAcceptedEntity, new JoinRequestAccepted());
|
||||
ecb.AddComponent(joinRequestAcceptedEntity, new SendRpcCommandRequestComponent());
|
||||
ecb.AddComponent(joinRequestAcceptedEntity, new SendRpcCommandRequestComponent{ TargetConnection = rpcReceive.SourceConnection });
|
||||
|
||||
// Stream in game
|
||||
ecb.AddComponent(rpcReceive.SourceConnection, new NetworkStreamInGame());
|
||||
|
|
|
@ -15,15 +15,20 @@ public partial struct PredictedFixedStepTransformsUpdateSystem : ISystem
|
|||
private SystemHandle _transformsGroupHandle;
|
||||
|
||||
public void OnCreate(ref SystemState state)
|
||||
{
|
||||
_transformsGroupHandle = state.World.GetExistingSystem<TransformSystemGroup>();
|
||||
}
|
||||
{ }
|
||||
|
||||
public void OnDestroy(ref SystemState state)
|
||||
{ }
|
||||
|
||||
public void OnUpdate(ref SystemState state)
|
||||
{
|
||||
_transformsGroupHandle.Update(state.WorldUnmanaged);
|
||||
if (_transformsGroupHandle == SystemHandle.Null)
|
||||
{
|
||||
_transformsGroupHandle = state.World.GetExistingSystem<TransformSystemGroup>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_transformsGroupHandle.Update(state.WorldUnmanaged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2022.2.0f1
|
||||
m_EditorVersionWithRevision: 2022.2.0f1 (35dcd44975df)
|
||||
m_EditorVersion: 2022.2.1f1
|
||||
m_EditorVersionWithRevision: 2022.2.1f1 (4fead5835099)
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Physics.Authoring;
|
|||
using Unity.Physics.Extensions;
|
||||
using Unity.Physics.Systems;
|
||||
using Unity.Transforms;
|
||||
using UnityEngine;
|
||||
using Material = Unity.Physics.Material;
|
||||
using RaycastHit = Unity.Physics.RaycastHit;
|
||||
|
||||
|
@ -333,18 +334,51 @@ namespace Rival
|
|||
[Serializable]
|
||||
public struct BasicStepAndSlopeHandlingParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not step handling logic is enabled
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Step Handling")]
|
||||
[UnityEngine.Tooltip("Whether or not step handling logic is enabled")]
|
||||
public bool StepHandling;
|
||||
/// <summary>
|
||||
/// Max height that the character can step on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max height that the character can step on")]
|
||||
public float MaxStepHeight;
|
||||
/// <summary>
|
||||
/// Horizontal offset distance of extra downwards raycasts used to detect grounding around a step
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Horizontal offset distance of extra downwards raycasts used to detect grounding around a step")]
|
||||
public float ExtraStepChecksDistance;
|
||||
/// <summary>
|
||||
/// Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.")]
|
||||
public float CharacterWidthForStepGroundingCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from "snapping" onto the ledge as it moves off of it
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Slope Changes")]
|
||||
[UnityEngine.Tooltip("Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from \"snapping\" onto the ledge as it moves off of it")]
|
||||
public bool PreventGroundingWhenMovingTowardsNoGrounding;
|
||||
/// <summary>
|
||||
/// Whether or not the character has a max slope change that it can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Whether or not the character has a max slope change that it can stay grounded on")]
|
||||
public bool HasMaxDownwardSlopeChangeAngle;
|
||||
/// <summary>
|
||||
/// Max slope change that the character can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max slope change that the character can stay grounded on")]
|
||||
[UnityEngine.Range(0f, 180f)]
|
||||
public float MaxDownwardSlopeChangeAngle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Misc")]
|
||||
[UnityEngine.Tooltip("Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope")]
|
||||
public bool ConstrainVelocityToGroundPlane;
|
||||
|
||||
public static BasicStepAndSlopeHandlingParameters GetDefault()
|
||||
|
@ -354,6 +388,7 @@ namespace Rival
|
|||
StepHandling = false,
|
||||
MaxStepHeight = 0.5f,
|
||||
ExtraStepChecksDistance = 0.1f,
|
||||
CharacterWidthForStepGroundingCheck = 1f,
|
||||
|
||||
PreventGroundingWhenMovingTowardsNoGrounding = true,
|
||||
HasMaxDownwardSlopeChangeAngle = false,
|
||||
|
@ -1448,7 +1483,6 @@ namespace Rival
|
|||
characterBody.IsGrounded,
|
||||
characterBody.RelativeVelocity,
|
||||
isGroundedOnMovementHit);
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(currentCharacterHit));
|
||||
|
||||
processor.OnMovementHit(
|
||||
ref context,
|
||||
|
@ -1918,6 +1952,7 @@ namespace Rival
|
|||
float maxStepHeight,
|
||||
float extraStepChecksDistance) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
|
||||
KinematicCharacterBody characterBody = CharacterBody.ValueRO;
|
||||
KinematicCharacterProperties characterProperties = CharacterProperties.ValueRO;
|
||||
|
||||
|
@ -2045,7 +2080,7 @@ namespace Rival
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the stepping-up-a-step logic during character movement iterations
|
||||
/// </summary>
|
||||
|
@ -2060,6 +2095,7 @@ namespace Rival
|
|||
/// <param name="hitDistance"></param>
|
||||
/// <param name="stepHandling"></param>
|
||||
/// <param name="maxStepHeight"></param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <param name="hasSteppedUp"></param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
|
@ -2075,6 +2111,7 @@ namespace Rival
|
|||
float hitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck,
|
||||
out bool hasSteppedUp) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
hasSteppedUp = false;
|
||||
|
@ -2086,7 +2123,8 @@ namespace Rival
|
|||
if (characterProperties.EvaluateGrounding &&
|
||||
stepHandling &&
|
||||
!hit.IsGroundedOnHit &&
|
||||
maxStepHeight > 0f)
|
||||
maxStepHeight > 0f &&
|
||||
!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
float3 startPositionOfUpCheck = characterPosition;
|
||||
float3 upCheckDirection = characterBody.GroundingUp;
|
||||
|
@ -2119,7 +2157,7 @@ namespace Rival
|
|||
{
|
||||
float3 startPositionOfForwardCheck = startPositionOfUpCheck + (upCheckDirection * upStepHitDistance);
|
||||
float distanceOverStep = math.length(math.projectsafe(remainingMovementDirection * (remainingMovementLength - hitDistance), hit.Normal));
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * remainingMovementLength);
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * (remainingMovementLength + Constants.CollisionOffset));
|
||||
float minimumDistanceOverStep = Constants.CollisionOffset * 3f;
|
||||
if (distanceOverStep < minimumDistanceOverStep)
|
||||
{
|
||||
|
@ -2185,22 +2223,53 @@ namespace Rival
|
|||
}
|
||||
|
||||
if (isGroundedOnStepHit)
|
||||
{
|
||||
float steppedHeight = upStepHitDistance - downStepHitDistance;
|
||||
|
||||
if (steppedHeight > Constants.CollisionOffset)
|
||||
{
|
||||
float hitHeight = upStepHitDistance - downStepHitDistance;
|
||||
float steppedHeight = hitHeight;
|
||||
steppedHeight = math.max(0f, steppedHeight + Constants.CollisionOffset);
|
||||
|
||||
// Add slope & character width consideration to stepped height
|
||||
if(characterWidthForStepGroundingCheck > 0f)
|
||||
{
|
||||
// Find the effective slope normal
|
||||
float3 forwardSlopeCheckDirection = -math.normalizesafe(math.cross(math.cross(characterBody.GroundingUp, stepHit.Normal), stepHit.Normal));
|
||||
|
||||
if (RaycastClosestCollisions(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
stepHit.Position + (characterBody.GroundingUp * Constants.CollisionOffset) + (forwardSlopeCheckDirection * Constants.CollisionOffset),
|
||||
-characterBody.GroundingUp,
|
||||
maxStepHeight,
|
||||
characterProperties.ShouldIgnoreDynamicBodies(),
|
||||
out RaycastHit forwardSlopeCheckHit,
|
||||
out float forwardSlopeCheckHitDistance))
|
||||
{
|
||||
float3 effectiveSlopeNormal = forwardSlopeCheckHit.SurfaceNormal;
|
||||
float slopeRadians = MathUtilities.AngleRadians(characterBody.GroundingUp, effectiveSlopeNormal);
|
||||
float extraHeightFromAngleAndCharacterWidth = math.tan(slopeRadians) * characterWidthForStepGroundingCheck * 0.5f;
|
||||
steppedHeight += extraHeightFromAngleAndCharacterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (steppedHeight < maxStepHeight)
|
||||
{
|
||||
// Step up
|
||||
characterPosition += characterBody.GroundingUp * steppedHeight;
|
||||
characterPosition += characterBody.GroundingUp * hitHeight;
|
||||
characterPosition += forwardCheckDirection * forwardStepHitDistance;
|
||||
|
||||
characterBody.IsGrounded = true;
|
||||
characterBody.GroundHit = stepHit;
|
||||
|
||||
// Project vel
|
||||
float3 characterVelocityBeforeHit = characterBody.RelativeVelocity;
|
||||
characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, characterBody.GroundingUp);
|
||||
remainingMovementDirection = math.normalizesafe(characterBody.RelativeVelocity);
|
||||
remainingMovementLength -= forwardStepHitDistance;
|
||||
|
||||
// Replace hit with step hit
|
||||
hit = KinematicCharacterUtilities.CreateCharacterHit(stepHit, characterBody.IsGrounded, characterVelocityBeforeHit, isGroundedOnStepHit);
|
||||
hit.CharacterVelocityAfterHit = characterBody.RelativeVelocity;
|
||||
|
||||
hasSteppedUp = true;
|
||||
}
|
||||
|
@ -2542,19 +2611,23 @@ namespace Rival
|
|||
if (!isGroundedOnSlope && stepAndSlopeHandling.StepHandling && stepAndSlopeHandling.MaxStepHeight > 0f)
|
||||
{
|
||||
bool hitIsOnCharacterBottom = math.dot(characterBody.GroundingUp, hit.Normal) > Constants.DotProductSimilarityEpsilon;
|
||||
if (hitIsOnCharacterBottom ||
|
||||
(groundingEvaluationType != (int)GroundingEvaluationType.MovementHit && groundingEvaluationType != (int)GroundingEvaluationType.InitialOverlaps))
|
||||
if (hitIsOnCharacterBottom &&
|
||||
(groundingEvaluationType == (int)GroundingEvaluationType.GroundProbing || groundingEvaluationType == (int)GroundingEvaluationType.StepUpHit))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
// Prevent step grounding detection on dynamic bodies, to prevent cases of character stepping onto sphere rolling towards it
|
||||
if (!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return isGroundedOnSlope || isGroundedOnSteps;
|
||||
}
|
||||
|
||||
|
@ -2666,7 +2739,7 @@ namespace Rival
|
|||
ProjectVelocityOnSingleHit(ref velocity, ref characterIsGrounded, ref characterGroundHit, in firstHit, characterBody.GroundingUp);
|
||||
velocityDirection = math.normalizesafe(velocity);
|
||||
|
||||
// Original velocity direction will act as a plane constaint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
// Original velocity direction will act as a plane constraint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
KinematicVelocityProjectionHit originalVelocityHit = default;
|
||||
originalVelocityHit.Normal = characterIsGrounded ? math.normalizesafe(MathUtilities.ProjectOnPlane(originalVelocityDirection, characterBody.GroundingUp)) : originalVelocityDirection;
|
||||
|
||||
|
@ -2760,6 +2833,7 @@ namespace Rival
|
|||
/// <param name="movementHitDistance"> Distance of the hit </param>
|
||||
/// <param name="stepHandling"> Whether step-handling is enabled or not </param>
|
||||
/// <param name="maxStepHeight"> Maximum height of steps that can be stepped on </param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
public void Default_OnMovementHit<T, C>(
|
||||
|
@ -2774,7 +2848,8 @@ namespace Rival
|
|||
float3 originalVelocityDirection,
|
||||
float movementHitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck = 0f) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
bool hasSteppedUp = false;
|
||||
|
||||
|
@ -2794,8 +2869,12 @@ namespace Rival
|
|||
movementHitDistance,
|
||||
stepHandling,
|
||||
maxStepHeight,
|
||||
characterWidthForStepGroundingCheck,
|
||||
out hasSteppedUp);
|
||||
}
|
||||
|
||||
// Add velocityProjection hits only after potential correction from step handling
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(hit));
|
||||
|
||||
if (!hasSteppedUp)
|
||||
{
|
||||
|
@ -2814,7 +2893,7 @@ namespace Rival
|
|||
ref characterBody.GroundHit,
|
||||
in VelocityProjectionHits,
|
||||
originalVelocityDirection);
|
||||
|
||||
|
||||
// Recalculate remaining movement after projection
|
||||
float projectedVelocityLengthFactor = math.length(characterBody.RelativeVelocity) / math.length(velocityBeforeProjection);
|
||||
remainingMovementLength *= projectedVelocityLengthFactor;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Rival
|
|||
// Grounding
|
||||
EvaluateGrounding = true,
|
||||
SnapToGround = true,
|
||||
GroundSnappingDistance = 0.3f,
|
||||
GroundSnappingDistance = 0.5f,
|
||||
EnhancedGroundPrecision = false,
|
||||
MaxGroundedSlopeAngle = 60f,
|
||||
|
||||
|
|
|
@ -270,22 +270,25 @@ namespace Rival
|
|||
float3 relativeVelocityAToB = pointVelocityB - pointVelocityA;
|
||||
float relativeVelocityOnNormal = math.dot(relativeVelocityAToB, collisionNormalBToA);
|
||||
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
if (invEffectiveMass > 0f)
|
||||
if (relativeVelocityOnNormal > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
if (invEffectiveMass > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -361,7 +361,8 @@ public readonly partial struct PlatformerCharacterAspect : IAspect, IKinematicCh
|
|||
originalVelocityDirection,
|
||||
hitDistance,
|
||||
characterComponent.StepAndSlopeHandling.StepHandling,
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight);
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight,
|
||||
characterComponent.StepAndSlopeHandling.CharacterWidthForStepGroundingCheck);
|
||||
}
|
||||
|
||||
public void OverrideDynamicHitMasses(
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2022.2.0f1
|
||||
m_EditorVersionWithRevision: 2022.2.0f1 (35dcd44975df)
|
||||
m_EditorVersion: 2022.2.1f1
|
||||
m_EditorVersionWithRevision: 2022.2.1f1 (4fead5835099)
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Physics.Authoring;
|
|||
using Unity.Physics.Extensions;
|
||||
using Unity.Physics.Systems;
|
||||
using Unity.Transforms;
|
||||
using UnityEngine;
|
||||
using Material = Unity.Physics.Material;
|
||||
using RaycastHit = Unity.Physics.RaycastHit;
|
||||
|
||||
|
@ -333,18 +334,51 @@ namespace Rival
|
|||
[Serializable]
|
||||
public struct BasicStepAndSlopeHandlingParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not step handling logic is enabled
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Step Handling")]
|
||||
[UnityEngine.Tooltip("Whether or not step handling logic is enabled")]
|
||||
public bool StepHandling;
|
||||
/// <summary>
|
||||
/// Max height that the character can step on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max height that the character can step on")]
|
||||
public float MaxStepHeight;
|
||||
/// <summary>
|
||||
/// Horizontal offset distance of extra downwards raycasts used to detect grounding around a step
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Horizontal offset distance of extra downwards raycasts used to detect grounding around a step")]
|
||||
public float ExtraStepChecksDistance;
|
||||
/// <summary>
|
||||
/// Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.")]
|
||||
public float CharacterWidthForStepGroundingCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from "snapping" onto the ledge as it moves off of it
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Slope Changes")]
|
||||
[UnityEngine.Tooltip("Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from \"snapping\" onto the ledge as it moves off of it")]
|
||||
public bool PreventGroundingWhenMovingTowardsNoGrounding;
|
||||
/// <summary>
|
||||
/// Whether or not the character has a max slope change that it can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Whether or not the character has a max slope change that it can stay grounded on")]
|
||||
public bool HasMaxDownwardSlopeChangeAngle;
|
||||
/// <summary>
|
||||
/// Max slope change that the character can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max slope change that the character can stay grounded on")]
|
||||
[UnityEngine.Range(0f, 180f)]
|
||||
public float MaxDownwardSlopeChangeAngle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Misc")]
|
||||
[UnityEngine.Tooltip("Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope")]
|
||||
public bool ConstrainVelocityToGroundPlane;
|
||||
|
||||
public static BasicStepAndSlopeHandlingParameters GetDefault()
|
||||
|
@ -354,6 +388,7 @@ namespace Rival
|
|||
StepHandling = false,
|
||||
MaxStepHeight = 0.5f,
|
||||
ExtraStepChecksDistance = 0.1f,
|
||||
CharacterWidthForStepGroundingCheck = 1f,
|
||||
|
||||
PreventGroundingWhenMovingTowardsNoGrounding = true,
|
||||
HasMaxDownwardSlopeChangeAngle = false,
|
||||
|
@ -1448,7 +1483,6 @@ namespace Rival
|
|||
characterBody.IsGrounded,
|
||||
characterBody.RelativeVelocity,
|
||||
isGroundedOnMovementHit);
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(currentCharacterHit));
|
||||
|
||||
processor.OnMovementHit(
|
||||
ref context,
|
||||
|
@ -1918,6 +1952,7 @@ namespace Rival
|
|||
float maxStepHeight,
|
||||
float extraStepChecksDistance) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
|
||||
KinematicCharacterBody characterBody = CharacterBody.ValueRO;
|
||||
KinematicCharacterProperties characterProperties = CharacterProperties.ValueRO;
|
||||
|
||||
|
@ -2045,7 +2080,7 @@ namespace Rival
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the stepping-up-a-step logic during character movement iterations
|
||||
/// </summary>
|
||||
|
@ -2060,6 +2095,7 @@ namespace Rival
|
|||
/// <param name="hitDistance"></param>
|
||||
/// <param name="stepHandling"></param>
|
||||
/// <param name="maxStepHeight"></param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <param name="hasSteppedUp"></param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
|
@ -2075,6 +2111,7 @@ namespace Rival
|
|||
float hitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck,
|
||||
out bool hasSteppedUp) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
hasSteppedUp = false;
|
||||
|
@ -2086,7 +2123,8 @@ namespace Rival
|
|||
if (characterProperties.EvaluateGrounding &&
|
||||
stepHandling &&
|
||||
!hit.IsGroundedOnHit &&
|
||||
maxStepHeight > 0f)
|
||||
maxStepHeight > 0f &&
|
||||
!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
float3 startPositionOfUpCheck = characterPosition;
|
||||
float3 upCheckDirection = characterBody.GroundingUp;
|
||||
|
@ -2119,7 +2157,7 @@ namespace Rival
|
|||
{
|
||||
float3 startPositionOfForwardCheck = startPositionOfUpCheck + (upCheckDirection * upStepHitDistance);
|
||||
float distanceOverStep = math.length(math.projectsafe(remainingMovementDirection * (remainingMovementLength - hitDistance), hit.Normal));
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * remainingMovementLength);
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * (remainingMovementLength + Constants.CollisionOffset));
|
||||
float minimumDistanceOverStep = Constants.CollisionOffset * 3f;
|
||||
if (distanceOverStep < minimumDistanceOverStep)
|
||||
{
|
||||
|
@ -2185,22 +2223,53 @@ namespace Rival
|
|||
}
|
||||
|
||||
if (isGroundedOnStepHit)
|
||||
{
|
||||
float steppedHeight = upStepHitDistance - downStepHitDistance;
|
||||
|
||||
if (steppedHeight > Constants.CollisionOffset)
|
||||
{
|
||||
float hitHeight = upStepHitDistance - downStepHitDistance;
|
||||
float steppedHeight = hitHeight;
|
||||
steppedHeight = math.max(0f, steppedHeight + Constants.CollisionOffset);
|
||||
|
||||
// Add slope & character width consideration to stepped height
|
||||
if(characterWidthForStepGroundingCheck > 0f)
|
||||
{
|
||||
// Find the effective slope normal
|
||||
float3 forwardSlopeCheckDirection = -math.normalizesafe(math.cross(math.cross(characterBody.GroundingUp, stepHit.Normal), stepHit.Normal));
|
||||
|
||||
if (RaycastClosestCollisions(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
stepHit.Position + (characterBody.GroundingUp * Constants.CollisionOffset) + (forwardSlopeCheckDirection * Constants.CollisionOffset),
|
||||
-characterBody.GroundingUp,
|
||||
maxStepHeight,
|
||||
characterProperties.ShouldIgnoreDynamicBodies(),
|
||||
out RaycastHit forwardSlopeCheckHit,
|
||||
out float forwardSlopeCheckHitDistance))
|
||||
{
|
||||
float3 effectiveSlopeNormal = forwardSlopeCheckHit.SurfaceNormal;
|
||||
float slopeRadians = MathUtilities.AngleRadians(characterBody.GroundingUp, effectiveSlopeNormal);
|
||||
float extraHeightFromAngleAndCharacterWidth = math.tan(slopeRadians) * characterWidthForStepGroundingCheck * 0.5f;
|
||||
steppedHeight += extraHeightFromAngleAndCharacterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (steppedHeight < maxStepHeight)
|
||||
{
|
||||
// Step up
|
||||
characterPosition += characterBody.GroundingUp * steppedHeight;
|
||||
characterPosition += characterBody.GroundingUp * hitHeight;
|
||||
characterPosition += forwardCheckDirection * forwardStepHitDistance;
|
||||
|
||||
characterBody.IsGrounded = true;
|
||||
characterBody.GroundHit = stepHit;
|
||||
|
||||
// Project vel
|
||||
float3 characterVelocityBeforeHit = characterBody.RelativeVelocity;
|
||||
characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, characterBody.GroundingUp);
|
||||
remainingMovementDirection = math.normalizesafe(characterBody.RelativeVelocity);
|
||||
remainingMovementLength -= forwardStepHitDistance;
|
||||
|
||||
// Replace hit with step hit
|
||||
hit = KinematicCharacterUtilities.CreateCharacterHit(stepHit, characterBody.IsGrounded, characterVelocityBeforeHit, isGroundedOnStepHit);
|
||||
hit.CharacterVelocityAfterHit = characterBody.RelativeVelocity;
|
||||
|
||||
hasSteppedUp = true;
|
||||
}
|
||||
|
@ -2542,19 +2611,23 @@ namespace Rival
|
|||
if (!isGroundedOnSlope && stepAndSlopeHandling.StepHandling && stepAndSlopeHandling.MaxStepHeight > 0f)
|
||||
{
|
||||
bool hitIsOnCharacterBottom = math.dot(characterBody.GroundingUp, hit.Normal) > Constants.DotProductSimilarityEpsilon;
|
||||
if (hitIsOnCharacterBottom ||
|
||||
(groundingEvaluationType != (int)GroundingEvaluationType.MovementHit && groundingEvaluationType != (int)GroundingEvaluationType.InitialOverlaps))
|
||||
if (hitIsOnCharacterBottom &&
|
||||
(groundingEvaluationType == (int)GroundingEvaluationType.GroundProbing || groundingEvaluationType == (int)GroundingEvaluationType.StepUpHit))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
// Prevent step grounding detection on dynamic bodies, to prevent cases of character stepping onto sphere rolling towards it
|
||||
if (!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return isGroundedOnSlope || isGroundedOnSteps;
|
||||
}
|
||||
|
||||
|
@ -2666,7 +2739,7 @@ namespace Rival
|
|||
ProjectVelocityOnSingleHit(ref velocity, ref characterIsGrounded, ref characterGroundHit, in firstHit, characterBody.GroundingUp);
|
||||
velocityDirection = math.normalizesafe(velocity);
|
||||
|
||||
// Original velocity direction will act as a plane constaint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
// Original velocity direction will act as a plane constraint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
KinematicVelocityProjectionHit originalVelocityHit = default;
|
||||
originalVelocityHit.Normal = characterIsGrounded ? math.normalizesafe(MathUtilities.ProjectOnPlane(originalVelocityDirection, characterBody.GroundingUp)) : originalVelocityDirection;
|
||||
|
||||
|
@ -2760,6 +2833,7 @@ namespace Rival
|
|||
/// <param name="movementHitDistance"> Distance of the hit </param>
|
||||
/// <param name="stepHandling"> Whether step-handling is enabled or not </param>
|
||||
/// <param name="maxStepHeight"> Maximum height of steps that can be stepped on </param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
public void Default_OnMovementHit<T, C>(
|
||||
|
@ -2774,7 +2848,8 @@ namespace Rival
|
|||
float3 originalVelocityDirection,
|
||||
float movementHitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck = 0f) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
bool hasSteppedUp = false;
|
||||
|
||||
|
@ -2794,8 +2869,12 @@ namespace Rival
|
|||
movementHitDistance,
|
||||
stepHandling,
|
||||
maxStepHeight,
|
||||
characterWidthForStepGroundingCheck,
|
||||
out hasSteppedUp);
|
||||
}
|
||||
|
||||
// Add velocityProjection hits only after potential correction from step handling
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(hit));
|
||||
|
||||
if (!hasSteppedUp)
|
||||
{
|
||||
|
@ -2814,7 +2893,7 @@ namespace Rival
|
|||
ref characterBody.GroundHit,
|
||||
in VelocityProjectionHits,
|
||||
originalVelocityDirection);
|
||||
|
||||
|
||||
// Recalculate remaining movement after projection
|
||||
float projectedVelocityLengthFactor = math.length(characterBody.RelativeVelocity) / math.length(velocityBeforeProjection);
|
||||
remainingMovementLength *= projectedVelocityLengthFactor;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Rival
|
|||
// Grounding
|
||||
EvaluateGrounding = true,
|
||||
SnapToGround = true,
|
||||
GroundSnappingDistance = 0.3f,
|
||||
GroundSnappingDistance = 0.5f,
|
||||
EnhancedGroundPrecision = false,
|
||||
MaxGroundedSlopeAngle = 60f,
|
||||
|
||||
|
|
|
@ -270,22 +270,25 @@ namespace Rival
|
|||
float3 relativeVelocityAToB = pointVelocityB - pointVelocityA;
|
||||
float relativeVelocityOnNormal = math.dot(relativeVelocityAToB, collisionNormalBToA);
|
||||
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
if (invEffectiveMass > 0f)
|
||||
if (relativeVelocityOnNormal > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
if (invEffectiveMass > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичные данные
StressTest/Assets/SceneDependencyCache/ff97f6f657bbe9caa9004db02d37109a.sceneWithBuildSettings
Normal file
Двоичные данные
StressTest/Assets/SceneDependencyCache/ff97f6f657bbe9caa9004db02d37109a.sceneWithBuildSettings
Normal file
Двоичный файл не отображается.
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ff97f6f657bbe9caa9004db02d37109a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -192,7 +192,8 @@ public readonly partial struct StressTestCharacterAspect : IAspect, IKinematicCh
|
|||
originalVelocityDirection,
|
||||
hitDistance,
|
||||
characterComponent.StepAndSlopeHandling.StepHandling,
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight);
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight,
|
||||
characterComponent.StepAndSlopeHandling.CharacterWidthForStepGroundingCheck);
|
||||
}
|
||||
|
||||
public void OverrideDynamicHitMasses(
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2022.2.0f1
|
||||
m_EditorVersionWithRevision: 2022.2.0f1 (35dcd44975df)
|
||||
m_EditorVersion: 2022.2.1f1
|
||||
m_EditorVersionWithRevision: 2022.2.1f1 (4fead5835099)
|
||||
|
|
|
@ -12,6 +12,7 @@ using Unity.Physics.Authoring;
|
|||
using Unity.Physics.Extensions;
|
||||
using Unity.Physics.Systems;
|
||||
using Unity.Transforms;
|
||||
using UnityEngine;
|
||||
using Material = Unity.Physics.Material;
|
||||
using RaycastHit = Unity.Physics.RaycastHit;
|
||||
|
||||
|
@ -333,18 +334,51 @@ namespace Rival
|
|||
[Serializable]
|
||||
public struct BasicStepAndSlopeHandlingParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not step handling logic is enabled
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Step Handling")]
|
||||
[UnityEngine.Tooltip("Whether or not step handling logic is enabled")]
|
||||
public bool StepHandling;
|
||||
/// <summary>
|
||||
/// Max height that the character can step on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max height that the character can step on")]
|
||||
public float MaxStepHeight;
|
||||
/// <summary>
|
||||
/// Horizontal offset distance of extra downwards raycasts used to detect grounding around a step
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Horizontal offset distance of extra downwards raycasts used to detect grounding around a step")]
|
||||
public float ExtraStepChecksDistance;
|
||||
/// <summary>
|
||||
/// Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Character width used to determine grounding for steps. For a capsule this should be 2x capsule radius, and for a box it should be maximum box width. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height.")]
|
||||
public float CharacterWidthForStepGroundingCheck;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from "snapping" onto the ledge as it moves off of it
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Slope Changes")]
|
||||
[UnityEngine.Tooltip("Whether or not to cancel grounding when the character is moving off a ledge. This prevents the character from \"snapping\" onto the ledge as it moves off of it")]
|
||||
public bool PreventGroundingWhenMovingTowardsNoGrounding;
|
||||
/// <summary>
|
||||
/// Whether or not the character has a max slope change that it can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Whether or not the character has a max slope change that it can stay grounded on")]
|
||||
public bool HasMaxDownwardSlopeChangeAngle;
|
||||
/// <summary>
|
||||
/// Max slope change that the character can stay grounded on
|
||||
/// </summary>
|
||||
[UnityEngine.Tooltip("Max slope change that the character can stay grounded on")]
|
||||
[UnityEngine.Range(0f, 180f)]
|
||||
public float MaxDownwardSlopeChangeAngle;
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope
|
||||
/// </summary>
|
||||
[UnityEngine.Header("Misc")]
|
||||
[UnityEngine.Tooltip("Whether or not to constrain the character velocity to ground plane when it hits a non-grounded slope")]
|
||||
public bool ConstrainVelocityToGroundPlane;
|
||||
|
||||
public static BasicStepAndSlopeHandlingParameters GetDefault()
|
||||
|
@ -354,6 +388,7 @@ namespace Rival
|
|||
StepHandling = false,
|
||||
MaxStepHeight = 0.5f,
|
||||
ExtraStepChecksDistance = 0.1f,
|
||||
CharacterWidthForStepGroundingCheck = 1f,
|
||||
|
||||
PreventGroundingWhenMovingTowardsNoGrounding = true,
|
||||
HasMaxDownwardSlopeChangeAngle = false,
|
||||
|
@ -1448,7 +1483,6 @@ namespace Rival
|
|||
characterBody.IsGrounded,
|
||||
characterBody.RelativeVelocity,
|
||||
isGroundedOnMovementHit);
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(currentCharacterHit));
|
||||
|
||||
processor.OnMovementHit(
|
||||
ref context,
|
||||
|
@ -1918,6 +1952,7 @@ namespace Rival
|
|||
float maxStepHeight,
|
||||
float extraStepChecksDistance) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
|
||||
KinematicCharacterBody characterBody = CharacterBody.ValueRO;
|
||||
KinematicCharacterProperties characterProperties = CharacterProperties.ValueRO;
|
||||
|
||||
|
@ -2045,7 +2080,7 @@ namespace Rival
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles the stepping-up-a-step logic during character movement iterations
|
||||
/// </summary>
|
||||
|
@ -2060,6 +2095,7 @@ namespace Rival
|
|||
/// <param name="hitDistance"></param>
|
||||
/// <param name="stepHandling"></param>
|
||||
/// <param name="maxStepHeight"></param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <param name="hasSteppedUp"></param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
|
@ -2075,6 +2111,7 @@ namespace Rival
|
|||
float hitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck,
|
||||
out bool hasSteppedUp) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
hasSteppedUp = false;
|
||||
|
@ -2086,7 +2123,8 @@ namespace Rival
|
|||
if (characterProperties.EvaluateGrounding &&
|
||||
stepHandling &&
|
||||
!hit.IsGroundedOnHit &&
|
||||
maxStepHeight > 0f)
|
||||
maxStepHeight > 0f &&
|
||||
!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
float3 startPositionOfUpCheck = characterPosition;
|
||||
float3 upCheckDirection = characterBody.GroundingUp;
|
||||
|
@ -2119,7 +2157,7 @@ namespace Rival
|
|||
{
|
||||
float3 startPositionOfForwardCheck = startPositionOfUpCheck + (upCheckDirection * upStepHitDistance);
|
||||
float distanceOverStep = math.length(math.projectsafe(remainingMovementDirection * (remainingMovementLength - hitDistance), hit.Normal));
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * remainingMovementLength);
|
||||
float3 endPositionOfForwardCheck = startPositionOfForwardCheck + (remainingMovementDirection * (remainingMovementLength + Constants.CollisionOffset));
|
||||
float minimumDistanceOverStep = Constants.CollisionOffset * 3f;
|
||||
if (distanceOverStep < minimumDistanceOverStep)
|
||||
{
|
||||
|
@ -2185,22 +2223,53 @@ namespace Rival
|
|||
}
|
||||
|
||||
if (isGroundedOnStepHit)
|
||||
{
|
||||
float steppedHeight = upStepHitDistance - downStepHitDistance;
|
||||
|
||||
if (steppedHeight > Constants.CollisionOffset)
|
||||
{
|
||||
float hitHeight = upStepHitDistance - downStepHitDistance;
|
||||
float steppedHeight = hitHeight;
|
||||
steppedHeight = math.max(0f, steppedHeight + Constants.CollisionOffset);
|
||||
|
||||
// Add slope & character width consideration to stepped height
|
||||
if(characterWidthForStepGroundingCheck > 0f)
|
||||
{
|
||||
// Find the effective slope normal
|
||||
float3 forwardSlopeCheckDirection = -math.normalizesafe(math.cross(math.cross(characterBody.GroundingUp, stepHit.Normal), stepHit.Normal));
|
||||
|
||||
if (RaycastClosestCollisions(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
stepHit.Position + (characterBody.GroundingUp * Constants.CollisionOffset) + (forwardSlopeCheckDirection * Constants.CollisionOffset),
|
||||
-characterBody.GroundingUp,
|
||||
maxStepHeight,
|
||||
characterProperties.ShouldIgnoreDynamicBodies(),
|
||||
out RaycastHit forwardSlopeCheckHit,
|
||||
out float forwardSlopeCheckHitDistance))
|
||||
{
|
||||
float3 effectiveSlopeNormal = forwardSlopeCheckHit.SurfaceNormal;
|
||||
float slopeRadians = MathUtilities.AngleRadians(characterBody.GroundingUp, effectiveSlopeNormal);
|
||||
float extraHeightFromAngleAndCharacterWidth = math.tan(slopeRadians) * characterWidthForStepGroundingCheck * 0.5f;
|
||||
steppedHeight += extraHeightFromAngleAndCharacterWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (steppedHeight < maxStepHeight)
|
||||
{
|
||||
// Step up
|
||||
characterPosition += characterBody.GroundingUp * steppedHeight;
|
||||
characterPosition += characterBody.GroundingUp * hitHeight;
|
||||
characterPosition += forwardCheckDirection * forwardStepHitDistance;
|
||||
|
||||
characterBody.IsGrounded = true;
|
||||
characterBody.GroundHit = stepHit;
|
||||
|
||||
// Project vel
|
||||
float3 characterVelocityBeforeHit = characterBody.RelativeVelocity;
|
||||
characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, characterBody.GroundingUp);
|
||||
remainingMovementDirection = math.normalizesafe(characterBody.RelativeVelocity);
|
||||
remainingMovementLength -= forwardStepHitDistance;
|
||||
|
||||
// Replace hit with step hit
|
||||
hit = KinematicCharacterUtilities.CreateCharacterHit(stepHit, characterBody.IsGrounded, characterVelocityBeforeHit, isGroundedOnStepHit);
|
||||
hit.CharacterVelocityAfterHit = characterBody.RelativeVelocity;
|
||||
|
||||
hasSteppedUp = true;
|
||||
}
|
||||
|
@ -2542,19 +2611,23 @@ namespace Rival
|
|||
if (!isGroundedOnSlope && stepAndSlopeHandling.StepHandling && stepAndSlopeHandling.MaxStepHeight > 0f)
|
||||
{
|
||||
bool hitIsOnCharacterBottom = math.dot(characterBody.GroundingUp, hit.Normal) > Constants.DotProductSimilarityEpsilon;
|
||||
if (hitIsOnCharacterBottom ||
|
||||
(groundingEvaluationType != (int)GroundingEvaluationType.MovementHit && groundingEvaluationType != (int)GroundingEvaluationType.InitialOverlaps))
|
||||
if (hitIsOnCharacterBottom &&
|
||||
(groundingEvaluationType == (int)GroundingEvaluationType.GroundProbing || groundingEvaluationType == (int)GroundingEvaluationType.StepUpHit))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
// Prevent step grounding detection on dynamic bodies, to prevent cases of character stepping onto sphere rolling towards it
|
||||
if (!PhysicsUtilities.IsBodyDynamic(in baseContext.PhysicsWorld, hit.RigidBodyIndex))
|
||||
{
|
||||
isGroundedOnSteps = IsGroundedOnSteps(
|
||||
in processor,
|
||||
ref context,
|
||||
ref baseContext,
|
||||
in hit,
|
||||
stepAndSlopeHandling.MaxStepHeight,
|
||||
stepAndSlopeHandling.ExtraStepChecksDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return isGroundedOnSlope || isGroundedOnSteps;
|
||||
}
|
||||
|
||||
|
@ -2666,7 +2739,7 @@ namespace Rival
|
|||
ProjectVelocityOnSingleHit(ref velocity, ref characterIsGrounded, ref characterGroundHit, in firstHit, characterBody.GroundingUp);
|
||||
velocityDirection = math.normalizesafe(velocity);
|
||||
|
||||
// Original velocity direction will act as a plane constaint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
// Original velocity direction will act as a plane constraint just like other hits, to prevent our velocity from going back the way it came from. Hit index -1 represents original velocity
|
||||
KinematicVelocityProjectionHit originalVelocityHit = default;
|
||||
originalVelocityHit.Normal = characterIsGrounded ? math.normalizesafe(MathUtilities.ProjectOnPlane(originalVelocityDirection, characterBody.GroundingUp)) : originalVelocityDirection;
|
||||
|
||||
|
@ -2760,6 +2833,7 @@ namespace Rival
|
|||
/// <param name="movementHitDistance"> Distance of the hit </param>
|
||||
/// <param name="stepHandling"> Whether step-handling is enabled or not </param>
|
||||
/// <param name="maxStepHeight"> Maximum height of steps that can be stepped on </param>
|
||||
/// <param name="characterWidthForStepGroundingCheck"> Character width used to determine grounding for steps. This is for cases where character with a spherical base tries to step onto an angled surface that is near the character's max step height. In thoses cases, the character might be grounded on steps on one frame, but wouldn't be grounded on the next frame as the spherical nature of its shape would push it a bit further up beyond its max step height. </param>
|
||||
/// <typeparam name="T"> The type of the struct implementing <see cref="IKinematicCharacterProcessor{C}"/> </typeparam>
|
||||
/// <typeparam name="C"> The type of the user-created context struct </typeparam>
|
||||
public void Default_OnMovementHit<T, C>(
|
||||
|
@ -2774,7 +2848,8 @@ namespace Rival
|
|||
float3 originalVelocityDirection,
|
||||
float movementHitDistance,
|
||||
bool stepHandling,
|
||||
float maxStepHeight) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
float maxStepHeight,
|
||||
float characterWidthForStepGroundingCheck = 0f) where T : unmanaged, IKinematicCharacterProcessor<C> where C : unmanaged
|
||||
{
|
||||
bool hasSteppedUp = false;
|
||||
|
||||
|
@ -2794,8 +2869,12 @@ namespace Rival
|
|||
movementHitDistance,
|
||||
stepHandling,
|
||||
maxStepHeight,
|
||||
characterWidthForStepGroundingCheck,
|
||||
out hasSteppedUp);
|
||||
}
|
||||
|
||||
// Add velocityProjection hits only after potential correction from step handling
|
||||
VelocityProjectionHits.Add(new KinematicVelocityProjectionHit(hit));
|
||||
|
||||
if (!hasSteppedUp)
|
||||
{
|
||||
|
@ -2814,7 +2893,7 @@ namespace Rival
|
|||
ref characterBody.GroundHit,
|
||||
in VelocityProjectionHits,
|
||||
originalVelocityDirection);
|
||||
|
||||
|
||||
// Recalculate remaining movement after projection
|
||||
float projectedVelocityLengthFactor = math.length(characterBody.RelativeVelocity) / math.length(velocityBeforeProjection);
|
||||
remainingMovementLength *= projectedVelocityLengthFactor;
|
||||
|
|
|
@ -131,7 +131,7 @@ namespace Rival
|
|||
// Grounding
|
||||
EvaluateGrounding = true,
|
||||
SnapToGround = true,
|
||||
GroundSnappingDistance = 0.3f,
|
||||
GroundSnappingDistance = 0.5f,
|
||||
EnhancedGroundPrecision = false,
|
||||
MaxGroundedSlopeAngle = 60f,
|
||||
|
||||
|
|
|
@ -270,22 +270,25 @@ namespace Rival
|
|||
float3 relativeVelocityAToB = pointVelocityB - pointVelocityA;
|
||||
float relativeVelocityOnNormal = math.dot(relativeVelocityAToB, collisionNormalBToA);
|
||||
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
if (invEffectiveMass > 0f)
|
||||
if (relativeVelocityOnNormal > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
float3 crossA = math.cross(centerOfMassAToPoint, collisionNormalBToA);
|
||||
float3 crossB = math.cross(collisionNormalBToA, centerOfMassBToPoint);
|
||||
float3 angularA = math.mul(new Math.MTransform(transformA).InverseRotation, crossA).xyz;
|
||||
float3 angularB = math.mul(new Math.MTransform(transformB).InverseRotation, crossB).xyz;
|
||||
float3 temp = angularA * angularA * physicsMassA.InverseInertia + angularB * angularB * physicsMassB.InverseInertia;
|
||||
float invEffectiveMass = temp.x + temp.y + temp.z + (physicsMassA.InverseMass + physicsMassB.InverseMass);
|
||||
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
if (invEffectiveMass > 0f)
|
||||
{
|
||||
float effectiveMass = 1f / invEffectiveMass;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
float impulseScale = -relativeVelocityOnNormal * effectiveMass;
|
||||
float3 totalImpulse = collisionNormalBToA * impulseScale;
|
||||
|
||||
impulseOnA = -totalImpulse;
|
||||
impulseOnB = totalImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -227,7 +227,8 @@ public readonly partial struct ThirdPersonCharacterAspect : IAspect, IKinematicC
|
|||
originalVelocityDirection,
|
||||
hitDistance,
|
||||
characterComponent.StepAndSlopeHandling.StepHandling,
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight);
|
||||
characterComponent.StepAndSlopeHandling.MaxStepHeight,
|
||||
characterComponent.StepAndSlopeHandling.CharacterWidthForStepGroundingCheck);
|
||||
}
|
||||
|
||||
public void OverrideDynamicHitMasses(
|
||||
|
|
|
@ -1333,6 +1333,7 @@ MonoBehaviour:
|
|||
StepHandling: 1
|
||||
MaxStepHeight: 0.5
|
||||
ExtraStepChecksDistance: 0.1
|
||||
CharacterWidthForStepGroundingCheck: 1
|
||||
PreventGroundingWhenMovingTowardsNoGrounding: 1
|
||||
HasMaxDownwardSlopeChangeAngle: 0
|
||||
MaxDownwardSlopeChangeAngle: 90
|
||||
|
@ -1659,6 +1660,11 @@ PrefabInstance:
|
|||
propertyPath: m_Name
|
||||
value: ThirdPersonCharacter
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6689285571920954877, guid: 5fbcc801dea8fd640a004697d22ed448,
|
||||
type: 3}
|
||||
propertyPath: CharacterProperties.GroundSnappingDistance
|
||||
value: 0.5
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_RemovedGameObjects: []
|
||||
m_AddedGameObjects: []
|
||||
|
@ -3044,6 +3050,7 @@ MonoBehaviour:
|
|||
StepHandling: 1
|
||||
MaxStepHeight: 0.5
|
||||
ExtraStepChecksDistance: 0.1
|
||||
CharacterWidthForStepGroundingCheck: 1
|
||||
PreventGroundingWhenMovingTowardsNoGrounding: 1
|
||||
HasMaxDownwardSlopeChangeAngle: 0
|
||||
MaxDownwardSlopeChangeAngle: 90
|
||||
|
@ -5028,6 +5035,7 @@ MonoBehaviour:
|
|||
StepHandling: 1
|
||||
MaxStepHeight: 0.5
|
||||
ExtraStepChecksDistance: 0.1
|
||||
CharacterWidthForStepGroundingCheck: 1
|
||||
PreventGroundingWhenMovingTowardsNoGrounding: 1
|
||||
HasMaxDownwardSlopeChangeAngle: 0
|
||||
MaxDownwardSlopeChangeAngle: 90
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
m_EditorVersion: 2022.2.0f1
|
||||
m_EditorVersionWithRevision: 2022.2.0f1 (35dcd44975df)
|
||||
m_EditorVersion: 2022.2.1f1
|
||||
m_EditorVersionWithRevision: 2022.2.1f1 (4fead5835099)
|
||||
|
|
Загрузка…
Ссылка в новой задаче