[3.1] Simplify list of branches in the README (#1255)

This commit is contained in:
Aaron Franke
2025-10-02 15:46:10 -07:00
parent a6ae6f64be
commit ea5b868fc7
143 changed files with 575 additions and 689 deletions

19
.github/workflows/static_checks.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Static Checks
on: [push, pull_request]
jobs:
format:
name: File formatting (file_format.sh)
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Install dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -qq dos2unix recode
- name: File formatting checks (file_format.sh)
run: |
bash ./file_format.sh

1
.gitignore vendored
View File

@@ -18,4 +18,5 @@ mono_crash.*.json
# System/tool-specific ignores # System/tool-specific ignores
.directory .directory
.DS_Store
*~ *~

View File

@@ -14,7 +14,7 @@ func _process(delta):
var velocity = Vector2() var velocity = Vector2()
velocity.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left") velocity.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
velocity.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up") velocity.y = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
if velocity.length() > 0: if velocity.length() > 0:
velocity = velocity.normalized() * speed velocity = velocity.normalized() * speed
$AnimatedSprite.play() $AnimatedSprite.play()

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -16,7 +16,7 @@ size_flags_vertical = 4
custom_fonts/bold_font = ExtResource( 1 ) custom_fonts/bold_font = ExtResource( 1 )
custom_fonts/normal_font = ExtResource( 2 ) custom_fonts/normal_font = ExtResource( 2 )
bbcode_enabled = true bbcode_enabled = true
bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton. bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
States are common in games. You can use the pattern to: States are common in games. You can use the pattern to:
@@ -25,7 +25,7 @@ States are common in games. You can use the pattern to:
3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do. 3. Improve your code's structure. Look at the scene tree and FileSystem tab: without looking at the code, you'll know what the Player can or cannot do.
You can read more about States in the excellent [url=http://gameprogrammingpatterns.com/state.html]Game Programming Patterns ebook[/url]." You can read more about States in the excellent [url=http://gameprogrammingpatterns.com/state.html]Game Programming Patterns ebook[/url]."
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton. text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
States are common in games. You can use the pattern to: States are common in games. You can use the pattern to:

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -60,14 +60,14 @@ func _change_state(state_name):
if not _active: if not _active:
return return
current_state.exit() current_state.exit()
if state_name == "previous": if state_name == "previous":
states_stack.pop_front() states_stack.pop_front()
else: else:
states_stack[0] = states_map[state_name] states_stack[0] = states_map[state_name]
current_state = states_stack[0] current_state = states_stack[0]
emit_signal("state_changed", current_state) emit_signal("state_changed", current_state)
if state_name != "previous": if state_name != "previous":
current_state.enter() current_state.enter()

View File

@@ -51,20 +51,20 @@ func _ready():
func _process(_delta): func _process(_delta):
var mouse_pos = get_viewport().get_mouse_position() var mouse_pos = get_viewport().get_mouse_position()
# Check if the mouse is currently inside the canvas/drawing-area. # Check if the mouse is currently inside the canvas/drawing-area.
is_mouse_in_drawing_area = false is_mouse_in_drawing_area = false
if mouse_pos.x > TL_node.global_position.x: if mouse_pos.x > TL_node.global_position.x:
if mouse_pos.y > TL_node.global_position.y: if mouse_pos.y > TL_node.global_position.y:
is_mouse_in_drawing_area = true is_mouse_in_drawing_area = true
if Input.is_mouse_button_pressed(BUTTON_LEFT): if Input.is_mouse_button_pressed(BUTTON_LEFT):
# If we do not have a position for when the mouse was first clicked, then this must # If we do not have a position for when the mouse was first clicked, then this must
# be the first time is_mouse_button_pressed has been called since the mouse button was # be the first time is_mouse_button_pressed has been called since the mouse button was
# released, so we need to store the position. # released, so we need to store the position.
if mouse_click_start_pos == null: if mouse_click_start_pos == null:
mouse_click_start_pos = mouse_pos mouse_click_start_pos = mouse_pos
# If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call. # If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call.
if check_if_mouse_is_inside_canvas(): if check_if_mouse_is_inside_canvas():
if mouse_pos.distance_to(last_mouse_pos) >= 1: if mouse_pos.distance_to(last_mouse_pos) >= 1:
@@ -77,11 +77,11 @@ func _process(_delta):
undo_element_list_num = brush_data_list.size() undo_element_list_num = brush_data_list.size()
# Add the brush object to draw_elements_array. # Add the brush object to draw_elements_array.
add_brush(mouse_pos, brush_mode) add_brush(mouse_pos, brush_mode)
else: else:
# We've finished our stroke, so we can set a new undo (if a new storke is made). # We've finished our stroke, so we can set a new undo (if a new storke is made).
undo_set = false undo_set = false
# If the mouse is inside the canvas. # If the mouse is inside the canvas.
if check_if_mouse_is_inside_canvas(): if check_if_mouse_is_inside_canvas():
# If we're using either the circle shape mode, or the rectangle shape mode, then # If we're using either the circle shape mode, or the rectangle shape mode, then
@@ -94,7 +94,7 @@ func _process(_delta):
# Since we've released the left mouse, we need to get a new mouse_click_start_pos next time # Since we've released the left mouse, we need to get a new mouse_click_start_pos next time
#is_mouse_button_pressed is true. #is_mouse_button_pressed is true.
mouse_click_start_pos = null mouse_click_start_pos = null
# Store mouse_pos as last_mouse_pos now that we're done with _process. # Store mouse_pos as last_mouse_pos now that we're done with _process.
last_mouse_pos = mouse_pos last_mouse_pos = mouse_pos
@@ -108,7 +108,7 @@ func check_if_mouse_is_inside_canvas():
if mouse_click_start_pos.x > TL_node.global_position.x: if mouse_click_start_pos.x > TL_node.global_position.x:
if mouse_click_start_pos.y > TL_node.global_position.y: if mouse_click_start_pos.y > TL_node.global_position.y:
# Make sure the current mouse position is inside the canvas. # Make sure the current mouse position is inside the canvas.
if is_mouse_in_drawing_area == true: if is_mouse_in_drawing_area:
return true return true
return false return false
@@ -117,17 +117,17 @@ func undo_stroke():
# Only undo a stroke if we have one. # Only undo a stroke if we have one.
if undo_element_list_num == UNDO_NONE: if undo_element_list_num == UNDO_NONE:
return return
# If we are undoing a shape, then we can just remove the latest brush. # If we are undoing a shape, then we can just remove the latest brush.
if undo_element_list_num == UNDO_MODE_SHAPE: if undo_element_list_num == UNDO_MODE_SHAPE:
if brush_data_list.size() > 0: if brush_data_list.size() > 0:
brush_data_list.remove(brush_data_list.size() - 1) brush_data_list.remove(brush_data_list.size() - 1)
# Now that we've undone a shape, we cannot undo again until another stoke is added. # Now that we've undone a shape, we cannot undo again until another stoke is added.
undo_element_list_num = UNDO_NONE undo_element_list_num = UNDO_NONE
# NOTE: if we only had shape brushes, then we could remove the above line and could let the user # NOTE: if we only had shape brushes, then we could remove the above line and could let the user
# undo until we have a empty element list. # undo until we have a empty element list.
# Otherwise we're removing a either a pencil stroke or a eraser stroke. # Otherwise we're removing a either a pencil stroke or a eraser stroke.
else: else:
# Figure out how many elements/brushes we've added in the last stroke. # Figure out how many elements/brushes we've added in the last stroke.
@@ -136,7 +136,7 @@ func undo_stroke():
#warning-ignore:unused_variable #warning-ignore:unused_variable
for elment_num in range(0, elements_to_remove): for elment_num in range(0, elements_to_remove):
brush_data_list.pop_back() brush_data_list.pop_back()
# Now that we've undone a stoke, we cannot undo again until another stoke is added. # Now that we've undone a stoke, we cannot undo again until another stoke is added.
undo_element_list_num = UNDO_NONE undo_element_list_num = UNDO_NONE
@@ -147,7 +147,7 @@ func undo_stroke():
func add_brush(mouse_pos, type): func add_brush(mouse_pos, type):
# Make new brush dictionary that will hold all of the data we need for the brush. # Make new brush dictionary that will hold all of the data we need for the brush.
var new_brush = {} var new_brush = {}
# Populate the dictionary with values based on the global brush variables. # Populate the dictionary with values based on the global brush variables.
# We will override these as needed if the brush is a rectange or circle. # We will override these as needed if the brush is a rectange or circle.
new_brush.brush_type = type new_brush.brush_type = type
@@ -155,13 +155,13 @@ func add_brush(mouse_pos, type):
new_brush.brush_shape = brush_shape new_brush.brush_shape = brush_shape
new_brush.brush_size = brush_size new_brush.brush_size = brush_size
new_brush.brush_color = brush_color new_brush.brush_color = brush_color
# If the new bursh is a rectangle shape, we need to calculate the top left corner of the rectangle and the # If the new bursh is a rectangle shape, we need to calculate the top left corner of the rectangle and the
# bottom right corner of the rectangle. # bottom right corner of the rectangle.
if type == BrushModes.RECTANGLE_SHAPE: if type == BrushModes.RECTANGLE_SHAPE:
var TL_pos = Vector2() var TL_pos = Vector2()
var BR_pos = Vector2() var BR_pos = Vector2()
# Figure out the left and right positions of the corners and assign them to the proper variable. # Figure out the left and right positions of the corners and assign them to the proper variable.
if mouse_pos.x < mouse_click_start_pos.x: if mouse_pos.x < mouse_click_start_pos.x:
TL_pos.x = mouse_pos.x TL_pos.x = mouse_pos.x
@@ -169,7 +169,7 @@ func add_brush(mouse_pos, type):
else: else:
TL_pos.x = mouse_click_start_pos.x TL_pos.x = mouse_click_start_pos.x
BR_pos.x = mouse_pos.x BR_pos.x = mouse_pos.x
# Figure out the top and bottom positions of the corners and assign them to the proper variable. # Figure out the top and bottom positions of the corners and assign them to the proper variable.
if mouse_pos.y < mouse_click_start_pos.y: if mouse_pos.y < mouse_click_start_pos.y:
TL_pos.y = mouse_pos.y TL_pos.y = mouse_pos.y
@@ -177,11 +177,11 @@ func add_brush(mouse_pos, type):
else: else:
TL_pos.y = mouse_click_start_pos.y TL_pos.y = mouse_click_start_pos.y
BR_pos.y = mouse_pos.y BR_pos.y = mouse_pos.y
# Assign the positions to the brush. # Assign the positions to the brush.
new_brush.brush_pos = TL_pos new_brush.brush_pos = TL_pos
new_brush.brush_shape_rect_pos_BR = BR_pos new_brush.brush_shape_rect_pos_BR = BR_pos
# If the brush isa circle shape, then we need to calculate the radius of the circle. # If the brush isa circle shape, then we need to calculate the radius of the circle.
if type == BrushModes.CIRCLE_SHAPE: if type == BrushModes.CIRCLE_SHAPE:
# Get the center point inbetween the mouse position and the position of the mouse when we clicked. # Get the center point inbetween the mouse position and the position of the mouse when we clicked.
@@ -190,7 +190,7 @@ func add_brush(mouse_pos, type):
# the center to the top/bottom positon of the mouse. # the center to the top/bottom positon of the mouse.
new_brush.brush_pos = center_pos new_brush.brush_pos = center_pos
new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y)) new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y))
# Add the brush and update/draw all of the brushes. # Add the brush and update/draw all of the brushes.
brush_data_list.append(new_brush) brush_data_list.append(new_brush)
update() update()
@@ -214,7 +214,7 @@ func _draw():
BrushModes.ERASER: BrushModes.ERASER:
# NOTE: this is a really cheap way of erasing that isn't really erasing! # NOTE: this is a really cheap way of erasing that isn't really erasing!
# However, this gives similar results in a fairy simple way! # However, this gives similar results in a fairy simple way!
# Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape, # Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape,
# but instead of using brush.brush_color, we instead use bg_color instead. # but instead of using brush.brush_color, we instead use bg_color instead.
if brush.brush_shape == BrushShapes.RECTANGLE: if brush.brush_shape == BrushShapes.RECTANGLE:
@@ -237,13 +237,13 @@ func save_picture(path):
# Wait a couple frames so the save dialog isn't in the way. # Wait a couple frames so the save dialog isn't in the way.
yield (get_tree(), "idle_frame") yield (get_tree(), "idle_frame")
yield (get_tree(), "idle_frame") yield (get_tree(), "idle_frame")
# Get the viewport image. # Get the viewport image.
var img = get_viewport().get_texture().get_data() var img = get_viewport().get_texture().get_data()
# Crop the image so we only have canvas area. # Crop the image so we only have canvas area.
var cropped_image = img.get_rect(Rect2(TL_node.global_position, IMAGE_SIZE)) var cropped_image = img.get_rect(Rect2(TL_node.global_position, IMAGE_SIZE))
# Flip the image on the Y-axis (it's flipped upside down by default). # Flip the image on the Y-axis (it's flipped upside down by default).
cropped_image.flip_y() cropped_image.flip_y()
# Save the image with the passed in path we got from the save dialog. # Save the image with the passed in path we got from the save dialog.
cropped_image.save_png(path) cropped_image.save_png(path)

