remove crawling and swimming states

This commit is contained in:
mischa 2023-12-13 16:31:07 +01:00
parent 0790b99007
commit 2b3d8a5583
3 changed files with 227 additions and 293 deletions

View File

@ -43,9 +43,13 @@ GameObject:
- component: {fileID: 5494952544308740964}
- component: {fileID: 5494952544308740967}
- component: {fileID: 5494952544308740966}
- component: {fileID: 5494952544308740984}
- component: {fileID: -3946790939204706219}
- component: {fileID: 5494952544308740987}
- component: {fileID: -1369090521221337779}
- component: {fileID: -6612530066273007424}
- component: {fileID: -8494711255715996189}
- component: {fileID: -1774763014265066545}
- component: {fileID: -8650763063470423008}
m_Layer: 0
m_Name: Player
m_TagString: Untagged
@ -137,24 +141,102 @@ MeshRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!143 &5494952544308740984
CharacterController:
--- !u!82 &-3946790939204706219
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5494952544308740986}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Height: 2
m_Radius: 0.5
m_SlopeLimit: 45
m_StepOffset: 0.3
m_SkinWidth: 0.08
m_MinMoveDistance: 0.001
m_Center: {x: 0, y: 0, z: 0}
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_PlayOnAwake: 1
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!54 &5494952544308740987
Rigidbody:
m_ObjectHideFlags: 0
@ -166,11 +248,25 @@ Rigidbody:
m_Mass: 1
m_Drag: 0
m_AngularDrag: 0.05
m_UseGravity: 1
m_UseGravity: 0
m_IsKinematic: 1
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 1
--- !u!136 &-1369090521221337779
CapsuleCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5494952544308740986}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
m_Radius: 0.5
m_Height: 2
m_Direction: 1
m_Center: {x: 0, y: 0, z: 0}
--- !u!114 &-6612530066273007424
MonoBehaviour:
m_ObjectHideFlags: 0
@ -187,3 +283,119 @@ MonoBehaviour:
syncMode: 0
syncInterval: 0
cameraMount: {fileID: 5741080586963324589}
--- !u!114 &-8494711255715996189
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5494952544308740986}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f380ddcf720745159256fd28850e60b, type: 3}
m_Name:
m_EditorClassIdentifier:
movement: {fileID: 0}
XSensitivity: 2
YSensitivity: 2
MinimumX: -90
MaximumX: 90
firstPersonParent: {fileID: 0}
freeLookParent: {fileID: 0}
freeLookKey: 308
viewBlockingLayers:
serializedVersion: 2
m_Bits: 0
zoomSpeed: 0.5
distance: 0
minDistance: 0
maxDistance: 7
raycastLayers:
serializedVersion: 2
m_Bits: 4294967291
firstPersonOffsetStanding: {x: 0, y: 0}
thirdPersonOffsetStanding: {x: 0, y: 1}
thirdPersonOffsetStandingMultiplier: {x: 0, y: 0}
firstPersonOffsetCrouching: {x: 0, y: 0}
thirdPersonOffsetCrouching: {x: 0, y: 0.5}
thirdPersonOffsetCrouchingMultiplier: {x: 0, y: 0}
crouchOriginMultiplier: 0.65
--- !u!114 &-1774763014265066545
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5494952544308740986}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 29d02e23dd78c434baee064aae1caed9, type: 3}
m_Name:
m_EditorClassIdentifier:
playerRootTransform: {fileID: 0}
rootTransformOffset: {x: 0, y: 0, z: 0}
slopeLimit: 45
stepOffset: 0.3
skinWidth: 0.08
groundedTestDistance: 0.002
center: {x: 0, y: 0, z: 0}
radius: 0.5
height: 2
collisionLayerMask:
serializedVersion: 2
m_Bits: 4294967295
isLocalHuman: 1
slideAlongCeiling: 1
slowAgainstWalls: 0
minSlowAgainstWallsAngle: 10
triggerQuery: 1
slideDownSlopes: 1
slideMaxSpeed: 10
slideGravityMultiplier: 1
slideStartDelay: 0.1
slideStopDelay: 0.1
--- !u!114 &-8650763063470423008
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 5494952544308740986}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4ab763efbf7234d96aedc8f08d29df1f, type: 3}
m_Name:
m_EditorClassIdentifier:
animator: {fileID: 0}
controller: {fileID: 0}
feetAudio: {fileID: 0}
look: {fileID: 0}
controllerCollider: {fileID: 0}
state: 0
moveDir: {x: 0, y: 0, z: 0}
rotationSpeed: 150
walkSpeed: 5
walkAcceleration: 15
walkDeceleration: 20
runSpeed: 8
runStepLength: 0.7
runStepInterval: 3
runCycleLegOffset: 0.2
runKey: 304
crouchSpeed: 1.5
crouchAcceleration: 5
crouchDeceleration: 10
crouchKey: 99
jumpSpeed: 7
jumpLeg: 0
airborneAcceleration: 15
airborneDeceleration: 20
fallMinimumMagnitude: 9
fallDamageMinimumMagnitude: 13
fallDamageMultiplier: 2
lastFall: {x: 0, y: 0, z: 0}
climbSpeed: 3
gravityMultiplier: 2
footstepSounds: []
jumpSound: {fileID: 0}
landSound: {fileID: 0}

