Format existing scripts
This commit is contained in:
		
							parent
							
								
									18a4b02c3e
								
							
						
					
					
						commit
						644df0bd80
					
				|  | @ -1,7 +1,8 @@ | |||
| class_name DampenedCamera3D extends Camera3D | ||||
| 
 | ||||
| @export var target : Node3D | ||||
| @export var damping : bool | ||||
| @export var target: Node3D | ||||
| @export var damping: bool | ||||
| 
 | ||||
| 
 | ||||
| # Called when the node enters the scene tree for the first time. | ||||
| func _ready() -> void: | ||||
|  | @ -24,8 +25,10 @@ func _process(delta: float) -> void: | |||
| 	target_pos.y = lerp(global_position.y, target_pos.y, 20 * delta) | ||||
| 	global_position = target_pos | ||||
| 
 | ||||
| 
 | ||||
| func damp() -> void: | ||||
| 	damping = true | ||||
| 
 | ||||
| 
 | ||||
| func donmp() -> void: | ||||
| 	damping = false | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ extends PhysicsBody3D | |||
| 
 | ||||
| ## The character will be blocked from moving up slopes steeper than this angle | ||||
| ## The character will be not be flagged as 'grounded' when stood on slopes steeper than this angle | ||||
| @export var slope_limit : float = 45 | ||||
| @export var slope_limit: float = 45 | ||||
| 
 | ||||
| ## The character will automatically adjust height to step over obstacles this high | ||||
| @export var step_height := 0.2 | ||||
|  | @ -17,13 +17,13 @@ extends PhysicsBody3D | |||
| @export var snap_to_ground_distance := 0.2 | ||||
| 
 | ||||
| @export_group("Connector Nodes") | ||||
| @export var head : Node3D | ||||
| @export var body : Node3D | ||||
| @export var camera : DampenedCamera3D | ||||
| @export var head: Node3D | ||||
| @export var body: Node3D | ||||
| @export var camera: DampenedCamera3D | ||||
| 
 | ||||
| ## A reference to the collision shape this physics body is using | ||||
| ## (It's just a bit easier rather than aquiring the reference via code) | ||||
| @export var collision_shape : CollisionShape3D | ||||
| @export var collision_shape: CollisionShape3D | ||||
| 
 | ||||
| @export_group("Advanced") | ||||
| ## Stop movement under this distance, but only if the movement touches at least 2 steep slopes | ||||
|  | @ -60,37 +60,38 @@ extends PhysicsBody3D | |||
| ## accurate. 4 is a decent number for low poly terrain! | ||||
| @export var max_iteration_count := 4 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| var jump_pressed := false | ||||
| 
 | ||||
| var gravity := 9.8 | ||||
| 
 | ||||
| var _velocity: Vector3 = Vector3() | ||||
| var at_max_speed: bool = true | ||||
| 
 | ||||
| var _velocity : Vector3 = Vector3() | ||||
| var at_max_speed : bool = true | ||||
| var grounded: bool = false | ||||
| var ground_normal: Vector3 | ||||
| var steep_slope_normals: Array[Vector3] = [] | ||||
| var total_stepped_height: float = 0 | ||||
| 
 | ||||
| var grounded : bool = false | ||||
| var ground_normal : Vector3 | ||||
| var steep_slope_normals : Array[Vector3]  = [] | ||||
| var total_stepped_height : float = 0 | ||||
| var escape_pressed: int | ||||
| var vertical_collisions: Array[KinematicCollision3D] | ||||
| var lateral_collisions: Array[KinematicCollision3D] | ||||
| var snap_collisions: Array[KinematicCollision3D] | ||||
| 
 | ||||
| var escape_pressed : int | ||||
| var vertical_collisions : Array[KinematicCollision3D] | ||||
| var lateral_collisions : Array[KinematicCollision3D] | ||||
| var snap_collisions : Array[KinematicCollision3D] | ||||
| enum MovementType { VERTICAL, LATERAL } | ||||
| 
 | ||||
