Godot Tutorial: Creating a physics based point & click mechanic
This is a step by step guide for how to recreate the physics based click and drag mechanic seen in my game.
Tutorial
Step 1: setup a global script with variables var is_dragging = false and var hovering = false in which will track whether you're actively dragging an object. Set that script in the project settings in the "autoload" settings.
Step 2: In project settings under "Input Map" add a new action called "click" that corresponds to left click
Step 3: Create your draggable RigidBody2d, make sure to add an Area2d called "clickable_area" and add a collision shape that covers everything you want to be draggable.
Step 4: Create the script for your draggable object and then go back to your Area2d, "clickable_area" and connect the following signals to your object script:
-
body_entered(body:Node2d)
-
body_exited(body:Node2d)
Step 5: Now the signals section of the Object script will have the following code: (replace > with tabs)
var draggable = false func _on_area_2d_mouse_entered(): > if not global.is_dragging: >> draggable = true #notes that this object can be dragged >> global.hovering = true #prevents clicking on multiple objects at the same time >> add_to_group("hovered") #prevents clicking on multiple objects at the same time >> scale = Vector2(1.05, 1.05) #shows which objects can be clicked by increasing size func _on_area_2d_mouse_exited(): > if not global.is_dragging: >> draggable = false >> global.hovering = false >> remove_from_group("hovered") >> scale = Vector2(1, 1)
Step 6: Next we'll go back the global script and add the logic for handling hovering:
... var hovered : Array var hovered_size var top_hovered func _process(delta): > if hovering and not is_dragging: >> hovered = get_tree().get_nodes_in_group("hovered") >> hovered_size = get_tree().get_nodes_in_group("hovered").size()-1 >> if hovered_size >= 0: >>> top_hovered = hovered[hovered_size] >> else: >>> hovering = false
Step 7: now we'll add a StaticBody2d named "mouse null" to your main scene with a child PinJoint2d make sure to set the Node A in the PinJoint2d reference your StaticBody2d
Step 8: Add a script to your StaticBody2d, "mouse null":
func _physics_process(delta): >global_position = lerp(global_position, get_global_mouse_position(), 60*delta) #make StaticBody2d follow mouse >if Input.is_action_pressed("click"): >>if global.is_dragging == true: >>$PinJoint2D.node_b = global.top_hovered.get_path() #get attached the PinJoint2d to the top object >elif Input.is_action_just_released("click"): >>$PinJoint2D.node_b = ""
Step 9: We'll go back to your object script, and add to the _physics_process:
func _physics_process(delta): > if draggable and global.top_hovered == self: #this is determined by the "clickable area" with signals & logic checking an array of overlapping objects >> if Input.is_action_just_pressed("click"): >>>self.collision_mask = 2 #keeps you from interacting with other objects while dragging remove if undesired >>>self.collision_layer = 2 #keeps you from interacting with other objects while dragging remove if undesired >>>global.is_dragging = true #keeps you from picking up multiple objects >>if Input.is_action_pressed("click"): >>>global.is_dragging = true >>elif Input.is_action_just_released("click"): >>>self.collision_mask = 1 >>>self.collision_layer = 1 >>>global.is_dragging = false >>>draggable = false >>>self.angular_velocity = 0.0 #reset any momentum when released to avoid physics glitches >>>self.linear_velocity = Vector2(0,0) #reset any momentum when released to avoid physics glitches
Now it should work! Have fun!
Get Voynich Cafe
Voynich Cafe
the geometric cooking game
Status | Released |
Author | Franz Kafka's Office Printer |
Genre | Puzzle |
Tags | Casual, Cooking, Cozy, Cute, Fantasy, illumination, Medieval, potion-crafting, voynich-cafe |
More posts
- Voynich Cafe - PostmortemJul 30, 2024
- Voynich Cafe V0.5 ReleaseJul 26, 2024
- A Progress UpdateMay 07, 2024
Leave a comment
Log in with itch.io to leave a comment.