SockSteve

Godot 3D Crouch

Jul 16th, 2024
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Godot GLSL 6.09 KB | Source Code | 0 0
  1. CrouchCharacter_1
  2. Scene_tree
  3. https://pasteboard.co/26gm9Ut5Xgj6.png
  4.  
  5.  
  6.  
  7. CharacterBody3d Script:
  8.  
  9. '''
  10. extends CharacterBody3D
  11.  
  12. const SPEED = 5.0
  13. const JUMP_VELOCITY = 4.5
  14.  
  15. #set the crouch component
  16. @export var crouch_component: CrouchComponent
  17.  
  18. # Get the gravity from the project settings to be synced with RigidBody nodes.
  19. var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
  20.  
  21.  
  22. func _physics_process(delta):
  23.     # Add the gravity.
  24.     if not is_on_floor():
  25.         velocity.y -= gravity * delta
  26.  
  27.     # Handle crouch.
  28.     crouch_component.can_uncrouch = not move_and_collide(crouch_component.grow_dir + Vector3(0,.2,0),true)
  29.  
  30.     # Handle jump.
  31.     if Input.is_action_just_pressed("ui_accept") and is_on_floor():
  32.         velocity.y = JUMP_VELOCITY
  33.  
  34.     # Get the input direction and handle the movement/deceleration.
  35.     # As good practice, you should replace UI actions with custom gameplay actions.
  36.     var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
  37.     var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
  38.     if direction:
  39.         velocity.x = direction.x * SPEED
  40.         velocity.z = direction.z * SPEED
  41.     else:
  42.         velocity.x = move_toward(velocity.x, 0, SPEED)
  43.         velocity.z = move_toward(velocity.z, 0, SPEED)
  44.  
  45.     move_and_slide()
  46. '''
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53. CrouchComponent Script:
  54.  
  55. '''
  56. extends Node3D
  57. class_name CrouchComponent
  58.  
  59. const CROUCH_SPEED: float = 0.1
  60. const MIN_HEIGHT: float = 0.2
  61.  
  62. @export var capsule_or_cylinder_collision_shape: CollisionShape3D
  63. @export var mesh_instance: MeshInstance3D
  64. @export var print_debug: bool = false
  65.  
  66. @onready var collision_max_height = capsule_or_cylinder_collision_shape.shape.height
  67. @onready var mesh_max_height = mesh_instance.mesh.height
  68.  
  69. var crouching: bool = false
  70. var can_uncrouch: bool = true
  71.  
  72. var grow_dir: Vector3 = Vector3.ZERO
  73.  
  74. func _process(delta):
  75.     if print_debug: print(grow_dir)
  76.    
  77.     if Input.is_action_pressed("crouch"):
  78.         crouching = true
  79.     else:
  80.         crouching = false
  81.    
  82.     if crouching:
  83.         decrease_height()
  84.         return
  85.    
  86.     if can_uncrouch:
  87.         increase_height()
  88.         grow_dir = Vector3.ZERO
  89.         return
  90.  
  91. # Function to set the height of the capsule shape
  92. func set_capsule_height(collision_height: float, mesh_height: float) -> void:
  93.     # Set the height of the capsule shape
  94.     collision_height = clamp(collision_height,MIN_HEIGHT, collision_max_height)
  95.     mesh_height = clamp(mesh_height,MIN_HEIGHT, mesh_max_height)
  96.    
  97.     capsule_or_cylinder_collision_shape.shape.height = collision_height
  98.     mesh_instance.mesh.height = mesh_height
  99.  
  100.     # Adjust the position to ensure it grows from the bottom
  101.     var parent_position = capsule_or_cylinder_collision_shape.position
  102.     parent_position.y = collision_height / 2.0
  103.     capsule_or_cylinder_collision_shape.position = parent_position
  104.    
  105.     var mesh_parent_position = mesh_instance.position
  106.     mesh_parent_position.y = mesh_height / 2.0
  107.     mesh_instance.position = mesh_parent_position
  108.  
  109. # Example function to increase the height
  110. func increase_height() -> void:
  111.     var new_collision_height = capsule_or_cylinder_collision_shape.shape.height + CROUCH_SPEED
  112.     var new_mesh_height = mesh_instance.mesh.height + CROUCH_SPEED
  113.     set_capsule_height(new_collision_height, new_mesh_height)
  114.     # The CROUCH_SPEED is multiplicated with 2 because we cant to test the future grow direction
  115.     # for collision. otherwise the objects collision would bump into the ceiling an is unable to move
  116.     grow_dir = Vector3(0,CROUCH_SPEED * 2, 0)
  117.  
  118. # Example function to decrease the height
  119. func decrease_height() -> void:
  120.     var new_collision_height = capsule_or_cylinder_collision_shape.shape.height - CROUCH_SPEED # Ensure height does not go below 1
  121.     var new_mesh_height = mesh_instance.mesh.height - CROUCH_SPEED
  122.     set_capsule_height(new_collision_height, new_mesh_height)
  123.  
  124. '''
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. CrouchCharacter_2
  140. Scene_tree
  141. https://pasteboard.co/8cI6hl3dhibv.png
  142.  
  143. CharacterBody3d Script:
  144.  
  145. '''
  146. extends CharacterBody3D
  147.  
  148.  
  149. const SPEED = 5.0
  150. const JUMP_VELOCITY = 4.5
  151. const CROUCH_SPEED: float = 2
  152. const MIN_SCALE_Y: float = 0.2
  153. const MAX_SCALE_Y: float = 1.0
  154.  
  155. @export var root: Marker3D
  156.  
  157. # Get the gravity from the project settings to be synced with RigidBody nodes.
  158. var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
  159.  
  160. func _physics_process(delta):
  161.     # Add the gravity.
  162.     if not is_on_floor():
  163.         velocity.y -= gravity * delta
  164.  
  165.     # Handle jump.
  166.     if Input.is_action_just_pressed("ui_accept") and is_on_floor():
  167.         velocity.y = JUMP_VELOCITY
  168.  
  169.     # Get the input direction and handle the movement/deceleration.
  170.     # As good practice, you should replace UI actions with custom gameplay actions.
  171.     var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
  172.     var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
  173.     if direction:
  174.         velocity.x = direction.x * SPEED
  175.         velocity.z = direction.z * SPEED
  176.     else:
  177.         velocity.x = move_toward(velocity.x, 0, SPEED)
  178.         velocity.z = move_toward(velocity.z, 0, SPEED)
  179.    
  180.     handle_crouch()
  181.     move_and_slide()
  182.  
  183. func handle_crouch():
  184.     var delta_time = get_process_delta_time()
  185.     var is_crouching = Input.is_action_pressed("crouch")
  186.  
  187.     if is_crouching:
  188.         # Crouch: Decrease the scale.y value gradually
  189.         root.scale.y -= CROUCH_SPEED * delta_time
  190.         root.scale.y = clamp(root.scale.y, MIN_SCALE_Y, MAX_SCALE_Y)
  191.     else:
  192.         # Uncrouch: Increase the scale.y value gradually, but check for collisions
  193.         var new_scale_y = min(MAX_SCALE_Y, root.scale.y + CROUCH_SPEED * delta_time)
  194.        
  195.         # Temporarily update the scale for collision checking
  196.         var original_scale_y = root.scale.y
  197.         root.scale.y = new_scale_y
  198.        
  199.         # Use a small upward velocity for collision checking
  200.         var _velocity = Vector3(0, 0.1, 0)
  201.         # we don't want to move with move_and_collide so we set 'test_collision' to true
  202.         var collision = move_and_collide(_velocity * delta_time, true)
  203.        
  204.         if collision:
  205.             # If there is a collision, revert the scale
  206.             root.scale.y = original_scale_y
  207.         else:
  208.             # If no collision, apply the new scale
  209.             root.scale.y = new_scale_y
  210.  
  211.     # Ensure the scale is within bounds
  212.     root.scale.y = clamp(root.scale.y, MIN_SCALE_Y, MAX_SCALE_Y)
  213. '''
Tags: godot4 Crouch
Advertisement
Add Comment
Please, Sign In to add comment