View File

@ -56,22 +56,6 @@ public class PlayerLook : MonoBehaviour
// zooming out puts camera target slightly above head for easier aiming
public float crouchOriginMultiplier = 0.65f;
[Header("Offsets - Crawling")]
public Vector2 firstPersonOffsetCrawling = Vector2.zero;
public Vector2 thirdPersonOffsetCrawling = Vector2.up;
public Vector2 thirdPersonOffsetCrawlingMultiplier = Vector2.zero;
// scale offset by distance so that 100% zoom in = first person and
// zooming out puts camera target slightly above head for easier aiming
public float crawlOriginMultiplier = 0.65f;
[Header("Offsets - Swimming")]
public Vector2 firstPersonOffsetSwimming = Vector2.zero;
public Vector2 thirdPersonOffsetSwimming = Vector2.up;
public Vector2 thirdPersonOffsetSwimmingMultiplier = Vector2.zero;
// scale offset by distance so that 100% zoom in = first person and
// zooming out puts camera target slightly above head for easier aiming
public float swimOriginMultiplier = 0.65f;
// look directions /////////////////////////////////////////////////////////
// * for first person, all we need is the camera.forward
//
@ -240,16 +224,6 @@ void LateUpdate()
origin = headLocal * crouchOriginMultiplier;
offset = firstPersonOffsetCrouching;
}
else if (movement.state == MoveState.CRAWLING)
{
origin = headLocal * crawlOriginMultiplier;
offset = firstPersonOffsetCrawling;
}
else if (movement.state == MoveState.SWIMMING)
{
origin = headLocal;
offset = firstPersonOffsetSwimming;
}
else
{
origin = headLocal;
@ -272,18 +246,6 @@ void LateUpdate()
offsetBase = thirdPersonOffsetCrouching;
offsetMult = thirdPersonOffsetCrouchingMultiplier;
}
else if (movement.state == MoveState.CRAWLING)
{
origin = originalCameraPosition * crawlOriginMultiplier;
offsetBase = thirdPersonOffsetCrawling;
offsetMult = thirdPersonOffsetCrawlingMultiplier;
}
else if (movement.state == MoveState.SWIMMING)
{
origin = originalCameraPosition * swimOriginMultiplier;
offsetBase = thirdPersonOffsetSwimming;
offsetMult = thirdPersonOffsetSwimmingMultiplier;
}
else
{
origin = originalCameraPosition;

View File

@ -8,7 +8,7 @@ namespace Mirror.Examples.Shooter
// MoveState as byte for minimal bandwidth (otherwise it's int by default)
// note: distinction between WALKING and RUNNING in case we need to know the
// difference somewhere (e.g. for endurance recovery)
public enum MoveState : byte {IDLE, WALKING, RUNNING, CROUCHING, CRAWLING, AIRBORNE, CLIMBING, SWIMMING}
public enum MoveState : byte {IDLE, WALKING, RUNNING, CROUCHING, AIRBORNE, CLIMBING}
[RequireComponent(typeof(CharacterController2k))]
[RequireComponent(typeof(AudioSource))]
@ -58,24 +58,6 @@ public class PlayerMovement : MonoBehaviour
public KeyCode crouchKey = KeyCode.C;
bool crouchKeyPressed;
[Header("Crawling")]
public float crawlSpeed = 1;
public float crawlAcceleration = 5; // set to maxint for instant speed
public float crawlDeceleration = 10; // feels best if higher than acceleration
public KeyCode crawlKey = KeyCode.V;
bool crawlKeyPressed;
[Header("Swimming")]
public float swimSpeed = 4;
public float swimAcceleration = 15; // set to maxint for instant speed
public float swimDeceleration = 20; // feels best if higher than acceleration
public float swimSurfaceOffset = 0.25f;
Collider waterCollider;
bool inWater => waterCollider != null; // standing in water / touching it?
bool underWater; // deep enough in water so we need to swim?
[Range(0, 1)] public float underwaterThreshold = 0.9f; // percent of body that need to be underwater to start swimming
public LayerMask canStandInWaterCheckLayers = Physics.DefaultRaycastLayers; // set this to everything except water layer
[Header("Jumping")]
public float jumpSpeed = 7;
[HideInInspector] public float jumpLeg;
@ -94,11 +76,6 @@ public class PlayerMovement : MonoBehaviour
public float climbSpeed = 3;
Collider ladderCollider;
[Header("Mounted")]
public float mountedRotationSpeed = 100;
public float mountedAcceleration = 15; // set to maxint for instant speed
public float mountedDeceleration = 20; // feels best if higher than acceleration
[Header("Physics")]
public float gravityMultiplier = 2;
@ -159,11 +136,6 @@ bool EventCrouchToggle()
return crouchKeyPressed;
}
bool EventCrawlToggle()
{
return crawlKeyPressed;
}
bool EventFalling()
{
// use minimum fall magnitude so walking down steps isn't detected as
@ -177,27 +149,6 @@ bool EventLanded()
return controller.isGrounded;
}
bool EventUnderWater()
{
// we can't really make it player position dependent, because he might
// swim to the surface at which point it might be detected as standing
// in water but not being under water, etc.
if (inWater) // in water and valid water collider?
{
// raycasting from water to the bottom at the position of the player
// seems like a very precise solution
Vector3 origin = new Vector3(transform.position.x,
waterCollider.bounds.max.y,
transform.position.z);
float distance = controllerCollider.height * underwaterThreshold;
Debug.DrawLine(origin, origin + Vector3.down * distance, Color.cyan);
// we are underwater if the raycast doesn't hit anything
return !Utils.RaycastWithout(origin, Vector3.down, out RaycastHit hit, distance, gameObject, canStandInWaterCheckLayers);
}
return false;
}
bool EventLadderEnter()
{
return ladderCollider != null;
@ -310,23 +261,11 @@ MoveState UpdateIDLE(Vector2 inputDir, Vector3 desiredDir)
if (controller.TrySetHeight(controller.defaultHeight * 0.5f, true, true, false))
return MoveState.CROUCHING;
}
else if (EventCrawlToggle())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
return MoveState.CRAWLING;
}
else if (EventLadderEnter())
{
EnterLadder();
return MoveState.CLIMBING;
}
else if (EventUnderWater())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
return MoveState.SWIMMING;
}
else if (inputDir != Vector2.zero)
{
return MoveState.WALKING;
@ -374,28 +313,11 @@ MoveState UpdateWALKINGandRUNNING(Vector2 inputDir, Vector3 desiredDir)
return MoveState.CROUCHING;
}
}
else if (EventCrawlToggle())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
{
// limit speed to crawl speed so we don't decelerate from run speed
// to crawl speed (hence crawling too fast for a short time)
horizontalSpeed = Mathf.Min(horizontalSpeed, crawlSpeed);
return MoveState.CRAWLING;
}
}
else if (EventLadderEnter())
{
EnterLadder();
return MoveState.CLIMBING;
}
else if (EventUnderWater())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
return MoveState.SWIMMING;
}
// go to idle after fully decelerating (y doesn't matter)
else if (moveDir.x == 0 && moveDir.z == 0)
{
@ -445,17 +367,6 @@ MoveState UpdateCROUCHING(Vector2 inputDir, Vector3 desiredDir)
return MoveState.IDLE;
}
}
else if (EventCrawlToggle())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
{
// limit speed to crawl speed so we don't decelerate from run speed
// to crawl speed (hence crawling too fast for a short time)
horizontalSpeed = Mathf.Min(horizontalSpeed, crawlSpeed);
return MoveState.CRAWLING;
}
}
else if (EventLadderEnter())
{
// rescale capsule if possible
@ -465,91 +376,11 @@ MoveState UpdateCROUCHING(Vector2 inputDir, Vector3 desiredDir)
return MoveState.CLIMBING;
}
}
else if (EventUnderWater())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
{
return MoveState.SWIMMING;
}
}
ProgressStepCycle(inputDir, crouchSpeed);
return MoveState.CROUCHING;
}
MoveState UpdateCRAWLING(Vector2 inputDir, Vector3 desiredDir)
{
// QE key rotation
RotateWithKeys();
// move with acceleration (feels better)
horizontalSpeed = AccelerateSpeed(inputDir, horizontalSpeed, crawlSpeed, inputDir != Vector2.zero ? crawlAcceleration : crawlDeceleration);
moveDir.x = desiredDir.x * horizontalSpeed;
moveDir.y = ApplyGravity(moveDir.y);
moveDir.z = desiredDir.z * horizontalSpeed;
if (EventFalling())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
sprintingBeforeAirborne = false;
return MoveState.AIRBORNE;
}
}
else if (EventJumpRequested())
{
// stop crawling when pressing jump key. this feels better than
// jumping from the crawling state.
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
return MoveState.IDLE;
}
}
else if (EventCrouchToggle())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 0.5f, true, true, false))
{
// limit speed to crouch speed so we don't decelerate from run speed
// to crouch speed (hence crouching too fast for a short time)
horizontalSpeed = Mathf.Min(horizontalSpeed, crouchSpeed);
return MoveState.CROUCHING;
}
}
else if (EventCrawlToggle())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
return MoveState.IDLE;
}
}
else if (EventLadderEnter())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
EnterLadder();
return MoveState.CLIMBING;
}
}
else if (EventUnderWater())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
{
return MoveState.SWIMMING;
}
}
ProgressStepCycle(inputDir, crawlSpeed);
return MoveState.CRAWLING;
}
MoveState UpdateAIRBORNE(Vector2 inputDir, Vector3 desiredDir)
{
// QE key rotation
@ -577,14 +408,6 @@ MoveState UpdateAIRBORNE(Vector2 inputDir, Vector3 desiredDir)
EnterLadder();
return MoveState.CLIMBING;
}
else if (EventUnderWater())
{
// rescale capsule
if (controller.TrySetHeight(controller.defaultHeight * 0.25f, true, true, false))
{
return MoveState.SWIMMING;
}
}
return MoveState.AIRBORNE;
}
@ -617,53 +440,10 @@ MoveState UpdateCLIMBING(Vector2 inputDir, Vector3 desiredDir)
return MoveState.CLIMBING;
}
MoveState UpdateSWIMMING(Vector2 inputDir, Vector3 desiredDir)
{
// ladder under / above water?
if (EventLadderEnter())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
EnterLadder();
return MoveState.CLIMBING;
}
}
// not under water anymore?
else if (!EventUnderWater())
{
// rescale capsule if possible
if (controller.TrySetHeight(controller.defaultHeight * 1f, true, true, false))
{
return MoveState.IDLE;
}
}
// QE key rotation
RotateWithKeys();
// move with acceleration (feels better)
horizontalSpeed = AccelerateSpeed(inputDir, horizontalSpeed, swimSpeed, inputDir != Vector2.zero ? swimAcceleration : swimDeceleration);
moveDir.x = desiredDir.x * horizontalSpeed;
moveDir.z = desiredDir.z * horizontalSpeed;
// gravitate toward surface
if (waterCollider != null)
{
float surface = waterCollider.bounds.max.y;
float surfaceDirection = surface - controller.bounds.min.y - swimSurfaceOffset;
moveDir.y = surfaceDirection * swimSpeed;
}
else moveDir.y = 0;
return MoveState.SWIMMING;
}
// use Update to check Input
void Update()
{
if (!jumpKeyPressed) jumpKeyPressed = Input.GetButtonDown("Jump");
if (!crawlKeyPressed) crawlKeyPressed = Input.GetKeyDown(crawlKey);
if (!crouchKeyPressed) crouchKeyPressed = Input.GetKeyDown(crouchKey);
}
@ -682,10 +462,8 @@ void FixedUpdate()
else if (state == MoveState.WALKING) state = UpdateWALKINGandRUNNING(inputDir, desiredDir);
else if (state == MoveState.RUNNING) state = UpdateWALKINGandRUNNING(inputDir, desiredDir);
else if (state == MoveState.CROUCHING) state = UpdateCROUCHING(inputDir, desiredDir);
else if (state == MoveState.CRAWLING) state = UpdateCRAWLING(inputDir, desiredDir);
else if (state == MoveState.AIRBORNE) state = UpdateAIRBORNE(inputDir, desiredDir);
else if (state == MoveState.CLIMBING) state = UpdateCLIMBING(inputDir, desiredDir);
else if (state == MoveState.SWIMMING) state = UpdateSWIMMING(inputDir, desiredDir);
else Debug.LogError("Unhandled Movement State: " + state);
// cache this move's state to detect landing etc. next time
@ -703,7 +481,6 @@ void FixedUpdate()
// reset keys no matter what
jumpKeyPressed = false;
crawlKeyPressed = false;
crouchKeyPressed = false;
}
@ -776,22 +553,5 @@ void PlayFootStepAudio()
footstepSounds[n] = footstepSounds[0];
footstepSounds[0] = feetAudio.clip;
}
void OnTriggerEnter(Collider co)
{
// touching ladder? then set ladder collider
if (co.CompareTag("Ladder"))
ladderCollider = co;
// touching water? then set water collider
else if (co.CompareTag("Water"))
waterCollider = co;
}
void OnTriggerExit(Collider co)
{
// not touching water anymore? then clear water collider
if (co.CompareTag("Water"))
waterCollider = null;
}
}
}