| enum MovementType {VERTICAL, LATERAL} | ||||
| 
 | ||||
| func _ready() -> void: | ||||
| 	lock_mouse() | ||||
| 
 | ||||
| 
 | ||||
| func lock_mouse() -> void: | ||||
| 	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED | ||||
| 
 | ||||
| 
 | ||||
| func unlock_mouse() -> void: | ||||
| 	Input.mouse_mode = Input.MOUSE_MODE_VISIBLE | ||||
| 
 | ||||
| 
 | ||||
| # TODO should this have an action associated? | ||||
| # TODO should it be in unhandled? | ||||
| func _input(event: InputEvent) -> void: | ||||
|  | @ -100,6 +101,7 @@ func _input(event: InputEvent) -> void: | |||
| 		head.rotate_x(-motion.relative.y * mouse_sensitivity) | ||||
| 		head.rotation.x = clamp(head.rotation.x, -1.4, 1.4) | ||||
| 
 | ||||
| 
 | ||||
| # TODO should this be in unhandled input? | ||||
| # Input buffering? lol lmao | ||||
| func get_input() -> Vector2: | ||||
|  | @ -117,12 +119,12 @@ func get_input() -> Vector2: | |||
| 	jump_pressed = Input.is_action_just_pressed("cc_jump") | ||||
| 
 | ||||
| 	if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED: | ||||
| 		return Vector2(0,0) | ||||
| 		return Vector2(0, 0) | ||||
| 
 | ||||
| 	if Input.is_action_just_pressed("cc_sprint"): | ||||
| 		at_max_speed = !at_max_speed | ||||
| 
 | ||||
| 	var input_dir : Vector2 = Vector2() | ||||
| 	var input_dir: Vector2 = Vector2() | ||||
| 	if Input.is_action_pressed("cc_forward"): | ||||
| 		input_dir += Vector2.UP | ||||
| 	if Input.is_action_pressed("cc_backward"): | ||||
|  | @ -136,6 +138,7 @@ func get_input() -> Vector2: | |||
| 	# Local rotation is fine given the parent isn't rotating ever | ||||
| 	return input_dir.rotated(-body.rotation.y) | ||||
| 
 | ||||
| 
 | ||||
| func _physics_process(delta: float) -> void: | ||||
| 	# Before Move | ||||
| 	var _desired_horz_velocity := get_input() | ||||
|  | @ -164,7 +167,7 @@ func _physics_process(delta: float) -> void: | |||
| 
 | ||||
| 
 | ||||
| # Entry point to moving | ||||
| func move(intended_velocity : Vector3, delta : float) -> void: | ||||
| func move(intended_velocity: Vector3, delta: float) -> void: | ||||
| 	var start_position := position | ||||
| 
 | ||||
| 	var lateral_translation := horz(intended_velocity * delta) | ||||
|  | @ -183,29 +186,45 @@ func move(intended_velocity : Vector3, delta : float) -> void: | |||
| 	# An initial grounded check is important because ground normal is used | ||||
| 	# to detect seams with steep slopes; which often are collided with before the ground | ||||
| 	if vertical_translation.y <= 0: | ||||
| 		var initial_grounded_collision := move_and_collide(Vector3.DOWN * ground_cast_distance, true, depenetration_margin) | ||||
| 		var initial_grounded_collision := move_and_collide( | ||||
| 			Vector3.DOWN * ground_cast_distance, true, depenetration_margin | ||||
| 		) | ||||
| 		if initial_grounded_collision: | ||||
| 			if initial_grounded_collision.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit): | ||||
| 			if ( | ||||
| 				initial_grounded_collision.get_normal(0).angle_to(Vector3.UP) | ||||
| 				< deg_to_rad(slope_limit) | ||||
| 			): | ||||
| 				grounded = true | ||||
| 				ground_normal = initial_grounded_collision.get_normal(0) | ||||
| 
 | ||||
| 	# === Iterate Movement Laterally | ||||
| 	var lateral_iterations := 0 | ||||
| 	while lateral_translation.length() > 0 and lateral_iterations < max_iteration_count: | ||||
| 
 | ||||
