From cdf5b018bfac5676a158e87d7b413b1ba80c8c3d Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 20 May 2026 15:15:25 +0200 Subject: [PATCH] fix: player considers whether the hang ray is reachable --- modules/viscosity/player_behaviour_tree.cpp | 2 ++ modules/viscosity/player_behaviour_tree.h | 2 ++ project/objects/player.tscn | 22 ++++++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/modules/viscosity/player_behaviour_tree.cpp b/modules/viscosity/player_behaviour_tree.cpp index 4e2fb3c9..3876ecfe 100644 --- a/modules/viscosity/player_behaviour_tree.cpp +++ b/modules/viscosity/player_behaviour_tree.cpp @@ -13,6 +13,7 @@ void PlayerBehaviourTree::_bind_methods() { BIND_HPROPERTY(Variant::OBJECT, anim, PROPERTY_HINT_NODE_TYPE, "AnimationPlayer", PROPERTY_USAGE_READ_ONLY); BIND_HPROPERTY(Variant::OBJECT, hang_ray, PROPERTY_HINT_NODE_TYPE, "RayCast3D", PROPERTY_USAGE_READ_ONLY); BIND_HPROPERTY(Variant::OBJECT, ground_ray, PROPERTY_HINT_NODE_TYPE, "RayCast3D", PROPERTY_USAGE_READ_ONLY); + BIND_HPROPERTY(Variant::OBJECT, high_wall_ray, PROPERTY_HINT_NODE_TYPE, "RayCast3D", PROPERTY_USAGE_READ_ONLY); ClassDB::bind_method(D_METHOD("get_world_move_input"), &self_type::get_world_move_input); ClassDB::bind_method(D_METHOD("get_ground_distance"), &self_type::get_ground_distance); } @@ -32,6 +33,7 @@ void PlayerBehaviourTree::_notification(int what) { if (this->character) { this->anim = cast_to(this->character->get_node(NodePath("AnimationTree"))); this->hang_ray = cast_to(this->character->get_node(NodePath("HangRay"))); + this->high_wall_ray = cast_to(this->character->get_node(NodePath("HighWallRay"))); } return; case NOTIFICATION_READY: diff --git a/modules/viscosity/player_behaviour_tree.h b/modules/viscosity/player_behaviour_tree.h index 89c7f1dc..425ff63d 100644 --- a/modules/viscosity/player_behaviour_tree.h +++ b/modules/viscosity/player_behaviour_tree.h @@ -26,6 +26,7 @@ private: AnimationTree *anim{ nullptr }; RayCast3D *hang_ray{ nullptr }; RayCast3D *ground_ray{ nullptr }; + RayCast3D *high_wall_ray{ nullptr }; public: GET_SET_FNS(RayCast3D *, ground_ray); @@ -34,5 +35,6 @@ public: GET_SET_FNS(Node3D *, character); GET_SET_FNS(AnimationTree *, anim); GET_SET_FNS(RayCast3D *, hang_ray); + GET_SET_FNS(RayCast3D *, high_wall_ray); float get_ground_distance() const; }; diff --git a/project/objects/player.tscn b/project/objects/player.tscn index 0039b162..130b6185 100644 --- a/project/objects/player.tscn +++ b/project/objects/player.tscn @@ -192,6 +192,16 @@ func _physics_process(_delta : float): global_position = body.global_position + Vector3.UP * height + last_direction * dist_mul " +[sub_resource type="GDScript" id="GDScript_4vq5b"] +resource_name = "PlayerHighWallRay" +script/source = "extends RayCast3D + +func _process(_delta : float): + target_position = $\"../HangRay\".global_position - global_position + global_rotation = Vector3.ZERO + global_position = get_parent_node_3d().global_position + Vector3.UP * 2.0 +" + [sub_resource type="GDScript" id="GDScript_3rerk"] resource_name = "BelowLedgePrerequisite" script/source = "extends PlayerAction @@ -204,7 +214,8 @@ func _ready(): func _enter() -> int: blackboard.hang_ray.force_raycast_update() blackboard.ground_ray.force_raycast_update() - if not timeout and not body.is_on_floor() and blackboard.hang_ray.is_colliding(): + blackboard.high_wall_ray.force_raycast_update() + if not timeout and not body.is_on_floor() and blackboard.hang_ray.is_colliding() and not blackboard.high_wall_ray.is_colliding(): var wall_normal_y : float = blackboard.hang_ray.get_collision_normal().y var edge_distance : float = blackboard.hang_ray.get_collision_point().distance_to(blackboard.hang_ray.global_position) if wall_normal_y > 0.9 and body.is_on_wall() and blackboard.get_ground_distance() > edge_distance: @@ -289,7 +300,7 @@ func _enter() -> int: var flat_velocity := Vector2(body.velocity.x, body.velocity.z) var input_velocity_dot : float = blackboard.get_world_move_input().normalized().dot(body.velocity.normalized()) var ground_velocity := Vector3(body.velocity.x, 0, body.velocity.z) - if body.is_on_wall_only() and input_velocity_dot > 0.01 and ground_velocity.length() >= min_ground_speed and flat_velocity.length() > -body.velocity.y * 4.0 and not blackboard.hang_ray.is_colliding(): + if body.is_on_wall_only() and input_velocity_dot > 0.01 and ground_velocity.length() >= min_ground_speed and flat_velocity.length() > -body.velocity.y * 4.0: if Input.is_action_just_pressed(\"jump\") and run_time > min_run_time: var wall_flat := Vector3(body.get_wall_normal().x, 0, body.get_wall_normal().z) body.velocity = wall_flat * jump_normal_force + (ground_velocity + blackboard.get_world_move_input()).normalized() * jump_input_force * ground_velocity.length() @@ -324,7 +335,7 @@ script/source = "extends PlayerAction func _enter() -> int: var flat_wall := Vector3(body.get_wall_normal().x, 0, body.get_wall_normal().z) var input_into_wall := blackboard.get_world_move_input().normalized().dot(body.get_wall_normal()) < 0.1 - if body.is_on_wall_only() and input_into_wall and not blackboard.hang_ray.is_colliding() and blackboard.get_ground_distance() > .5 and body.velocity.y < 1.0: + if body.is_on_wall_only() and input_into_wall and blackboard.get_ground_distance() > .5 and body.velocity.y < 1.0: if Input.is_action_just_pressed(\"jump\"): body.velocity = flat_wall * jump_normal_force body.velocity.y = jump_vertical_force @@ -433,6 +444,11 @@ target_position = Vector3(0, -2, 0) script = SubResource("GDScript_f46kd") dist_mul = -0.508 +[node name="HighWallRay" type="RayCast3D" parent="PlayerModel" unique_id=2283840] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0) +target_position = Vector3(0, 0, -0.5) +script = SubResource("GDScript_4vq5b") + [node name="Camera3D" type="PlayerCamera" parent="." unique_id=709217818] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.3841858e-07, 0.81082594, 1.2089427) fov = 96.8