Steep Contacts - Done!

This commit is contained in:
_Redstone_c_ 2021-02-08 19:01:37 +08:00
parent 6489a9f249
commit 9d848fbf4a
3 changed files with 248 additions and 31 deletions

View File

@ -98,7 +98,7 @@ LightmapSettings:
m_TrainingDataDestination: TrainingData m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4 m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0} m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0 m_UseShadowmask: 1
--- !u!196 &4 --- !u!196 &4
NavMeshSettings: NavMeshSettings:
serializedVersion: 2 serializedVersion: 2
@ -374,7 +374,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 1 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &963194225 --- !u!1 &963194225
GameObject: GameObject:
@ -430,7 +430,7 @@ Camera:
far clip plane: 1000 far clip plane: 1000
field of view: 60 field of view: 60
orthographic: 1 orthographic: 1
orthographic size: 32.84 orthographic size: 8
m_Depth: -1 m_Depth: -1
m_CullingMask: m_CullingMask:
serializedVersion: 2 serializedVersion: 2
@ -454,7 +454,7 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225} m_GameObject: {fileID: 963194225}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 100, z: 0} m_LocalPosition: {x: 0, y: 50, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
@ -491,6 +491,75 @@ MonoBehaviour:
m_RequiresDepthTexture: 0 m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0 m_RequiresColorTexture: 0
m_Version: 2 m_Version: 2
--- !u!1001 &1389571916
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720839, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_Name
value: Sphere
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 3dd5393965472a4438e901f90d336e67, type: 3}
--- !u!1 &1599492292 --- !u!1 &1599492292
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -1280,5 +1349,5 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 2 m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

View File

@ -98,7 +98,7 @@ LightmapSettings:
m_TrainingDataDestination: TrainingData m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4 m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0} m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 0 m_UseShadowmask: 1
--- !u!196 &4 --- !u!196 &4
NavMeshSettings: NavMeshSettings:
serializedVersion: 2 serializedVersion: 2
@ -121,6 +121,75 @@ NavMeshSettings:
debug: debug:
m_Flags: 0 m_Flags: 0
m_NavMeshData: {fileID: 0} m_NavMeshData: {fileID: 0}
--- !u!1001 &140227663
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_RootOrder
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalPosition.z
value: -0.5
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720835, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6426552592410720839, guid: 3dd5393965472a4438e901f90d336e67,
type: 3}
propertyPath: m_Name
value: Sphere
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 3dd5393965472a4438e901f90d336e67, type: 3}
--- !u!43 &151422163 --- !u!43 &151422163
Mesh: Mesh:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -374,7 +443,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 1 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
--- !u!1 &963194225 --- !u!1 &963194225
GameObject: GameObject:
@ -387,6 +456,7 @@ GameObject:
- component: {fileID: 963194228} - component: {fileID: 963194228}
- component: {fileID: 963194227} - component: {fileID: 963194227}
- component: {fileID: 963194226} - component: {fileID: 963194226}
- component: {fileID: 963194229}
m_Layer: 0 m_Layer: 0
m_Name: Main Camera m_Name: Main Camera
m_TagString: MainCamera m_TagString: MainCamera
@ -429,7 +499,7 @@ Camera:
far clip plane: 1000 far clip plane: 1000
field of view: 60 field of view: 60
orthographic: 1 orthographic: 1
orthographic size: 32.84 orthographic size: 8
m_Depth: -1 m_Depth: -1
m_CullingMask: m_CullingMask:
serializedVersion: 2 serializedVersion: 2
@ -452,13 +522,44 @@ Transform:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225} m_GameObject: {fileID: 963194225}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 100, z: 0} m_LocalPosition: {x: 0, y: 3, z: -20}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &963194229
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 963194225}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_RenderPostProcessing: 0
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
--- !u!1 &1276070527 --- !u!1 &1276070527
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -768,7 +869,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 3 m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!43 &1414717757 --- !u!43 &1414717757
Mesh: Mesh:
@ -1097,7 +1198,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 2 m_RootOrder: 3
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1896072346 --- !u!1 &1896072346
GameObject: GameObject:
@ -1408,7 +1509,7 @@ Transform:
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 4 m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!43 &1913054165 --- !u!43 &1913054165
Mesh: Mesh:

View File

@ -31,13 +31,14 @@ public class MovingSphere : MonoBehaviour
private Vector3 desiredVelocity = new Vector3(0f, 0f, 0f); private Vector3 desiredVelocity = new Vector3(0f, 0f, 0f);
private bool desiredJump = false; private bool desiredJump = false;
private int groundContactCount;
private bool onGround => groundContactCount > 0;
private int jumpPhase; private int jumpPhase;
private Vector3 velocity; private Vector3 velocity;
private Vector3 contactNormal; private Vector3 contactNormal, steepNormal;
private int groundContactCount, steepContactCount;
private float minGroundDotProduct, minStairsDotProduct; private float minGroundDotProduct, minStairsDotProduct;
private int stepsSinceLastGrounded, stepsSinceLastJump; private int stepsSinceLastGrounded, stepsSinceLastJump;
private bool onGround => groundContactCount > 0;
private bool onSteep => steepContactCount > 0;
private float GetMinDot(int layer) private float GetMinDot(int layer)
{ {
@ -94,10 +95,13 @@ public class MovingSphere : MonoBehaviour
stepsSinceLastGrounded++; stepsSinceLastGrounded++;
stepsSinceLastJump++; stepsSinceLastJump++;
velocity = body.velocity; velocity = body.velocity;
if (onGround || SnapToGround()) if (onGround || SnapToGround() || CheckSteepContacts())
{ {
jumpPhase = 0;
stepsSinceLastGrounded = 0; stepsSinceLastGrounded = 0;
if (stepsSinceLastJump > 1)
{
jumpPhase = 0;
}
if (groundContactCount > 1) if (groundContactCount > 1)
{ {
contactNormal.Normalize(); contactNormal.Normalize();
@ -130,23 +134,51 @@ public class MovingSphere : MonoBehaviour
groundContactCount += 1; groundContactCount += 1;
contactNormal += normal; contactNormal += normal;
} }
else if (normal.y > -0.01f)
{
steepContactCount += 1;
steepNormal += normal;
}
} }
} }
private void Jump() private void Jump()
{ {
if (onGround || jumpPhase < maxAirJumps) Vector3 jumpDirection;
if (onGround)
{ {
stepsSinceLastJump = 0; jumpDirection = contactNormal;
jumpPhase++;
float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
float alignedSpeed = Vector3.Dot(velocity, contactNormal);
if (alignedSpeed > 0f)
{
jumpSpeed = Mathf.Max(jumpSpeed - alignedSpeed, 0f);
}
velocity += contactNormal * jumpSpeed;
} }
else if (onSteep)
{
jumpDirection = steepNormal;
jumpPhase = 0;
}
else if (maxAirJumps > 0 && jumpPhase <= maxAirJumps)
{
if (jumpPhase == 0)
{
jumpPhase = 1;
}
jumpDirection = contactNormal;
}
else
{
return;
}
stepsSinceLastJump = 0;
jumpPhase++;
float jumpSpeed = Mathf.Sqrt(-2f * Physics.gravity.y * jumpHeight);
jumpDirection = (jumpDirection + Vector3.up).normalized;
float alignedSpeed = Vector3.Dot(velocity, jumpDirection);
if (alignedSpeed > 0f)
{
jumpSpeed = Mathf.Max(jumpSpeed - alignedSpeed, 0f);
}
velocity += jumpDirection * jumpSpeed;
} }
private void AdjustVelocity() private void AdjustVelocity()
@ -175,8 +207,8 @@ public class MovingSphere : MonoBehaviour
private void ClearState() private void ClearState()
{ {
groundContactCount = 0; groundContactCount = steepContactCount = 0;
contactNormal = Vector3.zero; contactNormal = steepNormal = Vector3.zero;
} }
private bool SnapToGround() private bool SnapToGround()
@ -208,4 +240,19 @@ public class MovingSphere : MonoBehaviour
} }
return true; return true;
} }
bool CheckSteepContacts()
{
if (steepContactCount > 1)
{
steepNormal.Normalize();
if (steepNormal.y >= minGroundDotProduct)
{
groundContactCount = 1;
contactNormal = steepNormal;
return true;
}
}
return false;
}
} }