| 		lateral_translation = move_iteration(MovementType.LATERAL, lateral_collisions, initial_lateral_translation, lateral_translation) | ||||
| 		lateral_translation = move_iteration( | ||||
| 			MovementType.LATERAL, | ||||
| 			lateral_collisions, | ||||
| 			initial_lateral_translation, | ||||
| 			lateral_translation | ||||
| 		) | ||||
| 		lateral_iterations += 1 | ||||
| 
 | ||||
| 		# De-jitter by just ignoring lateral movement | ||||
| 		# (multiple steep slopes have been collided, but movement is very small) | ||||
| 		if steep_slope_normals.size() > 1 and horz(position - start_position).length() < steep_slope_jitter_reduce: | ||||
| 		if ( | ||||
| 			steep_slope_normals.size() > 1 | ||||
| 			and horz(position - start_position).length() < steep_slope_jitter_reduce | ||||
| 		): | ||||
| 			position = start_position | ||||
| 
 | ||||
| 	# === Iterate Movement Vertically | ||||
| 	var vertical_iterations := 0 | ||||
| 	while vertical_translation.length() > 0 and vertical_iterations < max_iteration_count: | ||||
| 
 | ||||
| 		vertical_translation = move_iteration(MovementType.VERTICAL, vertical_collisions, initial_vertical_translation, vertical_translation) | ||||
| 		vertical_translation = move_iteration( | ||||
| 			MovementType.VERTICAL, | ||||
| 			vertical_collisions, | ||||
| 			initial_vertical_translation, | ||||
| 			vertical_translation | ||||
| 		) | ||||
| 		vertical_iterations += 1 | ||||
| 
 | ||||
| 	# Don't include step height in actual velocity | ||||
|  | @ -236,14 +255,23 @@ func move(intended_velocity : Vector3, delta : float) -> void: | |||
| 		var ground_snap_iterations := 0 | ||||
| 		var ground_snap_translation := Vector3.DOWN * snap_to_ground_distance | ||||
| 		while ground_snap_translation.length() > 0 and ground_snap_iterations < max_iteration_count: | ||||
| 
 | ||||
| 			ground_snap_translation = move_iteration(MovementType.VERTICAL, snap_collisions, Vector3.DOWN, ground_snap_translation) | ||||
| 			ground_snap_translation = move_iteration( | ||||
| 				MovementType.VERTICAL, snap_collisions, Vector3.DOWN, ground_snap_translation | ||||
| 			) | ||||
| 			ground_snap_iterations += 1 | ||||
| 
 | ||||
| 		# Decide whether to keep the snap or not | ||||
| 		if snap_collisions.is_empty(): | ||||
| 			var after_snap_ground_test := move_and_collide(Vector3.DOWN * ground_cast_distance, true, depenetration_margin) | ||||
| 			if after_snap_ground_test and after_snap_ground_test.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit): | ||||
| 			var after_snap_ground_test := move_and_collide( | ||||
| 				Vector3.DOWN * ground_cast_distance, true, depenetration_margin | ||||
| 			) | ||||
| 			if ( | ||||
| 				after_snap_ground_test | ||||
| 				and ( | ||||
| 					after_snap_ground_test.get_normal(0).angle_to(Vector3.UP) | ||||
| 					< deg_to_rad(slope_limit) | ||||
| 				) | ||||
| 			): | ||||
| 				# There was no snap collisions, but there is ground underneath | ||||
| 				# This can be due to an edge case where the snap movement falls through the ground | ||||
| 				# Why does this check not fall through the ground? I don't know | ||||
|  | @ -252,7 +280,10 @@ func move(intended_velocity : Vector3, delta : float) -> void: | |||
| 			else: | ||||
| 				# No snap collisions and no floor, reset | ||||
| 				position = before_snap_pos | ||||
| 		elif !(snap_collisions[snap_collisions.size() - 1].get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit)): | ||||
| 		elif !( | ||||
| 			snap_collisions[snap_collisions.size() - 1].get_normal(0).angle_to(Vector3.UP) | ||||
| 			< deg_to_rad(slope_limit) | ||||
| 		): | ||||
| 			# Collided with steep ground, reset | ||||
| 			position = before_snap_pos | ||||
| 	else: | ||||
|  | @ -261,9 +292,13 @@ func move(intended_velocity : Vector3, delta : float) -> void: | |||
| 
 | ||||