View File

@@ -50,7 +50,7 @@ func button_pressed(button_name):
# If a brush mode button is pressed. # If a brush mode button is pressed.
var tool_name = null var tool_name = null
var shape_name = null var shape_name = null
if button_name == "mode_pencil": if button_name == "mode_pencil":
paint_control.brush_mode = paint_control.BrushModes.PENCIL paint_control.brush_mode = paint_control.BrushModes.PENCIL
brush_settings.modulate = Color(1, 1, 1, 1) brush_settings.modulate = Color(1, 1, 1, 1)
@@ -84,7 +84,7 @@ func button_pressed(button_name):
save_dialog.popup_centered() save_dialog.popup_centered()
elif button_name == "undo_stroke": elif button_name == "undo_stroke":
paint_control.undo_stroke() paint_control.undo_stroke()
# Update the labels (in case the brush mode or brush shape has changed). # Update the labels (in case the brush mode or brush shape has changed).
if tool_name != null: if tool_name != null:
label_tools.text = "Selected tool: " + tool_name label_tools.text = "Selected tool: " + tool_name

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -16,7 +16,7 @@ func get_cell_pawn(coordinates):
func request_move(pawn, direction): func request_move(pawn, direction):
var cell_start = world_to_map(pawn.position) var cell_start = world_to_map(pawn.position)
var cell_target = cell_start + direction var cell_target = cell_start + direction
var cell_target_type = get_cellv(cell_target) var cell_target_type = get_cellv(cell_target)
match cell_target_type: match cell_target_type:
CellType.EMPTY: CellType.EMPTY:

View File

@@ -44,7 +44,7 @@ func move_to(target_position):
# Stop the function execution until the animation finished # Stop the function execution until the animation finished
yield($AnimationPlayer, "animation_finished") yield($AnimationPlayer, "animation_finished")
set_process(true) set_process(true)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -26,7 +26,7 @@ func _physics_process(delta):
if (velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED) or (velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED): if (velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED) or (velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED):
force.x += WALK_FORCE * walk force.x += WALK_FORCE * walk
if abs(walk) < 0.5: if abs(walk) < 0.5:
var vsign = sign(velocity.x) var vsign = sign(velocity.x)
var vlen = abs(velocity.x) var vlen = abs(velocity.x)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -26,24 +26,24 @@ func _integrate_forces(s):
new_anim = "explode" new_anim = "explode"
elif state == State.WALKING: elif state == State.WALKING:
new_anim = "walk" new_anim = "walk"
var wall_side = 0.0 var wall_side = 0.0
for i in range(s.get_contact_count()): for i in range(s.get_contact_count()):
var cc = s.get_contact_collider_object(i) var cc = s.get_contact_collider_object(i)
var dp = s.get_contact_local_normal(i) var dp = s.get_contact_local_normal(i)
if cc: if cc:
if cc is Bullet and not cc.disabled: if cc is Bullet and not cc.disabled:
# enqueue call # enqueue call
call_deferred("_bullet_collider", cc, s, dp) call_deferred("_bullet_collider", cc, s, dp)
break break
if dp.x > 0.9: if dp.x > 0.9:
wall_side = 1.0 wall_side = 1.0
elif dp.x < -0.9: elif dp.x < -0.9:
wall_side = -1.0 wall_side = -1.0
if wall_side != 0 and wall_side != direction: if wall_side != 0 and wall_side != direction:
direction = -direction direction = -direction
($Sprite as Sprite).scale.x = -direction ($Sprite as Sprite).scale.x = -direction
@@ -53,13 +53,13 @@ func _integrate_forces(s):
elif direction > 0 and not rc_right.is_colliding() and rc_left.is_colliding(): elif direction > 0 and not rc_right.is_colliding() and rc_left.is_colliding():
direction = -direction direction = -direction
($Sprite as Sprite).scale.x = -direction ($Sprite as Sprite).scale.x = -direction
lv.x = direction * WALK_SPEED lv.x = direction * WALK_SPEED
if anim != new_anim: if anim != new_anim:
anim = new_anim anim = new_anim
($AnimationPlayer as AnimationPlayer).play(anim) ($AnimationPlayer as AnimationPlayer).play(anim)
s.set_linear_velocity(lv) s.set_linear_velocity(lv)
@@ -72,7 +72,7 @@ func _pre_explode():
$Shape1.queue_free() $Shape1.queue_free()
$Shape2.queue_free() $Shape2.queue_free()
$Shape3.queue_free() $Shape3.queue_free()
# Stay there # Stay there
mode = MODE_STATIC mode = MODE_STATIC
($SoundExplode as AudioStreamPlayer2D).play() ($SoundExplode as AudioStreamPlayer2D).play()
@@ -81,7 +81,7 @@ func _pre_explode():
func _bullet_collider(cc, s, dp): func _bullet_collider(cc, s, dp):
mode = MODE_RIGID mode = MODE_RIGID
state = State.DYING state = State.DYING
s.set_angular_velocity(sign(dp.x) * 33.0) s.set_angular_velocity(sign(dp.x) * 33.0)
set_friction(1) set_friction(1)
cc.disable() cc.disable()

View File

@@ -9,9 +9,9 @@ var accum = 0.0
func _physics_process(delta): func _physics_process(delta):
accum += delta * (1.0 / cycle) * TAU accum += delta * (1.0 / cycle) * TAU
accum = fmod(accum, TAU) accum = fmod(accum, TAU)
var d = sin(accum) var d = sin(accum)
var xf = Transform2D() var xf = Transform2D()
xf[2]= motion * d xf[2]= motion * d
($Platform as RigidBody2D).transform = xf ($Platform as RigidBody2D).transform = xf

View File

@@ -10,6 +10,6 @@ func _ready():
func disable(): func disable():
if disabled: if disabled:
return return
($AnimationPlayer as AnimationPlayer).play("shutdown") ($AnimationPlayer as AnimationPlayer).play("shutdown")
disabled = true disabled = true

View File

@@ -50,47 +50,47 @@ var Enemy = preload("res://enemy/Enemy.tscn")
func _integrate_forces(s): func _integrate_forces(s):
var lv = s.get_linear_velocity() var lv = s.get_linear_velocity()
var step = s.get_step() var step = s.get_step()
var new_anim = anim var new_anim = anim
var new_siding_left = siding_left var new_siding_left = siding_left
# Get the controls. # Get the controls.
var move_left = Input.is_action_pressed("move_left") var move_left = Input.is_action_pressed("move_left")
var move_right = Input.is_action_pressed("move_right") var move_right = Input.is_action_pressed("move_right")
var jump = Input.is_action_pressed("jump") var jump = Input.is_action_pressed("jump")
var shoot = Input.is_action_pressed("shoot") var shoot = Input.is_action_pressed("shoot")
var spawn = Input.is_action_pressed("spawn") var spawn = Input.is_action_pressed("spawn")
if spawn: if spawn:
call_deferred("_spawn_enemy_above") call_deferred("_spawn_enemy_above")
# Deapply prev floor velocity. # Deapply prev floor velocity.
lv.x -= floor_h_velocity lv.x -= floor_h_velocity
floor_h_velocity = 0.0 floor_h_velocity = 0.0
# Find the floor (a contact with upwards facing collision normal). # Find the floor (a contact with upwards facing collision normal).
var found_floor = false var found_floor = false
var floor_index = -1 var floor_index = -1
for x in range(s.get_contact_count()): for x in range(s.get_contact_count()):
var ci = s.get_contact_local_normal(x) var ci = s.get_contact_local_normal(x)
if ci.dot(Vector2(0, -1)) > 0.6: if ci.dot(Vector2(0, -1)) > 0.6:
found_floor = true found_floor = true
floor_index = x floor_index = x
# A good idea when implementing characters of all kinds, # A good idea when implementing characters of all kinds,
# compensates for physics imprecision, as well as human reaction delay. # compensates for physics imprecision, as well as human reaction delay.
if shoot and not shooting: if shoot and not shooting:
call_deferred("_shot_bullet") call_deferred("_shot_bullet")
else: else:
shoot_time += step shoot_time += step
if found_floor: if found_floor:
airborne_time = 0.0 airborne_time = 0.0
else: else:
airborne_time += step # Time it spent in the air. airborne_time += step # Time it spent in the air.
var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME var on_floor = airborne_time < MAX_FLOOR_AIRBORNE_TIME
# Process jump. # Process jump.
@@ -100,10 +100,10 @@ func _integrate_forces(s):
jumping = false jumping = false
elif not jump: elif not jump:
stopping_jump = true stopping_jump = true
if stopping_jump: if stopping_jump:
lv.y += STOP_JUMP_FORCE * step lv.y += STOP_JUMP_FORCE * step
if on_floor: if on_floor:
# Process logic when character is on floor. # Process logic when character is on floor.
if move_left and not move_right: if move_left and not move_right:
@@ -118,14 +118,14 @@ func _integrate_forces(s):
if xv < 0: if xv < 0:
xv = 0 xv = 0
lv.x = sign(lv.x) * xv lv.x = sign(lv.x) * xv
# Check jump. # Check jump.
if not jumping and jump: if not jumping and jump:
lv.y = -JUMP_VELOCITY lv.y = -JUMP_VELOCITY
jumping = true jumping = true
stopping_jump = false stopping_jump = false
($SoundJump as AudioStreamPlayer2D).play() ($SoundJump as AudioStreamPlayer2D).play()
# Check siding. # Check siding.
if lv.x < 0 and move_left: if lv.x < 0 and move_left:
new_siding_left = true new_siding_left = true
@@ -154,11 +154,11 @@ func _integrate_forces(s):
else: else:
var xv = abs(lv.x) var xv = abs(lv.x)
xv -= AIR_DEACCEL * step xv -= AIR_DEACCEL * step
if xv < 0: if xv < 0:
xv = 0 xv = 0
lv.x = sign(lv.x) * xv lv.x = sign(lv.x) * xv
if lv.y < 0: if lv.y < 0:
if shoot_time < MAX_SHOOT_POSE_TIME: if shoot_time < MAX_SHOOT_POSE_TIME:
new_anim = "jumping_weapon" new_anim = "jumping_weapon"
@@ -169,28 +169,28 @@ func _integrate_forces(s):
new_anim = "falling_weapon" new_anim = "falling_weapon"
else: else:
new_anim = "falling" new_anim = "falling"
# Update siding. # Update siding.
if new_siding_left != siding_left: if new_siding_left != siding_left:
if new_siding_left: if new_siding_left:
($Sprite as Sprite).scale.x = -1 ($Sprite as Sprite).scale.x = -1
else: else:
($Sprite as Sprite).scale.x = 1 ($Sprite as Sprite).scale.x = 1
siding_left = new_siding_left siding_left = new_siding_left
# Change animation. # Change animation.
if new_anim != anim: if new_anim != anim:
anim = new_anim anim = new_anim
($AnimationPlayer as AnimationPlayer).play(anim) ($AnimationPlayer as AnimationPlayer).play(anim)
shooting = shoot shooting = shoot
# Apply floor velocity. # Apply floor velocity.
if found_floor: if found_floor:
floor_h_velocity = s.get_contact_collider_velocity_at_position(floor_index).x floor_h_velocity = s.get_contact_collider_velocity_at_position(floor_index).x
lv.x += floor_h_velocity lv.x += floor_h_velocity
# Finally, apply gravity and set back the linear velocity. # Finally, apply gravity and set back the linear velocity.
lv += s.get_total_gravity() * step lv += s.get_total_gravity() * step
s.set_linear_velocity(lv) s.set_linear_velocity(lv)
@@ -205,15 +205,15 @@ func _shot_bullet():
else: else:
ss = 1.0 ss = 1.0
var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0) var pos = position + ($BulletShoot as Position2D).position * Vector2(ss, 1.0)
bi.position = pos bi.position = pos
get_parent().add_child(bi) get_parent().add_child(bi)
bi.linear_velocity = Vector2(800.0 * ss, -80) bi.linear_velocity = Vector2(800.0 * ss, -80)
($Sprite/Smoke as Particles2D).restart() ($Sprite/Smoke as Particles2D).restart()
($SoundShoot as AudioStreamPlayer2D).play() ($SoundShoot as AudioStreamPlayer2D).play()
add_collision_exception_with(bi) # Make bullet and this not collide. add_collision_exception_with(bi) # Make bullet and this not collide.

