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 |
| Languages | English |
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.