| # Moves are composed of multiple iterates | ||||
| # In each iteration, move until collision, then calculate and return the next movement | ||||
| func move_iteration(movement_type: MovementType, collision_array : Array, initial_direction: Vector3, translation: Vector3) -> Vector3: | ||||
| 
 | ||||
| 	var collisions : KinematicCollision3D | ||||
| func move_iteration( | ||||
| 	movement_type: MovementType, | ||||
| 	collision_array: Array, | ||||
| 	initial_direction: Vector3, | ||||
| 	translation: Vector3 | ||||
| ) -> Vector3: | ||||
| 	var collisions: KinematicCollision3D | ||||
| 
 | ||||
| 	# If Lateral movement, try stepping | ||||
| 	if movement_type == MovementType.LATERAL: | ||||
|  | @ -274,7 +309,7 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 
 | ||||
| 		var current_step_height := step_height | ||||
| 		var step_up_collisions := move_and_collide(Vector3.UP * step_height, false, 0) | ||||
| 		if (step_up_collisions): | ||||
| 		if step_up_collisions: | ||||
| 			current_step_height = step_up_collisions.get_travel().length() | ||||
| 		var raised_forward_collisions := move_and_collide(translation, false, 0) | ||||
| 		var down_collision := move_and_collide(Vector3.DOWN * current_step_height, false, 0) | ||||
|  | @ -282,10 +317,12 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 		# Only step if the step algorithm landed on a walkable surface | ||||
| 		# AND the walk lands on a non-walkable surface | ||||
| 		# This stops stepping up ramps | ||||
| 		if (down_collision and | ||||
| 				down_collision.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit) and | ||||
| 				walk_test_collision and | ||||
| 				!walk_test_collision.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit)): | ||||
| 		if ( | ||||
| 			down_collision | ||||
| 			and down_collision.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit) | ||||
| 			and walk_test_collision | ||||
| 			and !walk_test_collision.get_normal(0).angle_to(Vector3.UP) < deg_to_rad(slope_limit) | ||||
| 		): | ||||
| 			do_step = true | ||||
| 
 | ||||
| 		if do_step:  # Keep track of stepepd distance to cancel it out later | ||||
|  | @ -322,8 +359,8 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 	# These values shouldn't be calculated every frame; they only need to change | ||||
| 	# when the user defines the slope limit | ||||
| 	# But I'm lazy :) | ||||
| 	var min_block_angle : float | ||||
| 	var max_block_angle : float | ||||
| 	var min_block_angle: float | ||||
| 	var max_block_angle: float | ||||
| 	if movement_type == MovementType.LATERAL: | ||||
| 		min_block_angle = deg_to_rad(slope_limit) | ||||
| 		if grounded: | ||||
|  | @ -334,7 +371,6 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 		min_block_angle = 0 | ||||
| 		max_block_angle = deg_to_rad(slope_limit) | ||||
| 
 | ||||
| 
 | ||||
| 	# This algorithm for determining where to move on a collisions uses "projection plane" | ||||
| 	# Whatever surface the character hits, we generate a blocking "plane" that we will slide along | ||||
| 	# | ||||
|  | @ -351,8 +387,13 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 
 | ||||