View File

@@ -8,7 +8,7 @@ const FLOOR_NORMAL = Vector2(0, -1)
const STATE_WALKING = 0 const STATE_WALKING = 0
const STATE_KILLED = 1 const STATE_KILLED = 1
const WALK_SPEED = 70 const WALK_SPEED = 70
var linear_velocity = Vector2() var linear_velocity = Vector2()
var direction = -1 var direction = -1

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -1,5 +1,5 @@
{ {
"dialog_1" : {"name": "Unknown", "text": "Hey, it's a good time to have a JRPG fight, right?"}, "dialog_1": { "name": "Unknown", "text": "Hey, it's a good time to have a JRPG fight, right?" },
"dialog_2" : {"name": "Unknown", "text": "Let me introduce myself, I'm the OPPONENT"}, "dialog_2": { "name": "Unknown", "text": "Let me introduce myself, I'm the OPPONENT" },
"dialog_3" : {"name": "Opponent", "text": "Enough talking. Let's fight!"}, "dialog_3": { "name": "Opponent", "text": "Enough talking. Let's fight!" }
} }

View File

@@ -1,3 +1,3 @@
{ {
"dialog_1" : {"name":"Player", "text":"Just some object..." } "dialog_1": { "name": "Player", "text": "Just some object..." }
} }

View File

@@ -1,3 +1,3 @@
{ {
"dialog_1" : {"name": "Opponent", "text": "Aha! I won, maybe you can try again next time"} "dialog_1": { "name": "Opponent", "text": "Aha! I won, maybe you can try again next time" }
} }

View File

@@ -1,3 +1,3 @@
{ {
"dialog_1" : {"name": "Opponent", "text": "Congratulations, you won!"} "dialog_1": { "name": "Opponent", "text": "Congratulations, you won!" }
} }

View File

@@ -19,7 +19,7 @@ func get_cell_pawn(cell, type = CellType.ACTOR):
func request_move(pawn, direction): func request_move(pawn, direction):
var cell_start = world_to_map(pawn.position) var cell_start = world_to_map(pawn.position)
var cell_target = cell_start + direction var cell_target = cell_start + direction
var cell_tile_id = get_cellv(cell_target) var cell_tile_id = get_cellv(cell_target)
match cell_tile_id: match cell_tile_id:
-1: -1:
@@ -29,7 +29,7 @@ func request_move(pawn, direction):
CellType.OBJECT, CellType.ACTOR: CellType.OBJECT, CellType.ACTOR:
var target_pawn = get_cell_pawn(cell_target, cell_tile_id) var target_pawn = get_cell_pawn(cell_target, cell_tile_id)
print("Cell %s contains %s" % [cell_target, target_pawn.name]) print("Cell %s contains %s" % [cell_target, target_pawn.name])
if not target_pawn.has_node("DialoguePlayer"): if not target_pawn.has_node("DialoguePlayer"):
return return
get_node(dialogue_ui).show_dialogue(pawn, target_pawn.get_node("DialoguePlayer")) get_node(dialogue_ui).show_dialogue(pawn, target_pawn.get_node("DialoguePlayer"))

View File

@@ -7,7 +7,7 @@ func get_input_direction():
return Vector2() return Vector2()
var random_x = DIRECTIONS[randi() % DIRECTIONS.size()] var random_x = DIRECTIONS[randi() % DIRECTIONS.size()]
var random_y = DIRECTIONS[randi() % DIRECTIONS.size()] var random_y = DIRECTIONS[randi() % DIRECTIONS.size()]
var random_axis = randi() % 2 var random_axis = randi() % 2
if random_axis > 0: if random_axis > 0:
random_x = 0 random_x = 0

View File

@@ -42,9 +42,9 @@ func move_to(target_position):
$Tween.interpolate_property($Pivot, "position", move_direction * 32, Vector2(), $AnimationPlayer.current_animation_length, Tween.TRANS_LINEAR, Tween.EASE_IN) $Tween.interpolate_property($Pivot, "position", move_direction * 32, Vector2(), $AnimationPlayer.current_animation_length, Tween.TRANS_LINEAR, Tween.EASE_IN)
$Pivot/Sprite.position = position - target_position $Pivot/Sprite.position = position - target_position
position = target_position position = target_position
yield($AnimationPlayer, "animation_finished") yield($AnimationPlayer, "animation_finished")
set_process(true) set_process(true)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,7 @@ func set_active(value):
.set_active(value) .set_active(value)
if not active: if not active:
return return
$Timer.start() $Timer.start()
yield($Timer, \"timeout\") yield($Timer, \"timeout\")
var target var target

View File

@@ -10,7 +10,7 @@ func set_active(value):
active = value active = value
set_process(value) set_process(value)
set_process_input(value) set_process_input(value)
if not active: if not active:
return return
if $Health.armor >= $Health.base_armor + defense: if $Health.armor >= $Health.base_armor + defense:

View File

@@ -4,7 +4,7 @@ func set_active(value):
.set_active(value) .set_active(value)
if not active: if not active:
return return
$Timer.start() $Timer.start()
yield($Timer, "timeout") yield($Timer, "timeout")
var target var target

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -6,10 +6,10 @@ uniform float saturation = 1.8;
void fragment() { void fragment() {
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb; vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
c.rgb = mix(vec3(0.0), c.rgb, brightness); c.rgb = mix(vec3(0.0), c.rgb, brightness);
c.rgb = mix(vec3(0.5), c.rgb, contrast); c.rgb = mix(vec3(0.5), c.rgb, contrast);
c.rgb = mix(vec3(dot(vec3(1.0), c.rgb) * 0.33333), c.rgb, saturation); c.rgb = mix(vec3(dot(vec3(1.0), c.rgb) * 0.33333), c.rgb, saturation);
COLOR.rgb = c; COLOR.rgb = c;
} }

View File

@@ -8,6 +8,6 @@ void fragment() {
uv.x += sin(uv.y * frequency + TIME) * depth; uv.x += sin(uv.y * frequency + TIME) * depth;
uv.x = clamp(uv.x, 0.0, 1.0); uv.x = clamp(uv.x, 0.0, 1.0);
vec3 c = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb; vec3 c = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
COLOR.rgb = c; COLOR.rgb = c;
} }

View File

@@ -15,17 +15,17 @@ float make_grain(float time, vec2 uv) {
void fragment() { void fragment() {
vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb; vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
//float v = max(c.r, max(c.g, c.b)); //float v = max(c.r, max(c.g, c.b));
float v = dot(c, vec3(0.33333, 0.33333, 0.33333)); float v = dot(c, vec3(0.33333, 0.33333, 0.33333));
v = sqrt(v); v = sqrt(v);
//v *= v; //v *= v;
float f = 1.0 / fps; float f = 1.0 / fps;
float g = make_grain(TIME - mod(TIME, f), UV); float g = make_grain(TIME - mod(TIME, f), UV);
g = max(g, make_grain(TIME - mod(TIME, f) + f, UV) * 0.5); g = max(g, make_grain(TIME - mod(TIME, f) + f, UV) * 0.5);
g = max(g, make_grain(TIME - mod(TIME, f) + f * 2.0, UV) * 0.25); g = max(g, make_grain(TIME - mod(TIME, f) + f * 2.0, UV) * 0.25);
COLOR.rgb = base.rgb * v - vec3(g) * grain_strength; COLOR.rgb = base.rgb * v - vec3(g) * grain_strength;
COLOR.rgb *= texture(vignette, UV).r; COLOR.rgb *= texture(vignette, UV).r;
float ft = TIME * 0.002; float ft = TIME * 0.002;

View File

@@ -6,6 +6,6 @@ uniform float size_y = 0.008;
void fragment() { void fragment() {
vec2 uv = SCREEN_UV; vec2 uv = SCREEN_UV;
uv -= mod(uv, vec2(size_x, size_y)); uv -= mod(uv, vec2(size_x, size_y));
COLOR.rgb = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb; COLOR.rgb = textureLod(SCREEN_TEXTURE, uv, 0.0).rgb;
} }

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -52,61 +52,61 @@ func _ready():
if has_node("target") == false: if has_node("target") == false:
target = Spatial.new() target = Spatial.new()
add_child(target) add_child(target)
if Engine.editor_hint == true: if Engine.editor_hint:
if get_tree() != null: if get_tree() != null:
if get_tree().edited_scene_root != null: if get_tree().edited_scene_root != null:
target.set_owner(get_tree().edited_scene_root) target.set_owner(get_tree().edited_scene_root)
target.name = "target" target.name = "target"
else: else:
target = get_node("target") target = get_node("target")
# If we are in the editor, we want to make a sphere at this node # If we are in the editor, we want to make a sphere at this node
if Engine.editor_hint == true: if Engine.editor_hint:
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1)) _make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
if middle_joint_target == null: if middle_joint_target == null:
if has_node("middle_joint_target") == false: if has_node("middle_joint_target") == false:
middle_joint_target = Spatial.new() middle_joint_target = Spatial.new()
add_child(middle_joint_target) add_child(middle_joint_target)
if Engine.editor_hint == true: if Engine.editor_hint:
if get_tree() != null: if get_tree() != null:
if get_tree().edited_scene_root != null: if get_tree().edited_scene_root != null:
middle_joint_target.set_owner(get_tree().edited_scene_root) middle_joint_target.set_owner(get_tree().edited_scene_root)
middle_joint_target.name = "middle_joint_target" middle_joint_target.name = "middle_joint_target"
else: else:
middle_joint_target = get_node("middle_joint_target") middle_joint_target = get_node("middle_joint_target")
# If we are in the editor, we want to make a sphere at this node # If we are in the editor, we want to make a sphere at this node
if Engine.editor_hint == true: if Engine.editor_hint:
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1)) _make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
# Make all of the bone nodes for each bone in the IK chain # Make all of the bone nodes for each bone in the IK chain
_make_bone_nodes() _make_bone_nodes()
# Make sure we're using the right update mode # Make sure we're using the right update mode
_set_update_mode(update_mode) _set_update_mode(update_mode)
# Various upate methods # Various upate methods
func _process(_delta): func _process(_delta):
if reset_iterations_on_update == true: if reset_iterations_on_update:
chain_iterations = 0 chain_iterations = 0
update_skeleton() update_skeleton()
func _physics_process(_delta): func _physics_process(_delta):
if reset_iterations_on_update == true: if reset_iterations_on_update:
chain_iterations = 0 chain_iterations = 0
update_skeleton() update_skeleton()
func _notification(what): func _notification(what):
if what == NOTIFICATION_TRANSFORM_CHANGED: if what == NOTIFICATION_TRANSFORM_CHANGED:
if reset_iterations_on_update == true: if reset_iterations_on_update:
chain_iterations = 0 chain_iterations = 0
update_skeleton() update_skeleton()
@@ -115,51 +115,51 @@ func _notification(what):
func update_skeleton(): func update_skeleton():
#### ERROR CHECKING conditions #### ERROR CHECKING conditions
if first_call == true: if first_call:
_set_skeleton_path(skeleton_path) _set_skeleton_path(skeleton_path)
first_call = false first_call = false
if skeleton == null: if skeleton == null:
_set_skeleton_path(skeleton_path) _set_skeleton_path(skeleton_path)
return return
if bones_in_chain == null: if bones_in_chain == null:
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: No Bones in IK chain defined!") printerr(name, " - IK_FABRIK: No Bones in IK chain defined!")
return return
if bones_in_chain_lengths == null: if bones_in_chain_lengths == null:
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: No Bone lengths in IK chain defined!") printerr(name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
return return
if bones_in_chain.size() != bones_in_chain_lengths.size(): if bones_in_chain.size() != bones_in_chain_lengths.size():
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!") printerr(name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!")
return return
################################ ################################
# Set all of the bone IDs in bone_IDs, if they are not already made # Set all of the bone IDs in bone_IDs, if they are not already made
var i = 0 var i = 0
if bone_IDs.size() <= 0: if bone_IDs.size() <= 0:
for bone_name in bones_in_chain: for bone_name in bones_in_chain:
bone_IDs[bone_name] = skeleton.find_bone(bone_name) bone_IDs[bone_name] = skeleton.find_bone(bone_name)
# Set the bone node to the currect bone position # Set the bone node to the currect bone position
bone_nodes[i].global_transform = get_bone_transform(i) bone_nodes[i].global_transform = get_bone_transform(i)
# If this is not the last bone in the bone chain, make it look at the next bone in the bone chain # If this is not the last bone in the bone chain, make it look at the next bone in the bone chain
if i < bone_IDs.size()-1: if i < bone_IDs.size()-1:
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3.UP) bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3.UP)
i += 1 i += 1
# Set the total length of the bone chain, if it is not already set # Set the total length of the bone chain, if it is not already set
if total_length == INF: if total_length == INF:
total_length = 0 total_length = 0
for bone_length in bones_in_chain_lengths: for bone_length in bones_in_chain_lengths:
total_length += bone_length total_length += bone_length
# Solve the bone chain # Solve the bone chain
solve_chain() solve_chain()
@@ -167,14 +167,14 @@ func update_skeleton():
func solve_chain(): func solve_chain():
# If we have reached our max chain iteration, and we are limiting ourselves, then return. # If we have reached our max chain iteration, and we are limiting ourselves, then return.
# Otherwise set chain_iterations to zero (so we constantly update) # Otherwise set chain_iterations to zero (so we constantly update)
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations == true: if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations:
return return
else: else:
chain_iterations = 0 chain_iterations = 0
# Update the origin with the current bone's origin # Update the origin with the current bone's origin
chain_origin = get_bone_transform(0).origin chain_origin = get_bone_transform(0).origin
# Get the direction of the final bone by using the next to last bone if there is more than 2 bones. # Get the direction of the final bone by using the next to last bone if there is more than 2 bones.
# If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well) # If there are only 2 bones, we use the target's forward Z vector instead (not ideal, but it works fairly well)
var dir var dir
@@ -182,19 +182,19 @@ func solve_chain():
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized() dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
else: else:
dir = -target.global_transform.basis.z.normalized() dir = -target.global_transform.basis.z.normalized()
# Get the target position (accounting for the final bone and it's length) # Get the target position (accounting for the final bone and it's length)
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1]) var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it! # If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
if use_middle_joint_target == true: if use_middle_joint_target:
if bone_nodes.size() > 2: if bone_nodes.size() > 2:
var middle_point_pos = middle_joint_target.global_transform var middle_point_pos = middle_joint_target.global_transform
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
# Get the distance from the origin to the target # Get the distance from the origin to the target
var distance = (chain_origin - target_pos).length() var distance = (chain_origin - target_pos).length()
# If the distance is farther than our total reach, the target cannot be reached. # If the distance is farther than our total reach, the target cannot be reached.
# Make the bone chain a straight line pointing towards the target # Make the bone chain a straight line pointing towards the target
if distance > total_length: if distance > total_length:
@@ -203,37 +203,37 @@ func solve_chain():
var curr_origin = bone_nodes[i].global_transform.origin var curr_origin = bone_nodes[i].global_transform.origin
var r =(target_pos - curr_origin).length() var r =(target_pos - curr_origin).length()
var l = bones_in_chain_lengths[i] / r var l = bones_in_chain_lengths[i] / r
# Find new join position # Find new join position
var new_pos = curr_origin.linear_interpolate(target_pos, l) var new_pos = curr_origin.linear_interpolate(target_pos, l)
# Apply it to the bone node # Apply it to the bone node
bone_nodes[i].look_at(new_pos, Vector3.UP) bone_nodes[i].look_at(new_pos, Vector3.UP)
bone_nodes[i].global_transform.origin = new_pos bone_nodes[i].global_transform.origin = new_pos
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain # Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3.UP) bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3.UP)
# If the distance is NOT farther than our total reach, the target can be reached. # If the distance is NOT farther than our total reach, the target can be reached.
else: else:
# Get the difference between our end effector (the final bone in the chain) and the target # Get the difference between our end effector (the final bone in the chain) and the target
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length() var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE). # Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation) # If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
while dif > CHAIN_TOLERANCE: while dif > CHAIN_TOLERANCE:
chain_backward() chain_backward()
chain_forward() chain_forward()
chain_apply_rotation() chain_apply_rotation()
# Update the difference between our end effector (the final bone in the chain) and the target # Update the difference between our end effector (the final bone in the chain) and the target
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length() dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
# Add one to chain_iterations. If we have reached our max iterations, then break # Add one to chain_iterations. If we have reached our max iterations, then break
chain_iterations = chain_iterations + 1 chain_iterations = chain_iterations + 1
if chain_iterations >= CHAIN_MAX_ITER: if chain_iterations >= CHAIN_MAX_ITER:
break break
# Reset the bone node transforms to the skeleton bone transforms # Reset the bone node transforms to the skeleton bone transforms
#if constrained == false: # Resetting seems to break bone constraints... #if constrained == false: # Resetting seems to break bone constraints...
for i in range(0, bone_nodes.size()): for i in range(0, bone_nodes.size()):
@@ -250,17 +250,17 @@ func chain_backward():
dir = bone_nodes[bone_nodes.size() - 2].global_transform.basis.z.normalized() dir = bone_nodes[bone_nodes.size() - 2].global_transform.basis.z.normalized()
else: else:
dir = -target.global_transform.basis.z.normalized() dir = -target.global_transform.basis.z.normalized()
# Set the position of the end effector (the final bone in the chain) to the target position # Set the position of the end effector (the final bone in the chain) to the target position
bone_nodes[bone_nodes.size()-1].global_transform.origin = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1]) bone_nodes[bone_nodes.size()-1].global_transform.origin = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
# For all of the other bones, move them towards the target # For all of the other bones, move them towards the target
var i = bones_in_chain.size() - 1 var i = bones_in_chain.size() - 1
while i >= 1: while i >= 1:
var prev_origin = bone_nodes[i].global_transform.origin var prev_origin = bone_nodes[i].global_transform.origin
i -= 1 i -= 1
var curr_origin = bone_nodes[i].global_transform.origin var curr_origin = bone_nodes[i].global_transform.origin
var r = prev_origin - curr_origin var r = prev_origin - curr_origin
var l = bones_in_chain_lengths[i] / r.length() var l = bones_in_chain_lengths[i] / r.length()
# Apply the new joint position # Apply the new joint position
@@ -271,12 +271,12 @@ func chain_backward():
func chain_forward(): func chain_forward():
# Set root at initial position # Set root at initial position
bone_nodes[0].global_transform.origin = chain_origin bone_nodes[0].global_transform.origin = chain_origin
# Go through every bone in the bone chain # Go through every bone in the bone chain
for i in range(bones_in_chain.size() - 1): for i in range(bones_in_chain.size() - 1):
var curr_origin = bone_nodes[i].global_transform.origin var curr_origin = bone_nodes[i].global_transform.origin
var next_origin = bone_nodes[i + 1].global_transform.origin var next_origin = bone_nodes[i + 1].global_transform.origin
var r = next_origin - curr_origin var r = next_origin - curr_origin
var l = bones_in_chain_lengths[i] / r.length() var l = bones_in_chain_lengths[i] / r.length()
# Apply the new joint position, (potentially with constraints), to the bone node # Apply the new joint position, (potentially with constraints), to the bone node
@@ -297,38 +297,38 @@ func chain_apply_rotation():
# Get the bone node for this bone, and the previous bone # Get the bone node for this bone, and the previous bone
var b_target = bone_nodes[i].global_transform var b_target = bone_nodes[i].global_transform
var b_target_two = bone_nodes[i-1].global_transform var b_target_two = bone_nodes[i-1].global_transform
# Convert the bone nodes positions from world space to bone/skeleton space # Convert the bone nodes positions from world space to bone/skeleton space
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin) b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin) b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
# Get the direction that the previous bone is pointing towards # Get the direction that the previous bone is pointing towards
var dir = (target.global_transform.origin - b_target_two.origin).normalized() var dir = (target.global_transform.origin - b_target_two.origin).normalized()
# Make this bone look in the same the direction as the last bone # Make this bone look in the same the direction as the last bone
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP) bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
else: else:
var b_target = target.global_transform var b_target = target.global_transform
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin) b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP) bone_trans = bone_trans.looking_at(b_target.origin, Vector3.UP)
# If this is NOT the last bone in the bone chain, rotate the bone to look at the next # If this is NOT the last bone in the bone chain, rotate the bone to look at the next
# bone in the bone chain. # bone in the bone chain.
else: else:
# Get the bone node for this bone, and the next bone # Get the bone node for this bone, and the next bone
var b_target = bone_nodes[i].global_transform var b_target = bone_nodes[i].global_transform
var b_target_two = bone_nodes[i+1].global_transform var b_target_two = bone_nodes[i+1].global_transform
# Convert the bone nodes positions from world space to bone/skeleton space # Convert the bone nodes positions from world space to bone/skeleton space
b_target.origin = skeleton.global_transform.xform_inv(b_target.origin) b_target.origin = skeleton.global_transform.xform_inv(b_target.origin)
b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin) b_target_two.origin = skeleton.global_transform.xform_inv(b_target_two.origin)
# Get the direction towards the next bone # Get the direction towards the next bone
var dir = (b_target_two.origin - b_target.origin).normalized() var dir = (b_target_two.origin - b_target.origin).normalized()
# Make this bone look towards the direction of the next bone # Make this bone look towards the direction of the next bone
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP) bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3.UP)
# The the bone's (updated) transform # The the bone's (updated) transform
set_bone_transform(i, bone_trans) set_bone_transform(i, bone_trans)
@@ -336,12 +336,12 @@ func chain_apply_rotation():
func get_bone_transform(bone, convert_to_world_space = true): func get_bone_transform(bone, convert_to_world_space = true):
# Get the global transform of the bone # Get the global transform of the bone
var ret: Transform = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]]) var ret: Transform = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
# If we need to convert the bone position from bone/skeleton space to world space, we # If we need to convert the bone position from bone/skeleton space to world space, we
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node). # use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
if convert_to_world_space == true: if convert_to_world_space:
ret.origin = skeleton.global_transform.xform(ret.origin) ret.origin = skeleton.global_transform.xform(ret.origin)
return ret return ret
@@ -381,11 +381,11 @@ func _make_editor_sphere_at_node(node, color):
func _set_update_mode(new_value): func _set_update_mode(new_value):
update_mode = new_value update_mode = new_value
set_process(false) set_process(false)
set_physics_process(false) set_physics_process(false)
set_notify_transform(false) set_notify_transform(false)
if update_mode == 0: if update_mode == 0:
set_process(true) set_process(true)
elif update_mode == 1: elif update_mode == 1:
@@ -393,43 +393,43 @@ func _set_update_mode(new_value):
elif update_mode == 2: elif update_mode == 2:
set_notify_transform(true) set_notify_transform(true)
else: else:
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton") printerr(name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
return return
func _set_skeleton_path(new_value): func _set_skeleton_path(new_value):
# Because get_node doesn't work in the first call, we just want to assign instead # Because get_node doesn't work in the first call, we just want to assign instead
if first_call == true: if first_call:
skeleton_path = new_value skeleton_path = new_value
return return
skeleton_path = new_value skeleton_path = new_value
if skeleton_path == null: if skeleton_path == null:
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!") printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
return return
var temp = get_node(skeleton_path) var temp = get_node(skeleton_path)
if temp != null: if temp != null:
# If it has the method "get_bone_global_pose" it is likely a Skeleton # If it has the method "get_bone_global_pose" it is likely a Skeleton
if temp.has_method("get_bone_global_pose") == true: if temp.has_method("get_bone_global_pose"):
skeleton = temp skeleton = temp
bone_IDs = {} bone_IDs = {}
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain # (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
_make_bone_nodes() _make_bone_nodes()
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: Attached to a new skeleton") printerr(name, " - IK_FABRIK: Attached to a new skeleton")
# If not, then it's (likely) not a Skeleton node # If not, then it's (likely) not a Skeleton node
else: else:
skeleton = null skeleton = null
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: skeleton_path does not point to a skeleton!") printerr(name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
else: else:
if debug_messages == true: if debug_messages:
printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!") printerr(name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
@@ -438,33 +438,33 @@ func _set_skeleton_path(new_value):
func _make_bone_nodes(): func _make_bone_nodes():
# Remove all of the old bone nodes # Remove all of the old bone nodes
# TODO: (not a huge concern, as these can be removed in the editor) # TODO: (not a huge concern, as these can be removed in the editor)
for bone in range(0, bones_in_chain.size()): for bone in range(0, bones_in_chain.size()):
var bone_name = bones_in_chain[bone] var bone_name = bones_in_chain[bone]
if has_node(bone_name) == false: if has_node(bone_name) == false:
var new_node = Spatial.new() var new_node = Spatial.new()
bone_nodes[bone] = new_node bone_nodes[bone] = new_node
add_child(bone_nodes[bone]) add_child(bone_nodes[bone])
if Engine.editor_hint == true: if Engine.editor_hint:
if get_tree() != null: if get_tree() != null:
if get_tree().edited_scene_root != null: if get_tree().edited_scene_root != null:
bone_nodes[bone].set_owner(get_tree().edited_scene_root) bone_nodes[bone].set_owner(get_tree().edited_scene_root)
bone_nodes[bone].name = bone_name bone_nodes[bone].name = bone_name
else: else:
bone_nodes[bone] = get_node(bone_name) bone_nodes[bone] = get_node(bone_name)
# If we are in the editor, we want to make a sphere at this node # If we are in the editor, we want to make a sphere at this node
if Engine.editor_hint == true: if Engine.editor_hint:
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1)) _make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
func _set_bone_chain_bones(new_value): func _set_bone_chain_bones(new_value):
bones_in_chain = new_value bones_in_chain = new_value
_make_bone_nodes() _make_bone_nodes()

View File

@@ -20,7 +20,7 @@ func _ready():
set_process(false) set_process(false)
set_physics_process(false) set_physics_process(false)
set_notify_transform(false) set_notify_transform(false)
if update_mode == 0: if update_mode == 0:
set_process(true) set_process(true)
elif update_mode == 1: elif update_mode == 1:
@@ -28,10 +28,10 @@ func _ready():
elif update_mode == 2: elif update_mode == 2:
set_notify_transform(true) set_notify_transform(true)
else: else:
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton") print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
if Engine.editor_hint == true: if Engine.editor_hint:
_setup_for_editor() _setup_for_editor()
@@ -51,33 +51,33 @@ func _notification(what):
func update_skeleton(): func update_skeleton():
# NOTE: Because get_node doesn't work in _ready, we need to skip # NOTE: Because get_node doesn't work in _ready, we need to skip
# a call before doing anything. # a call before doing anything.
if first_call == true: if first_call:
first_call = false first_call = false
if skeleton_to_use == null: if skeleton_to_use == null:
_set_skeleton_path(skeleton_path) _set_skeleton_path(skeleton_path)
# If we do not have a skeleton and/or we're not supposed to update, then return. # If we do not have a skeleton and/or we're not supposed to update, then return.
if skeleton_to_use == null: if skeleton_to_use == null:
return return
if update_mode >= 3: if update_mode >= 3:
return return
# Get the bone # Get the bone
var bone = skeleton_to_use.find_bone(bone_name) var bone = skeleton_to_use.find_bone(bone_name)
# If no bone is found (-1), then return (and optionally print an error) # If no bone is found (-1), then return (and optionally print an error)
if bone == -1: if bone == -1:
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!") print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
return return
# get the bone's rest position # get the bone's rest position
var rest = skeleton_to_use.get_bone_global_pose(bone) var rest = skeleton_to_use.get_bone_global_pose(bone)
# Convert our position relative to the skeleton's transform # Convert our position relative to the skeleton's transform
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin) var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
# Call helper's look_at function with the chosen up axis. # Call helper's look_at function with the chosen up axis.
if look_at_axis == 0: if look_at_axis == 0:
rest = rest.looking_at(target_pos, Vector3(1, 0, 0)) rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
@@ -87,34 +87,34 @@ func update_skeleton():
rest = rest.looking_at(target_pos, Vector3(0, 0, 1)) rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
else: else:
rest = rest.looking_at(target_pos, Vector3(0, 1, 0)) rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: Unknown look_at_axis value!") print (name, " - IK_LookAt: Unknown look_at_axis value!")
# Get our rotation euler, and the bone's rotation euler # Get our rotation euler, and the bone's rotation euler
var rest_euler = rest.basis.get_euler() var rest_euler = rest.basis.get_euler()
var self_euler = global_transform.basis.orthonormalized().get_euler() var self_euler = global_transform.basis.orthonormalized().get_euler()
# If we using negative rotation, we flip our rotation euler # If we using negative rotation, we flip our rotation euler
if use_negative_our_rot == true: if use_negative_our_rot:
self_euler = -self_euler self_euler = -self_euler
# Apply our rotation euler, if wanted/required # Apply our rotation euler, if wanted/required
if use_our_rotation_x == true: if use_our_rotation_x:
rest_euler.x = self_euler.x rest_euler.x = self_euler.x
if use_our_rotation_y == true: if use_our_rotation_y:
rest_euler.y = self_euler.y rest_euler.y = self_euler.y
if use_our_rotation_z == true: if use_our_rotation_z:
rest_euler.z = self_euler.z rest_euler.z = self_euler.z
# Rotate the bone by the (potentially) changed euler angle(s) # Rotate the bone by the (potentially) changed euler angle(s)
rest.basis = Basis(rest_euler) rest.basis = Basis(rest_euler)
# If we have additional rotation, then rotate it by the local rotation vectors # If we have additional rotation, then rotate it by the local rotation vectors
if additional_rotation != Vector3.ZERO: if additional_rotation != Vector3.ZERO:
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x)) rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y)) rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z)) rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
# Finally, apply the bone rotation to the skeleton # Finally, apply the bone rotation to the skeleton
skeleton_to_use.set_bone_global_pose(bone, rest) skeleton_to_use.set_bone_global_pose(bone, rest)
@@ -146,58 +146,58 @@ func _setup_for_editor():
func _set_update(new_value): func _set_update(new_value):
update_mode = new_value update_mode = new_value
# Set all of our processes to false # Set all of our processes to false
set_process(false) set_process(false)
set_physics_process(false) set_physics_process(false)
set_notify_transform(false) set_notify_transform(false)
# Based on the value of upate, change how we handle updating the skeleton # Based on the value of upate, change how we handle updating the skeleton
if update_mode == 0: if update_mode == 0:
set_process(true) set_process(true)
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: updating skeleton using _process...") print (name, " - IK_LookAt: updating skeleton using _process...")
elif update_mode == 1: elif update_mode == 1:
set_physics_process(true) set_physics_process(true)
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: updating skeleton using _physics_process...") print (name, " - IK_LookAt: updating skeleton using _physics_process...")
elif update_mode == 2: elif update_mode == 2:
set_notify_transform(true) set_notify_transform(true)
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: updating skeleton using _notification...") print (name, " - IK_LookAt: updating skeleton using _notification...")
else: else:
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...") print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
func _set_skeleton_path(new_value): func _set_skeleton_path(new_value):
# Because get_node doesn't work in the first call, we just want to assign instead # Because get_node doesn't work in the first call, we just want to assign instead
# This is to get around a issue with NodePaths exposed to the editor # This is to get around a issue with NodePaths exposed to the editor
if first_call == true: if first_call:
skeleton_path = new_value skeleton_path = new_value
return return
# Assign skeleton_path to whatever value is passed # Assign skeleton_path to whatever value is passed
skeleton_path = new_value skeleton_path = new_value
if skeleton_path == null: if skeleton_path == null:
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!") print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
return return
# Get the node at that location, if there is one # Get the node at that location, if there is one
var temp = get_node(skeleton_path) var temp = get_node(skeleton_path)
if temp != null: if temp != null:
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton # If the node has the method "find_bone" then we can assume it is (likely) a skeleton
if temp.has_method("find_bone") == true: if temp.has_method("find_bone"):
skeleton_to_use = temp skeleton_to_use = temp
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: attached to (new) skeleton") print (name, " - IK_LookAt: attached to (new) skeleton")
# If not, then it's (likely) not a skeleton # If not, then it's (likely) not a skeleton
else: else:
skeleton_to_use = null skeleton_to_use = null
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!") print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
else: else:
if debug_messages == true: if debug_messages:
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!") print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")

View File

@@ -3,7 +3,7 @@ extends EditorPlugin
func _enter_tree(): func _enter_tree():
# Plugin Initialization here! # Plugin Initialization here!
# ------ IK STUFF ------ # ------ IK STUFF ------
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png")) add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png")) add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
@@ -12,7 +12,7 @@ func _enter_tree():
func _exit_tree(): func _exit_tree():
# Plugin Clean-up here! # Plugin Clean-up here!
# ------ IK STUFF ------ # ------ IK STUFF ------
remove_custom_type("IK_LookAt") remove_custom_type("IK_LookAt")
remove_custom_type("IK_FABRIK") remove_custom_type("IK_FABRIK")

View File

@@ -55,16 +55,16 @@ var simple_bullet = preload("res://fps/simple_bullet.tscn")
func _ready(): func _ready():
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera") camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
camera_holder = get_node("CameraHolder") camera_holder = get_node("CameraHolder")
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow") path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
anim_player = get_node("CameraHolder/AnimationPlayer") anim_player = get_node("CameraHolder/AnimationPlayer")
anim_player.connect("animation_finished", self, "animation_finished") anim_player.connect("animation_finished", self, "animation_finished")
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end") pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
set_physics_process(true) set_physics_process(true)
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
set_process_input(true) set_process_input(true)
@@ -76,12 +76,12 @@ func _physics_process(delta):
func process_input(delta): func process_input(delta):
# Reset dir, so our previous movement does not effect us # Reset dir, so our previous movement does not effect us
dir = Vector3() dir = Vector3()
# Get the camera's global transform so we can use its directional vectors # Get the camera's global transform so we can use its directional vectors
var cam_xform = camera.get_global_transform() var cam_xform = camera.get_global_transform()
# ---------------------------------- # ----------------------------------
# Walking # Walking
if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W): if Input.is_key_pressed(KEY_UP) or Input.is_key_pressed(KEY_W):
@@ -92,33 +92,33 @@ func process_input(delta):
dir += -cam_xform.basis[0] dir += -cam_xform.basis[0]
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D): if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
dir += cam_xform.basis[0] dir += cam_xform.basis[0]
if Input.is_action_just_pressed("ui_cancel"): if Input.is_action_just_pressed("ui_cancel"):
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE: if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
else: else:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
if Input.is_mouse_button_pressed(2): if Input.is_mouse_button_pressed(2):
if right_mouse_down == false: if right_mouse_down == false:
right_mouse_down = true right_mouse_down = true
if anim_done == true: if anim_done:
if current_anim != "Aiming": if current_anim != "Aiming":
anim_player.play("Aiming") anim_player.play("Aiming")
current_anim = "Aiming" current_anim = "Aiming"
else: else:
anim_player.play("Idle") anim_player.play("Idle")
current_anim = "Idle" current_anim = "Idle"
anim_done = false anim_done = false
else: else:
right_mouse_down = false right_mouse_down = false
if Input.is_mouse_button_pressed(1): if Input.is_mouse_button_pressed(1):
if left_mouse_timer <= 0: if left_mouse_timer <= 0:
left_mouse_timer = LEFT_MOUSE_FIRE_TIME left_mouse_timer = LEFT_MOUSE_FIRE_TIME
# Create a bullet # Create a bullet
var new_bullet = simple_bullet.instance() var new_bullet = simple_bullet.instance()
get_tree().root.add_child(new_bullet) get_tree().root.add_child(new_bullet)
@@ -127,8 +127,8 @@ func process_input(delta):
if left_mouse_timer > 0: if left_mouse_timer > 0:
left_mouse_timer -= delta left_mouse_timer -= delta
# ---------------------------------- # ----------------------------------
# ---------------------------------- # ----------------------------------
# Sprinting # Sprinting
if Input.is_key_pressed(KEY_SHIFT): if Input.is_key_pressed(KEY_SHIFT):
@@ -136,7 +136,7 @@ func process_input(delta):
else: else:
is_sprinting = false is_sprinting = false
# ---------------------------------- # ----------------------------------
# ---------------------------------- # ----------------------------------
# Jumping # Jumping
if Input.is_key_pressed(KEY_SPACE): if Input.is_key_pressed(KEY_SPACE):
@@ -147,8 +147,8 @@ func process_input(delta):
else: else:
jump_button_down = false jump_button_down = false
# ---------------------------------- # ----------------------------------
# ---------------------------------- # ----------------------------------
# Leaninng # Leaninng
if Input.is_key_pressed(KEY_Q): if Input.is_key_pressed(KEY_Q):
@@ -164,7 +164,7 @@ func process_input(delta):
lean_value += 1 * delta lean_value += 1 * delta
if lean_value > 0.5: if lean_value > 0.5:
lean_value = 0.5 lean_value = 0.5
lean_value = clamp(lean_value, 0, 1) lean_value = clamp(lean_value, 0, 1)
path_follow_node.unit_offset = lean_value path_follow_node.unit_offset = lean_value
if lean_value < 0.5: if lean_value < 0.5:
@@ -177,24 +177,24 @@ func process_input(delta):
func process_movement(delta): func process_movement(delta):
var grav = norm_grav var grav = norm_grav
dir.y = 0 dir.y = 0
dir = dir.normalized() dir = dir.normalized()
vel.y += delta*grav vel.y += delta*grav
var hvel = vel var hvel = vel
hvel.y = 0 hvel.y = 0
var target = dir var target = dir
if is_sprinting: if is_sprinting:
target *= MAX_SPRINT_SPEED target *= MAX_SPRINT_SPEED
else: else:
target *= MAX_SPEED target *= MAX_SPEED
var accel var accel
if dir.dot(hvel) > 0: if dir.dot(hvel) > 0:
if is_sprinting == false: if is_sprinting == false:
@@ -203,32 +203,32 @@ func process_movement(delta):
accel = SPRINT_ACCEL accel = SPRINT_ACCEL
else: else:
accel = DEACCEL accel = DEACCEL
hvel = hvel.linear_interpolate(target, accel*delta) hvel = hvel.linear_interpolate(target, accel*delta)
vel.x = hvel.x vel.x = hvel.x
vel.z = hvel.z vel.z = hvel.z
vel = move_and_slide(vel,Vector3(0,1,0)) vel = move_and_slide(vel,Vector3(0,1,0))
# Mouse based camera movement # Mouse based camera movement
func _input(event): func _input(event):
if event is InputEventMouseMotion && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: if event is InputEventMouseMotion && Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1)) rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY)) camera_holder.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
# We need to clamp the camera's rotation so we cannot rotate ourselves upside down # We need to clamp the camera's rotation so we cannot rotate ourselves upside down
var camera_rot = camera_holder.rotation_degrees var camera_rot = camera_holder.rotation_degrees
if camera_rot.x < -40: if camera_rot.x < -40:
camera_rot.x = -40 camera_rot.x = -40
elif camera_rot.x > 60: elif camera_rot.x > 60:
camera_rot.x = 60 camera_rot.x = 60
camera_holder.rotation_degrees = camera_rot camera_holder.rotation_degrees = camera_rot
else: else:
pass pass

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -12,10 +12,10 @@ func _ready():
func _process(_delta): func _process(_delta):
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
if flip_axis == false: if flip_axis == false:
mouse_to_world.z *= -1 mouse_to_world.z *= -1
else: else:
mouse_to_world = -mouse_to_world mouse_to_world = -mouse_to_world
targets.transform.origin = mouse_to_world targets.transform.origin = mouse_to_world

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -40,7 +40,7 @@ func _unhandled_input(ev):
zoom += ZOOM_SPEED zoom += ZOOM_SPEED
zoom = clamp(zoom, 2, 8) zoom = clamp(zoom, 2, 8)
camera.translation.z = zoom camera.translation.z = zoom
if ev is InputEventMouseMotion and ev.button_mask & MAIN_BUTTONS: if ev is InputEventMouseMotion and ev.button_mask & MAIN_BUTTONS:
# Compensate motion speed to be resolution-independent (based on the window height). # Compensate motion speed to be resolution-independent (based on the window height).
var relative_motion = ev.relative * get_viewport().size.y / base_height var relative_motion = ev.relative * get_viewport().size.y / base_height

View File

@@ -33,16 +33,16 @@ func _process(delta):
else: else:
path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk / d) path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk / d)
to_walk = 0 to_walk = 0
var atpos = path[path.size() - 1] var atpos = path[path.size() - 1]
var atdir = to_watch var atdir = to_watch
atdir.y = 0 atdir.y = 0
var t = Transform() var t = Transform()
t.origin = atpos t.origin = atpos
t = t.looking_at(atpos + atdir, Vector3.UP) t = t.looking_at(atpos + atdir, Vector3.UP)
get_node("RobotBase").set_transform(t) get_node("RobotBase").set_transform(t)
if path.size() < 2: if path.size() < 2:
path = [] path = []
set_process(false) set_process(false)
@@ -55,11 +55,11 @@ func _input(event):
var from = get_node("CameraBase/Camera").project_ray_origin(event.position) var from = get_node("CameraBase/Camera").project_ray_origin(event.position)
var to = from + get_node("CameraBase/Camera").project_ray_normal(event.position) * 100 var to = from + get_node("CameraBase/Camera").project_ray_normal(event.position) * 100
var p = get_closest_point_to_segment(from, to) var p = get_closest_point_to_segment(from, to)
begin = get_closest_point(get_node("RobotBase").get_translation()) begin = get_closest_point(get_node("RobotBase").get_translation())
end = p end = p
_update_path() _update_path()
if event is InputEventMouseMotion: if event is InputEventMouseMotion:
if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT): if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT):
camrot += event.relative.x * 0.005 camrot += event.relative.x * 0.005
@@ -72,7 +72,7 @@ func _update_path():
path = Array(p) # Vector3 array too complex to use, convert to regular array. path = Array(p) # Vector3 array too complex to use, convert to regular array.
path.invert() path.invert()
set_process(true) set_process(true)
if draw_path: if draw_path:
var im = get_node("Draw") var im = get_node("Draw")
im.set_material_override(m) im.set_material_override(m)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -24,15 +24,15 @@ func _integrate_forces(state):
lv += g * delta # Apply gravity. lv += g * delta # Apply gravity.
var up = -g.normalized() var up = -g.normalized()
if dying: if dying:
state.set_linear_velocity(lv) state.set_linear_velocity(lv)
return return
for i in range(state.get_contact_count()): for i in range(state.get_contact_count()):
var cc = state.get_contact_collider_object(i) var cc = state.get_contact_collider_object(i)
var dp = state.get_contact_local_normal(i) var dp = state.get_contact_local_normal(i)
if cc: if cc:
if cc is preload("res://bullet.gd") and cc.enabled: if cc is preload("res://bullet.gd") and cc.enabled:
set_mode(MODE_RIGID) set_mode(MODE_RIGID)
@@ -43,15 +43,15 @@ func _integrate_forces(state):
cc.enabled = false cc.enabled = false
get_node("SoundHit").play() get_node("SoundHit").play()
return return
var col_floor = get_node("Armature/RayFloor").is_colliding() var col_floor = get_node("Armature/RayFloor").is_colliding()
var col_wall = get_node("Armature/RayWall").is_colliding() var col_wall = get_node("Armature/RayWall").is_colliding()
var advance = col_floor and not col_wall var advance = col_floor and not col_wall
var dir = get_node("Armature").get_transform().basis[2].normalized() var dir = get_node("Armature").get_transform().basis[2].normalized()
var deaccel_dir = dir var deaccel_dir = dir
if advance: if advance:
if dir.dot(lv) < max_speed: if dir.dot(lv) < max_speed:
lv += dir * accel * delta lv += dir * accel * delta
@@ -59,17 +59,17 @@ func _integrate_forces(state):
else: else:
if prev_advance: if prev_advance:
rot_dir = 1 rot_dir = 1
dir = Basis(up, rot_dir * rot_speed * delta).xform(dir) dir = Basis(up, rot_dir * rot_speed * delta).xform(dir)
get_node("Armature").set_transform(Transform().looking_at(-dir, up)) get_node("Armature").set_transform(Transform().looking_at(-dir, up))
var dspeed = deaccel_dir.dot(lv) var dspeed = deaccel_dir.dot(lv)
dspeed -= deaccel * delta dspeed -= deaccel * delta
if dspeed < 0: if dspeed < 0:
dspeed = 0 dspeed = 0
lv = lv - deaccel_dir * deaccel_dir.dot(lv) + deaccel_dir * dspeed lv = lv - deaccel_dir * deaccel_dir.dot(lv) + deaccel_dir * dspeed
state.set_linear_velocity(lv) state.set_linear_velocity(lv)
prev_advance = advance prev_advance = advance

View File

@@ -32,15 +32,15 @@ func _ready():
func _physics_process(delta): func _physics_process(delta):
linear_velocity += gravity * delta linear_velocity += gravity * delta
var anim = ANIM_FLOOR var anim = ANIM_FLOOR
var vv = linear_velocity.y # Vertical velocity. var vv = linear_velocity.y # Vertical velocity.
var hv = Vector3(linear_velocity.x, 0, linear_velocity.z) # Horizontal velocity. var hv = Vector3(linear_velocity.x, 0, linear_velocity.z) # Horizontal velocity.
var hdir = hv.normalized() # Horizontal direction. var hdir = hv.normalized() # Horizontal direction.
var hspeed = hv.length() # Horizontal speed. var hspeed = hv.length() # Horizontal speed.
# Player input # Player input
var cam_basis = get_node("Target/Camera").get_global_transform().basis var cam_basis = get_node("Target/Camera").get_global_transform().basis
var dir = Vector3() # Where does the player intend to walk to. var dir = Vector3() # Where does the player intend to walk to.
@@ -50,39 +50,39 @@ func _physics_process(delta):
dir -= Input.get_action_strength("move_forward") * cam_basis[2] dir -= Input.get_action_strength("move_forward") * cam_basis[2]
dir.y = 0 dir.y = 0
dir = dir.normalized() dir = dir.normalized()
var jump_attempt = Input.is_action_pressed("jump") var jump_attempt = Input.is_action_pressed("jump")
var shoot_attempt = Input.is_action_pressed("shoot") var shoot_attempt = Input.is_action_pressed("shoot")
if is_on_floor(): if is_on_floor():
var sharp_turn = hspeed > 0.1 and rad2deg(acos(dir.dot(hdir))) > sharp_turn_threshold var sharp_turn = hspeed > 0.1 and rad2deg(acos(dir.dot(hdir))) > sharp_turn_threshold
if dir.length() > 0.1 and !sharp_turn: if dir.length() > 0.1 and !sharp_turn:
if hspeed > 0.001: if hspeed > 0.001:
hdir = adjust_facing(hdir, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP) hdir = adjust_facing(hdir, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
facing_dir = hdir facing_dir = hdir
else: else:
hdir = dir hdir = dir
if hspeed < max_speed: if hspeed < max_speed:
hspeed += accel * delta hspeed += accel * delta
else: else:
hspeed -= deaccel * delta hspeed -= deaccel * delta
if hspeed < 0: if hspeed < 0:
hspeed = 0 hspeed = 0
hv = hdir * hspeed hv = hdir * hspeed
var mesh_xform = get_node("Armature").get_transform() var mesh_xform = get_node("Armature").get_transform()
var facing_mesh = -mesh_xform.basis[0].normalized() var facing_mesh = -mesh_xform.basis[0].normalized()
facing_mesh = (facing_mesh - Vector3.UP * facing_mesh.dot(Vector3.UP)).normalized() facing_mesh = (facing_mesh - Vector3.UP * facing_mesh.dot(Vector3.UP)).normalized()
if hspeed > 0: if hspeed > 0:
facing_mesh = adjust_facing(facing_mesh, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP) facing_mesh = adjust_facing(facing_mesh, dir, delta, 1.0 / hspeed * TURN_SPEED, Vector3.UP)
var m3 = Basis(-facing_mesh, Vector3.UP, -facing_mesh.cross(Vector3.UP).normalized()).scaled(CHAR_SCALE) var m3 = Basis(-facing_mesh, Vector3.UP, -facing_mesh.cross(Vector3.UP).normalized()).scaled(CHAR_SCALE)
get_node("Armature").set_transform(Transform(m3, mesh_xform.origin)) get_node("Armature").set_transform(Transform(m3, mesh_xform.origin))
if not jumping and jump_attempt: if not jumping and jump_attempt:
vv = 7.0 vv = 7.0
jumping = true jumping = true
@@ -92,7 +92,7 @@ func _physics_process(delta):
anim = ANIM_AIR_UP anim = ANIM_AIR_UP
else: else:
anim = ANIM_AIR_DOWN anim = ANIM_AIR_DOWN
if dir.length() > 0.1: if dir.length() > 0.1:
hv += dir * (accel * 0.2 * delta) hv += dir * (accel * 0.2 * delta)
if hv.length() > max_speed: if hv.length() > max_speed:
@@ -103,22 +103,22 @@ func _physics_process(delta):
if hspeed < 0: if hspeed < 0:
hspeed = 0 hspeed = 0
hv = hdir * hspeed hv = hdir * hspeed
if jumping and vv < 0: if jumping and vv < 0:
jumping = false jumping = false
linear_velocity = hv + Vector3.UP * vv linear_velocity = hv + Vector3.UP * vv
if is_on_floor(): if is_on_floor():
movement_dir = linear_velocity movement_dir = linear_velocity
linear_velocity = move_and_slide(linear_velocity, -gravity.normalized()) linear_velocity = move_and_slide(linear_velocity, -gravity.normalized())
if shoot_blend > 0: if shoot_blend > 0:
shoot_blend -= delta * SHOOT_SCALE shoot_blend -= delta * SHOOT_SCALE
if (shoot_blend < 0): if (shoot_blend < 0):
shoot_blend = 0 shoot_blend = 0
if shoot_attempt and not prev_shoot: if shoot_attempt and not prev_shoot:
shoot_blend = SHOOT_TIME shoot_blend = SHOOT_TIME
var bullet = preload("res://bullet.tscn").instance() var bullet = preload("res://bullet.tscn").instance()
@@ -127,12 +127,12 @@ func _physics_process(delta):
bullet.set_linear_velocity(get_node("Armature/Bullet").get_global_transform().basis[2].normalized() * 20) bullet.set_linear_velocity(get_node("Armature/Bullet").get_global_transform().basis[2].normalized() * 20)
bullet.add_collision_exception_with(self) # Add it to bullet. bullet.add_collision_exception_with(self) # Add it to bullet.
get_node("SoundShoot").play() get_node("SoundShoot").play()
prev_shoot = shoot_attempt prev_shoot = shoot_attempt
if is_on_floor(): if is_on_floor():
get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed) get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
get_node("AnimationTreePlayer").transition_node_set_current("state", anim) get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0)) get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
@@ -140,15 +140,15 @@ func _physics_process(delta):
func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn): func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
var n = p_target # Normal. var n = p_target # Normal.
var t = n.cross(current_gn).normalized() var t = n.cross(current_gn).normalized()
var x = n.dot(p_facing) var x = n.dot(p_facing)
var y = t.dot(p_facing) var y = t.dot(p_facing)
var ang = atan2(y,x) var ang = atan2(y,x)
if abs(ang) < 0.001: # Too small. if abs(ang) < 0.001: # Too small.
return p_facing return p_facing
var s = sign(ang) var s = sign(ang)
ang = ang * s ang = ang * s
var turn = ang * p_adjust_rate * p_step var turn = ang * p_adjust_rate * p_step
@@ -158,5 +158,5 @@ func adjust_facing(p_facing, p_target, p_step, p_adjust_rate, current_gn):
else: else:
a = turn a = turn
ang = (ang - a) * s ang = (ang - a) * s
return (n * cos(ang) + t * sin(ang)) * p_facing.length() return (n * cos(ang) + t * sin(ang)) * p_facing.length()

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -17,7 +17,7 @@ func _ready():
break break
else: else:
node = node.get_parent() node = node.get_parent()
# This detaches the camera transform from the parent spatial node. # This detaches the camera transform from the parent spatial node.
set_as_toplevel(true) set_as_toplevel(true)
@@ -25,25 +25,25 @@ func _ready():
func _physics_process(_delta): func _physics_process(_delta):
var target = get_parent().get_global_transform().origin var target = get_parent().get_global_transform().origin
var pos = get_global_transform().origin var pos = get_global_transform().origin
var from_target = pos - target var from_target = pos - target
# Check ranges. # Check ranges.
if from_target.length() < min_distance: if from_target.length() < min_distance:
from_target = from_target.normalized() * min_distance from_target = from_target.normalized() * min_distance
elif from_target.length() > max_distance: elif from_target.length() > max_distance:
from_target = from_target.normalized() * max_distance from_target = from_target.normalized() * max_distance
# Check upper and lower height. # Check upper and lower height.
if from_target.y > max_height: if from_target.y > max_height:
from_target.y = max_height from_target.y = max_height
if from_target.y < min_height: if from_target.y < min_height:
from_target.y = min_height from_target.y = min_height
pos = target + from_target pos = target + from_target
look_at_from_position(pos, target, Vector3.UP) look_at_from_position(pos, target, Vector3.UP)
# Turn a little up or down # Turn a little up or down
var t = get_transform() var t = get_transform()
t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust)) * t.basis t.basis = Basis(t.basis[0], deg2rad(angle_v_adjust)) * t.basis

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,15 +10,15 @@ export var engine_force_value = 40
func _physics_process(delta): func _physics_process(delta):
var fwd_mps = transform.basis.xform_inv(linear_velocity).x var fwd_mps = transform.basis.xform_inv(linear_velocity).x
steer_target = Input.get_action_strength("turn_left") - Input.get_action_strength("turn_right") steer_target = Input.get_action_strength("turn_left") - Input.get_action_strength("turn_right")
steer_target *= STEER_LIMIT steer_target *= STEER_LIMIT
if Input.is_action_pressed("accelerate"): if Input.is_action_pressed("accelerate"):
engine_force = engine_force_value engine_force = engine_force_value
else: else:
engine_force = 0 engine_force = 0
if Input.is_action_pressed("reverse"): if Input.is_action_pressed("reverse"):
if (fwd_mps >= -1): if (fwd_mps >= -1):
engine_force = -engine_force_value engine_force = -engine_force_value
@@ -26,7 +26,7 @@ func _physics_process(delta):
brake = 1 brake = 1
else: else:
brake = 0.0 brake = 0.0
if steer_target < steer_angle: if steer_target < steer_angle:
steer_angle -= STEER_SPEED * delta steer_angle -= STEER_SPEED * delta
if steer_target > steer_angle: if steer_target > steer_angle:
@@ -35,5 +35,5 @@ func _physics_process(delta):
steer_angle += STEER_SPEED * delta steer_angle += STEER_SPEED * delta
if steer_target < steer_angle: if steer_target < steer_angle:
steer_angle = steer_target steer_angle = steer_target
steering = steer_angle steering = steer_angle

View File

@@ -8,23 +8,10 @@ be used with [Godot Engine](https://godotengine.org), the open source
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with Godot's `master` development branch (next 4.x release). - The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with Godot's `master` development branch (next 4.x release).
- The [`3.x`](https://github.com/godotengine/godot-demo-projects/tree/3.x) branch is compatible with Godot's `3.x` development branch (next 3.x release). - The [`3.x`](https://github.com/godotengine/godot-demo-projects/tree/3.x) branch is compatible with Godot's `3.x` development branch (next 3.x release).
- The other branches are compatible with the matching stable versions of Godot: - The other branches are compatible with the matching stable versions of Godot.
- [`4.0`](https://github.com/godotengine/godot-demo-projects/tree/4.0) - [Click here](https://github.com/godotengine/godot-demo-projects/branches) to see all branches.
branch for Godot 4.0.x. - For example, the [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1)
- [`3.5`](https://github.com/godotengine/godot-demo-projects/tree/3.5) branch is for demos compatible with Godot 2.1.x.
branch for Godot 3.5.x.
- [`3.4`](https://github.com/godotengine/godot-demo-projects/tree/3.4)
branch for Godot 3.4.x.
- [`3.3`](https://github.com/godotengine/godot-demo-projects/tree/3.3)
branch for Godot 3.3.x.
- [`3.2`](https://github.com/godotengine/godot-demo-projects/tree/3.2)
branch for Godot 3.2.x.
- [***`3.1`***](https://github.com/godotengine/godot-demo-projects/tree/3.1)
branch for Godot 3.1.x.
- [`3.0`](https://github.com/godotengine/godot-demo-projects/tree/3.0)
branch for Godot 3.0.x.
- [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1)
branch for Godot 2.1.x.
## Importing all demos ## Importing all demos

View File

@@ -6,7 +6,7 @@ onready var itemList = get_node("ItemList")
func _ready(): func _ready():
for item in AudioServer.get_device_list(): for item in AudioServer.get_device_list():
itemList.add_item(item) itemList.add_item(item)
var device = AudioServer.get_device() var device = AudioServer.get_device()
for i in range(itemList.get_item_count()): for i in range(itemList.get_item_count()):
if device == itemList.get_item_text(i): if device == itemList.get_item_text(i):
@@ -16,14 +16,14 @@ func _ready():
func _process(_delta): func _process(_delta):
var speakerMode = "Stereo" var speakerMode = "Stereo"
if AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_31: if AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_31:
speakerMode = "Surround 3.1" speakerMode = "Surround 3.1"
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_51: elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_51:
speakerMode = "Surround 5.1" speakerMode = "Surround 5.1"
elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_71: elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_71:
speakerMode = "Surround 7.1" speakerMode = "Surround 7.1"
$DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n" $DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n"
$DeviceInfo.text += "Speaker Mode: " + speakerMode $DeviceInfo.text += "Speaker Mode: " + speakerMode

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -8,7 +8,7 @@ var playback: AudioStreamPlayback = null # Actual playback stream, assigned in _
func _fill_buffer(): func _fill_buffer():
var increment = pulse_hz / sample_hz var increment = pulse_hz / sample_hz
var to_fill = playback.get_frames_available() var to_fill = playback.get_frames_available()
while (to_fill > 0): while (to_fill > 0):
playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo. playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo.

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -14,7 +14,7 @@ func _draw():
#warning-ignore:integer_division #warning-ignore:integer_division
var w = WIDTH / VU_COUNT var w = WIDTH / VU_COUNT
var prev_hz = 0 var prev_hz = 0
for i in range(1, VU_COUNT+1): for i in range(1, VU_COUNT+1):
var hz = i * FREQ_MAX / VU_COUNT; var hz = i * FREQ_MAX / VU_COUNT;
var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length() var magnitude: float = spectrum.get_magnitude_for_frequency_range(prev_hz, hz).length()
var energy = clamp((MIN_DB + linear2db(magnitude)) / MIN_DB, 0, 1) var energy = clamp((MIN_DB + linear2db(magnitude)) / MIN_DB, 0, 1)

55
file_format.sh Normal file
View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# This script ensures proper POSIX text file formatting and a few other things.
set -uo pipefail
IFS=$'\n\t'
# Loops through all text files tracked by Git.
git grep -zIl '' |
while IFS= read -rd '' f; do
# Exclude some types of files.
if [[ "$f" == *"csproj" ]]; then
continue
elif [[ "$f" == *"hdr" ]]; then
continue
fi
# Ensure that files are UTF-8 formatted.
recode UTF-8 "$f" 2> /dev/null
# Ensure that files have LF line endings and do not contain a BOM.
dos2unix "$f" 2> /dev/null
# Remove trailing space characters and ensures that files end
# with newline characters. -l option handles newlines conveniently.
perl -i -ple 's/\s*$//g' "$f"
# Remove the character sequence "== true" if it has a leading space.
perl -i -pe 's/\x20== true//g' "$f"
# We don't want to change lines around braces in godot/tscn files.
if [[ "$f" == *"godot" ]]; then
continue
elif [[ "$f" == *"tscn" ]]; then
continue
fi
# Disallow empty lines after the opening brace.
sed -z -i 's/\x7B\x0A\x0A/\x7B\x0A/g' "$f"
# Disallow some empty lines before the closing brace.
sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f"
done
git diff > patch.patch
FILESIZE="$(stat -c%s patch.patch)"
MAXSIZE=5
# If no patch has been generated all is OK, clean up, and exit.
if (( FILESIZE < MAXSIZE )); then
printf "Files in this commit comply with the formatting rules.\n"
rm -f patch.patch
exit 0
fi
# A patch has been created, notify the user, clean up, and exit.
printf "\n*** The following differences were found between the code "
printf "and the formatting rules:\n\n"
cat patch.patch
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
rm -f patch.patch
exit 1

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -152,4 +152,4 @@ TERMINATION
This license becomes null and void if any of the above conditions are not met. This license becomes null and void if any of the above conditions are not met.
DISCLAIMER DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -3,9 +3,9 @@ Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -1,3 +1,3 @@
,en,es,ja ,en,es,ja
KEY_HELLO,Hello!,Hola!,こんにちは KEY_HELLO,Hello!,Hola!,こんにちは
KEY_PUSH,Push Me!,Aprétame!,押す KEY_PUSH,Push Me!,Aprétame!,押す
1 en es ja
2 KEY_HELLO Hello! Hola! こんにちは
3 KEY_PUSH Push Me! Aprétame! 押す

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -12,9 +12,9 @@ func _thread_load(path):
var total = ril.get_stage_count() var total = ril.get_stage_count()
# Call deferred to configure max load steps. # Call deferred to configure max load steps.
progress.call_deferred("set_max", total) progress.call_deferred("set_max", total)
var res = null var res = null
while true: #iterate until we have a resource while true: #iterate until we have a resource
# Update progress bar, use call deferred, which routes to main thread. # Update progress bar, use call deferred, which routes to main thread.
progress.call_deferred("set_value", ril.get_stage()) progress.call_deferred("set_value", ril.get_stage())
@@ -31,20 +31,20 @@ func _thread_load(path):
# Not OK, there was an error. # Not OK, there was an error.
print("There was an error loading") print("There was an error loading")
break break
# Send whathever we did (or did not) get. # Send whathever we did (or did not) get.
call_deferred("_thread_done", res) call_deferred("_thread_done", res)
func _thread_done(resource): func _thread_done(resource):
assert(resource) assert(resource)
# Always wait for threads to finish, this is required on Windows. # Always wait for threads to finish, this is required on Windows.
thread.wait_to_finish() thread.wait_to_finish()
# Hide the progress bar. # Hide the progress bar.
progress.hide() progress.hide()
# Instantiate new scene. # Instantiate new scene.
var new_scene = resource.instance() var new_scene = resource.instance()
# Free current scene. # Free current scene.
@@ -54,7 +54,7 @@ func _thread_done(resource):
get_tree().root.add_child(new_scene) get_tree().root.add_child(new_scene)
# Set as current scene. # Set as current scene.
get_tree().current_scene = new_scene get_tree().current_scene = new_scene
progress.visible = false progress.visible = false
func load_scene(path): func load_scene(path):

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[android] [android]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -6,7 +6,7 @@ uniform float max_value = 1;
void fragment() { void fragment() {
// Get the color. // Get the color.
vec4 color = texture(TEXTURE, UV); vec4 color = texture(TEXTURE, UV);
// Compare the value. // Compare the value.
float gray = color.x; float gray = color.x;
if (gray < min_value) { if (gray < min_value) {
@@ -14,7 +14,7 @@ void fragment() {
} else if (gray > max_value) { } else if (gray > max_value) {
color = vec4(1, 1, 1, 1); color = vec4(1, 1, 1, 1);
} }
// Write back the color. // Write back the color.
COLOR = color; COLOR = color;
} }

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -1,11 +1,11 @@
extends Node extends Node
# Below are a number of helper functions that show how you can use the raw sensor data to determine the orientation # Below are a number of helper functions that show how you can use the raw sensor data to determine the orientation
# of your phone/device. The cheapest phones only have an accelerometer only the most expensive phones have all three. # of your phone/device. The cheapest phones only have an accelerometer only the most expensive phones have all three.
# Note that none of this logic filters data. Filters introduce lag but also provide stability. There are plenty # Note that none of this logic filters data. Filters introduce lag but also provide stability. There are plenty
# of examples on the internet on how to implement these. I wanted to keep this straight forward. # of examples on the internet on how to implement these. I wanted to keep this straight forward.
# We draw a few arrow objects to visualize the vectors and two cubes to show two implementation for orientating # We draw a few arrow objects to visualize the vectors and two cubes to show two implementation for orientating
# these cubes to our phones orientation. # these cubes to our phones orientation.
# This is a 3D example however reading the phones orientation is also invaluable for 2D # This is a 3D example however reading the phones orientation is also invaluable for 2D
@@ -13,52 +13,52 @@ extends Node
# care about the rotation around this axis. # care about the rotation around this axis.
func get_basis_for_arrow(p_vector): func get_basis_for_arrow(p_vector):
var rotate = Basis() var rotate = Basis()
# as our arrow points up, Y = our direction vector # as our arrow points up, Y = our direction vector
rotate.y = p_vector.normalized() rotate.y = p_vector.normalized()
# get an arbitrary vector we can use to calculate our other two vectors # get an arbitrary vector we can use to calculate our other two vectors
var v = Vector3(1.0, 0.0, 0.0) var v = Vector3(1.0, 0.0, 0.0)
if abs(v.dot(rotate.y)) > 0.9: if abs(v.dot(rotate.y)) > 0.9:
v = Vector3(0.0, 1.0, 0.0) v = Vector3(0.0, 1.0, 0.0)
# use our vector to get a vector perpendicular to our two vectors # use our vector to get a vector perpendicular to our two vectors
rotate.x = rotate.y.cross(v).normalized() rotate.x = rotate.y.cross(v).normalized()
# and the cross product again gives us our final vector perpendicular to our previous two vectors # and the cross product again gives us our final vector perpendicular to our previous two vectors
rotate.z = rotate.x.cross(rotate.y).normalized() rotate.z = rotate.x.cross(rotate.y).normalized()
return rotate return rotate
# This function combines the magnetometer reading with the gravity vector to get a vector that points due north # This function combines the magnetometer reading with the gravity vector to get a vector that points due north
func calc_north(p_grav, p_mag): func calc_north(p_grav, p_mag):
# Always use normalized vectors! # Always use normalized vectors!
p_grav = p_grav.normalized() p_grav = p_grav.normalized()
# Calculate east (or is it west) by getting our cross product. # Calculate east (or is it west) by getting our cross product.
# The cross product of two normalized vectors returns a vector that # The cross product of two normalized vectors returns a vector that
# is perpendicular to our two vectors # is perpendicular to our two vectors
var east = p_grav.cross(p_mag.normalized()).normalized() var east = p_grav.cross(p_mag.normalized()).normalized()
# Cross again to get our horizon aligned north # Cross again to get our horizon aligned north
return east.cross(p_grav).normalized() return east.cross(p_grav).normalized()
# This function creates an orientation matrix using the magnetometer and gravity vector as inputs. # This function creates an orientation matrix using the magnetometer and gravity vector as inputs.
func orientate_by_mag_and_grav(p_mag, p_grav): func orientate_by_mag_and_grav(p_mag, p_grav):
var rotate = Basis() var rotate = Basis()
# as always, normalize! # as always, normalize!
p_mag = p_mag.normalized() p_mag = p_mag.normalized()
# gravity points down, so - gravity points up! # gravity points down, so - gravity points up!
rotate.y = -p_grav.normalized() rotate.y = -p_grav.normalized()
# Cross products with our magnetic north gives an aligned east (or west, I always forget) # Cross products with our magnetic north gives an aligned east (or west, I always forget)
rotate.x = rotate.y.cross(p_mag) rotate.x = rotate.y.cross(p_mag)
# And cross product again and we get our aligned north completing our matrix # And cross product again and we get our aligned north completing our matrix
rotate.z = rotate.x.cross(rotate.y) rotate.z = rotate.x.cross(rotate.y)
return rotate return rotate
# This function takes our gyro input and update an orientation matrix accordingly # This function takes our gyro input and update an orientation matrix accordingly
@@ -66,28 +66,28 @@ func orientate_by_mag_and_grav(p_mag, p_grav):
# rotational velocity. This is why we multiply our values with delta. # rotational velocity. This is why we multiply our values with delta.
func rotate_by_gyro(p_gyro, p_basis, p_delta): func rotate_by_gyro(p_gyro, p_basis, p_delta):
var rotate = Basis() var rotate = Basis()
rotate = rotate.rotated(p_basis.x, -p_gyro.x * p_delta) rotate = rotate.rotated(p_basis.x, -p_gyro.x * p_delta)
rotate = rotate.rotated(p_basis.y, -p_gyro.y * p_delta) rotate = rotate.rotated(p_basis.y, -p_gyro.y * p_delta)
rotate = rotate.rotated(p_basis.z, -p_gyro.z * p_delta) rotate = rotate.rotated(p_basis.z, -p_gyro.z * p_delta)
return rotate * p_basis return rotate * p_basis
# This function corrects the drift in our matrix by our gravity vector # This function corrects the drift in our matrix by our gravity vector
func drift_correction(p_basis, p_grav): func drift_correction(p_basis, p_grav):
# as always, make sure our vector is normalized but also invert as our gravity points down # as always, make sure our vector is normalized but also invert as our gravity points down
var real_up = -p_grav.normalized() var real_up = -p_grav.normalized()
# start by calculating the dot product, this gives us the cosine angle between our two vectors # start by calculating the dot product, this gives us the cosine angle between our two vectors
var dot = p_basis.y.dot(real_up) var dot = p_basis.y.dot(real_up)
# if our dot is 1.0 we're good # if our dot is 1.0 we're good
if dot < 1.0: if dot < 1.0:
# the cross between our two vectors gives us a vector perpendicular to our two vectors # the cross between our two vectors gives us a vector perpendicular to our two vectors
var axis = p_basis.y.cross(real_up).normalized() var axis = p_basis.y.cross(real_up).normalized()
var correction = Basis(axis, acos(dot)) var correction = Basis(axis, acos(dot))
p_basis = correction * p_basis p_basis = correction * p_basis
return p_basis return p_basis
func _process(delta): func _process(delta):
@@ -96,12 +96,12 @@ func _process(delta):
var grav = Input.get_gravity() var grav = Input.get_gravity()
var mag = Input.get_magnetometer() var mag = Input.get_magnetometer()
var gyro = Input.get_gyroscope() var gyro = Input.get_gyroscope()
# Show our base values # Show our base values
get_node("Control/Accelerometer").text = 'Accelerometer: ' + str(acc) + ', gravity: ' + str(grav) get_node("Control/Accelerometer").text = 'Accelerometer: ' + str(acc) + ', gravity: ' + str(grav)
get_node("Control/Magnetometer").text = 'Magnetometer: ' + str(mag) get_node("Control/Magnetometer").text = 'Magnetometer: ' + str(mag)
get_node("Control/Gyroscope").text = 'Gyroscope: ' + str(gyro) get_node("Control/Gyroscope").text = 'Gyroscope: ' + str(gyro)
# Check if we have all needed data # Check if we have all needed data
if grav.length() < 0.1: if grav.length() < 0.1:
if acc.length() < 0.1: if acc.length() < 0.1:
@@ -110,31 +110,31 @@ func _process(delta):
else: else:
# The gravity vector is calculated by the OS by combining the other sensor inputs. # The gravity vector is calculated by the OS by combining the other sensor inputs.
# If we don't have a gravity vector, from now on, use accelerometer... # If we don't have a gravity vector, from now on, use accelerometer...
grav = acc grav = acc
if mag.length() < 0.1: if mag.length() < 0.1:
mag = Vector3(1.0, 0.0, 0.0) mag = Vector3(1.0, 0.0, 0.0)
# Update our arrow showing gravity # Update our arrow showing gravity
get_node("Arrows/AccelerometerArrow").transform.basis = get_basis_for_arrow(grav) get_node("Arrows/AccelerometerArrow").transform.basis = get_basis_for_arrow(grav)
# Update our arrow showing our magnetometer # Update our arrow showing our magnetometer
# Note that in absense of other strong magnetic forces this will point to magnetic north, which is not horizontal thanks to the earth being, uhm, round # Note that in absense of other strong magnetic forces this will point to magnetic north, which is not horizontal thanks to the earth being, uhm, round
get_node("Arrows/MagnetoArrow").transform.basis = get_basis_for_arrow(mag) get_node("Arrows/MagnetoArrow").transform.basis = get_basis_for_arrow(mag)
# Calculate our north vector and show that # Calculate our north vector and show that
var north = calc_north(grav,mag) var north = calc_north(grav,mag)
get_node("Arrows/NorthArrow").transform.basis = get_basis_for_arrow(north) get_node("Arrows/NorthArrow").transform.basis = get_basis_for_arrow(north)
# Combine our magnetometer and gravity vector to position our box. This will be fairly accurate # Combine our magnetometer and gravity vector to position our box. This will be fairly accurate
# but our magnetometer can be easily influenced by magnets. Cheaper phones often don't have gyros # but our magnetometer can be easily influenced by magnets. Cheaper phones often don't have gyros
# so it is a good backup. # so it is a good backup.
var mag_and_grav = get_node("Boxes/MagAndGrav") var mag_and_grav = get_node("Boxes/MagAndGrav")
mag_and_grav.transform.basis = orientate_by_mag_and_grav(mag, grav).orthonormalized() mag_and_grav.transform.basis = orientate_by_mag_and_grav(mag, grav).orthonormalized()
# Using our gyro and do a drift correction using our gravity vector gives the best result # Using our gyro and do a drift correction using our gravity vector gives the best result
var gyro_and_grav = get_node("Boxes/GyroAndGrav") var gyro_and_grav = get_node("Boxes/GyroAndGrav")
var new_basis = rotate_by_gyro(gyro, gyro_and_grav.transform.basis, delta).orthonormalized() var new_basis = rotate_by_gyro(gyro, gyro_and_grav.transform.basis, delta).orthonormalized()
gyro_and_grav.transform.basis = drift_correction(new_basis, grav) gyro_and_grav.transform.basis = drift_correction(new_basis, grav)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -11,23 +11,23 @@ onready var camera = $Camera
func _process(delta): func _process(delta):
if state != STATE_GRAB: if state != STATE_GRAB:
return return
var x_movement = Input.get_action_strength("move_right") - Input.get_action_strength("move_left") var x_movement = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
var z_movement = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward") var z_movement = Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")
var dir = direction(Vector3(x_movement, 0, z_movement)) var dir = direction(Vector3(x_movement, 0, z_movement))
transform.origin += dir * 10 * delta transform.origin += dir * 10 * delta
var d = delta * 0.1 # Scale the input, easiest to do by scaling the delta. var d = delta * 0.1 # Scale the input, easiest to do by scaling the delta.
rotate(Vector3.UP, d * r_pos.x) # Yaw rotate(Vector3.UP, d * r_pos.x) # Yaw
camera.transform = camera.transform.rotated(Vector3.RIGHT, d * r_pos.y) # Pitch camera.transform = camera.transform.rotated(Vector3.RIGHT, d * r_pos.y) # Pitch
r_pos = Vector2.ZERO # We've dealt with all the input, so set it to zero. r_pos = Vector2.ZERO # We've dealt with all the input, so set it to zero.
func _input(event): func _input(event):
if (event is InputEventMouseMotion): if (event is InputEventMouseMotion):
r_pos = -event.relative r_pos = -event.relative
if (event.is_action("ui_cancel") and event.is_pressed() and !event.is_echo()): if (event.is_action("ui_cancel") and event.is_pressed() and !event.is_echo()):
if (state == STATE_GRAB): if (state == STATE_GRAB):
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

View File

@@ -10,7 +10,6 @@ config_version=4
_global_script_classes=[ ] _global_script_classes=[ ]
_global_script_class_icons={ _global_script_class_icons={
} }
[application] [application]

Some files were not shown because too many files have changed in this diff Show More