| 	# If collision happens on the "side" of the cylinder, treat it as a vertical | ||||
| 	# wall in all cases (we use the tangent of the cylinder) | ||||
| 	if (movement_type == MovementType.LATERAL and | ||||
| 		(collision_point.y > (collision_shape.global_position.y - cylinder.height / 2) + bottom_height)): | ||||
| 	if ( | ||||
| 		movement_type == MovementType.LATERAL | ||||
| 		and ( | ||||
| 			collision_point.y | ||||
| 			> (collision_shape.global_position.y - cylinder.height / 2) + bottom_height | ||||
| 		) | ||||
| 	): | ||||
| 		projection_normal = collision_shape.global_position - collision_point | ||||
| 		projection_normal.y = 0 | ||||
| 		projection_normal = projection_normal.normalized() | ||||
|  | @ -386,11 +427,13 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 	var continued_translation := projection_plane.project(collisions.get_remainder()) | ||||
| 	var initial_influenced_translation := projection_plane.project(initial_direction) | ||||
| 
 | ||||
| 	var next_translation : Vector3 | ||||
| 	var next_translation: Vector3 | ||||
| 	if initial_influenced_translation.dot(continued_translation) >= 0: | ||||
| 		next_translation = continued_translation | ||||
| 	else: | ||||
| 		next_translation = initial_influenced_translation.normalized() * continued_translation.length() | ||||
| 		next_translation = ( | ||||
| 			initial_influenced_translation.normalized() * continued_translation.length() | ||||
| 		) | ||||
| 
 | ||||
| 	# See same_surface_adjust_distance | ||||
| 	if next_translation.normalized() == translation.normalized(): | ||||
|  | @ -399,16 +442,17 @@ func move_iteration(movement_type: MovementType, collision_array : Array, initia | |||
| 	return next_translation | ||||
| 
 | ||||
| 
 | ||||
| func already_touched_slope_close_match(normal : Vector3) -> bool: | ||||
| func already_touched_slope_close_match(normal: Vector3) -> bool: | ||||
| 	for steep_slope_normal in steep_slope_normals: | ||||
| 		if steep_slope_normal.distance_squared_to(normal) < 0.001: | ||||
| 			return true | ||||
| 
 | ||||
| 	return false | ||||
| 
 | ||||
| 
 | ||||
| # I wrote this a while ago in Unity | ||||
| # I ported it here but I only have a vague grasp of how it works | ||||
| func relative_slope_normal(slope_normal : Vector3, lateral_desired_direction : Vector3) -> Vector3: | ||||
| func relative_slope_normal(slope_normal: Vector3, lateral_desired_direction: Vector3) -> Vector3: | ||||
| 	var slope_normal_horz := horz(slope_normal) | ||||
| 	var angle_to_straight := slope_normal_horz.angle_to(-lateral_desired_direction) | ||||
| 	var angle_to_up := slope_normal.angle_to(Vector3.UP) | ||||
|  | @ -435,8 +479,10 @@ func relative_slope_normal(slope_normal : Vector3, lateral_desired_direction : V | |||
| 
 | ||||
| 	return emulated_normal.normalized() | ||||
| 
 | ||||
| 
 | ||||
| func horz(value: Vector3) -> Vector3: | ||||
| 	return Vector3(value.x,0,value.z) | ||||
| 	return Vector3(value.x, 0, value.z) | ||||
| 
 | ||||
| 
 | ||||
| func vert(value: Vector3) -> Vector3: | ||||
| 	return Vector3(0,value.y,0) | ||||
| 	return Vector3(0, value.y, 0) | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| extends Node3D | ||||
| 
 | ||||
| @export var target : Node3D | ||||
| @export var target: Node3D | ||||
| var currTransform: Transform3D | ||||
| var prevTransform: Transform3D | ||||
| 
 | ||||
| 
 | ||||
| # Called when the node enters the scene tree for the first time. | ||||
| func _ready() -> void: | ||||
| 	currTransform = Transform3D() | ||||
|  | @ -26,6 +27,7 @@ func _process(_delta: float) -> void: | |||
| 
 | ||||
| 	transform = new_transform | ||||
| 
 | ||||
| 
 | ||||
| func _physics_process(_delta: float) -> void: | ||||
| 	prevTransform = currTransform | ||||
| 	currTransform = target.global_transform | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue