mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-06 16:00:08 +01:00
Merge pull request #525 from aaronfranke/gitignore-attr
Update gitignore for 4.x, add gitattributes, and update file format
This commit is contained in:
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Normalize EOL for all files that Git considers text files.
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
*.hdr binary
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
# Godot 4+ specific ignores
|
||||||
|
.godot/
|
||||||
|
|
||||||
# Godot-specific ignores
|
# Godot-specific ignores
|
||||||
.import/
|
.import/
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ func initialize(speed, velocity):
|
|||||||
max_horizontal_speed = speed if speed > 0.0 else base_max_horizontal_speed
|
max_horizontal_speed = speed if speed > 0.0 else base_max_horizontal_speed
|
||||||
enter_velocity = velocity
|
enter_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
func enter():
|
func enter():
|
||||||
var input_direction = get_input_direction()
|
var input_direction = get_input_direction()
|
||||||
update_look_direction(input_direction)
|
update_look_direction(input_direction)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -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:
|
||||||
@@ -235,13 +235,13 @@ func _draw():
|
|||||||
func save_picture(path):
|
func save_picture(path):
|
||||||
# Wait until the frame has finished before getting the texture.
|
# Wait until the frame has finished before getting the texture.
|
||||||
yield(VisualServer, "frame_post_draw")
|
yield(VisualServer, "frame_post_draw")
|
||||||
|
|
||||||
# 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)
|
||||||
|
|||||||
@@ -46,7 +46,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)
|
||||||
@@ -80,7 +80,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
|
||||||
|
|||||||
@@ -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)
|
||||||
physics_material_override.friction = 1
|
physics_material_override.friction = 1
|
||||||
cc.disable()
|
cc.disable()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -57,47 +57,47 @@ onready var bullet_shoot = $BulletShoot
|
|||||||
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 player input.
|
# Get player input.
|
||||||
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.
|
||||||
@@ -107,10 +107,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:
|
||||||
@@ -125,14 +125,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
|
||||||
sound_jump.play()
|
sound_jump.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
|
||||||
@@ -161,11 +161,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"
|
||||||
@@ -176,28 +176,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.scale.x = -1
|
sprite.scale.x = -1
|
||||||
else:
|
else:
|
||||||
sprite.scale.x = 1
|
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
|
||||||
animation_player.play(anim)
|
animation_player.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)
|
||||||
@@ -212,15 +212,15 @@ func _shot_bullet():
|
|||||||
else:
|
else:
|
||||||
ss = 1.0
|
ss = 1.0
|
||||||
var pos = position + bullet_shoot.position * Vector2(ss, 1.0)
|
var pos = position + bullet_shoot.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(400.0 * ss, -40)
|
bi.linear_velocity = Vector2(400.0 * ss, -40)
|
||||||
|
|
||||||
sprite_smoke.restart()
|
sprite_smoke.restart()
|
||||||
sound_shoot.play()
|
sound_shoot.play()
|
||||||
|
|
||||||
add_collision_exception_with(bi) # Make bullet and this not collide.
|
add_collision_exception_with(bi) # Make bullet and this not collide.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func _unhandled_input(event):
|
|||||||
else:
|
else:
|
||||||
_pause_menu.close()
|
_pause_menu.close()
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
elif event.is_action_pressed("splitscreen"):
|
elif event.is_action_pressed("splitscreen"):
|
||||||
if name == "Splitscreen":
|
if name == "Splitscreen":
|
||||||
# We need to clean up a little bit first to avoid Viewport errors.
|
# We need to clean up a little bit first to avoid Viewport errors.
|
||||||
|
|||||||
@@ -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"))
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,41 +53,41 @@ func _ready():
|
|||||||
if not has_node("Target"):
|
if not has_node("Target"):
|
||||||
target = Spatial.new()
|
target = Spatial.new()
|
||||||
add_child(target)
|
add_child(target)
|
||||||
|
|
||||||
if Engine.editor_hint:
|
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 = $Target
|
target = $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:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(target, Color.magenta)
|
_make_editor_sphere_at_node(target, Color.magenta)
|
||||||
|
|
||||||
if middle_joint_target == null:
|
if middle_joint_target == null:
|
||||||
if not has_node("MiddleJoint"):
|
if not has_node("MiddleJoint"):
|
||||||
middle_joint_target = Spatial.new()
|
middle_joint_target = Spatial.new()
|
||||||
add_child(middle_joint_target)
|
add_child(middle_joint_target)
|
||||||
|
|
||||||
if Engine.editor_hint:
|
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 = "MiddleJoint"
|
middle_joint_target.name = "MiddleJoint"
|
||||||
else:
|
else:
|
||||||
middle_joint_target = get_node("MiddleJoint")
|
middle_joint_target = get_node("MiddleJoint")
|
||||||
|
|
||||||
# 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:
|
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)
|
||||||
|
|
||||||
@@ -119,12 +119,12 @@ func update_skeleton():
|
|||||||
if first_call:
|
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:
|
if debug_messages:
|
||||||
printerr(name, " - IK_FABRIK: No Bones in IK chain defined!")
|
printerr(name, " - IK_FABRIK: No Bones in IK chain defined!")
|
||||||
@@ -133,34 +133,34 @@ func update_skeleton():
|
|||||||
if debug_messages:
|
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:
|
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()
|
||||||
|
|
||||||
@@ -172,10 +172,10 @@ func solve_chain():
|
|||||||
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
|
||||||
@@ -183,35 +183,35 @@ 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:
|
if use_middle_joint_target:
|
||||||
if bone_nodes.size() > 2:
|
if bone_nodes.size() > 2:
|
||||||
var middle_point_pos = middle_joint_target.global_transform.origin
|
var middle_point_pos = middle_joint_target.global_transform.origin
|
||||||
var middle_point_pos_diff = (middle_point_pos - bone_nodes[bone_nodes.size()/2].global_transform.origin)
|
var middle_point_pos_diff = (middle_point_pos - bone_nodes[bone_nodes.size()/2].global_transform.origin)
|
||||||
bone_nodes[bone_nodes.size()/2].global_transform.origin += middle_point_pos_diff.normalized()
|
bone_nodes[bone_nodes.size()/2].global_transform.origin += middle_point_pos_diff.normalized()
|
||||||
|
|
||||||
# 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
|
||||||
for i in range(0, bone_nodes.size()):
|
for i in range(0, bone_nodes.size()):
|
||||||
var reset_bone_trans = get_bone_transform(i)
|
var reset_bone_trans = get_bone_transform(i)
|
||||||
@@ -227,17 +227,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
|
||||||
@@ -248,12 +248,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
|
||||||
@@ -274,27 +274,27 @@ 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)
|
||||||
|
|
||||||
# Set the position of the bone to the bone target.
|
# Set the position of the bone to the bone target.
|
||||||
# Prior to Godot 3.2, this was not necessary, but because we can now completely
|
# Prior to Godot 3.2, this was not necessary, but because we can now completely
|
||||||
# override bone transforms, we need to set the position as well as rotation.
|
# override bone transforms, we need to set the position as well as rotation.
|
||||||
bone_trans.origin = b_target.origin
|
bone_trans.origin = b_target.origin
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
# A bit of a hack. Because we only have two bones, we have to use the previous
|
# A bit of a hack. Because we only have two bones, we have to use the previous
|
||||||
# bone to position the last bone in the chain.
|
# bone to position the last bone in the chain.
|
||||||
var last_bone = bone_nodes[i-1].global_transform
|
var last_bone = bone_nodes[i-1].global_transform
|
||||||
@@ -303,29 +303,29 @@ func chain_apply_rotation():
|
|||||||
# bone on the Z axis.
|
# bone on the Z axis.
|
||||||
# This will place the position of the bone at the end of the last bone
|
# This will place the position of the bone at the end of the last bone
|
||||||
bone_trans.origin = last_bone.origin - last_bone.basis.z.normalized() * bones_in_chain_lengths[i-1]
|
bone_trans.origin = last_bone.origin - last_bone.basis.z.normalized() * bones_in_chain_lengths[i-1]
|
||||||
|
|
||||||
# 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)
|
||||||
|
|
||||||
# Set the position of the bone to the bone target.
|
# Set the position of the bone to the bone target.
|
||||||
# Prior to Godot 3.2, this was not necessary, but because we can now completely
|
# Prior to Godot 3.2, this was not necessary, but because we can now completely
|
||||||
# override bone transforms, we need to set the position as well as rotation.
|
# override bone transforms, we need to set the position as well as rotation.
|
||||||
bone_trans.origin = b_target.origin
|
bone_trans.origin = b_target.origin
|
||||||
|
|
||||||
# The the bone's (updated) transform
|
# The the bone's (updated) transform
|
||||||
set_bone_transform(i, bone_trans)
|
set_bone_transform(i, bone_trans)
|
||||||
|
|
||||||
@@ -333,12 +333,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:
|
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
|
||||||
|
|
||||||
|
|
||||||
@@ -378,11 +378,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:
|
||||||
@@ -400,24 +400,24 @@ func _set_skeleton_path(new_value):
|
|||||||
if first_call:
|
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:
|
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"):
|
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:
|
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
|
||||||
@@ -435,25 +435,25 @@ 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 not has_node(bone_name):
|
if not has_node(bone_name):
|
||||||
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:
|
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:
|
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))
|
||||||
@@ -461,7 +461,7 @@ func _make_bone_nodes():
|
|||||||
|
|
||||||
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()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,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:
|
||||||
@@ -34,7 +34,7 @@ func _ready():
|
|||||||
else:
|
else:
|
||||||
if debug_messages:
|
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:
|
if Engine.editor_hint:
|
||||||
_setup_for_editor()
|
_setup_for_editor()
|
||||||
|
|
||||||
@@ -59,29 +59,29 @@ func update_skeleton():
|
|||||||
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 index.
|
# Get the bone index.
|
||||||
var bone: int = skeleton_to_use.find_bone(bone_name)
|
var bone: int = skeleton_to_use.find_bone(bone_name)
|
||||||
|
|
||||||
# If no bone is found (-1), then return and optionally printan error.
|
# If no bone is found (-1), then return and optionally printan error.
|
||||||
if bone == -1:
|
if bone == -1:
|
||||||
if debug_messages:
|
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 global transform pose.
|
# get the bone's global transform pose.
|
||||||
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.RIGHT)
|
rest = rest.looking_at(target_pos, Vector3.RIGHT)
|
||||||
@@ -93,15 +93,15 @@ func update_skeleton():
|
|||||||
rest = rest.looking_at(target_pos, Vector3.UP)
|
rest = rest.looking_at(target_pos, Vector3.UP)
|
||||||
if debug_messages:
|
if debug_messages:
|
||||||
print(name, " - IK_LookAt: Unknown look_at_axis value!")
|
print(name, " - IK_LookAt: Unknown look_at_axis value!")
|
||||||
|
|
||||||
# Get the rotation euler of the bone and of this node.
|
# Get the rotation euler of the bone and of this node.
|
||||||
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()
|
||||||
|
|
||||||
# Flip the rotation euler if using negative rotation.
|
# Flip the rotation euler if using negative rotation.
|
||||||
if use_negative_our_rot:
|
if use_negative_our_rot:
|
||||||
self_euler = -self_euler
|
self_euler = -self_euler
|
||||||
|
|
||||||
# Apply this node's rotation euler on each axis, if wanted/required.
|
# Apply this node's rotation euler on each axis, if wanted/required.
|
||||||
if use_our_rotation_x:
|
if use_our_rotation_x:
|
||||||
rest_euler.x = self_euler.x
|
rest_euler.x = self_euler.x
|
||||||
@@ -109,23 +109,23 @@ func update_skeleton():
|
|||||||
rest_euler.y = self_euler.y
|
rest_euler.y = self_euler.y
|
||||||
if use_our_rotation_z:
|
if use_our_rotation_z:
|
||||||
rest_euler.z = self_euler.z
|
rest_euler.z = self_euler.z
|
||||||
|
|
||||||
# Make a new basis with the, potentially, changed euler angles.
|
# Make a new basis with the, potentially, changed euler angles.
|
||||||
rest.basis = Basis(rest_euler)
|
rest.basis = Basis(rest_euler)
|
||||||
|
|
||||||
# Apply additional rotation stored in additional_rotation to the bone.
|
# Apply additional rotation stored in additional_rotation to the bone.
|
||||||
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))
|
||||||
|
|
||||||
# If the position is set using an additional bone, then set the origin
|
# If the position is set using an additional bone, then set the origin
|
||||||
# based on that bone and its length.
|
# based on that bone and its length.
|
||||||
if position_using_additional_bone:
|
if position_using_additional_bone:
|
||||||
var additional_bone_id = skeleton_to_use.find_bone(additional_bone_name)
|
var additional_bone_id = skeleton_to_use.find_bone(additional_bone_name)
|
||||||
var additional_bone_pos = skeleton_to_use.get_bone_global_pose(additional_bone_id)
|
var additional_bone_pos = skeleton_to_use.get_bone_global_pose(additional_bone_id)
|
||||||
rest.origin = additional_bone_pos.origin - additional_bone_pos.basis.z.normalized() * additional_bone_length
|
rest.origin = additional_bone_pos.origin - additional_bone_pos.basis.z.normalized() * additional_bone_length
|
||||||
|
|
||||||
# Finally, apply the new rotation to the bone in the skeleton.
|
# Finally, apply the new rotation to the bone in the skeleton.
|
||||||
skeleton_to_use.set_bone_global_pose_override(bone, rest, 1.0, true)
|
skeleton_to_use.set_bone_global_pose_override(bone, rest, 1.0, true)
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ func _setup_for_editor():
|
|||||||
indicator_material.flags_unshaded = true
|
indicator_material.flags_unshaded = true
|
||||||
indicator_material.albedo_texture = preload("editor_gizmo_texture.png")
|
indicator_material.albedo_texture = preload("editor_gizmo_texture.png")
|
||||||
indicator_material.albedo_color = Color(1, 0.5, 0, 1)
|
indicator_material.albedo_color = Color(1, 0.5, 0, 1)
|
||||||
|
|
||||||
# Assign the material and mesh to the MeshInstance.
|
# Assign the material and mesh to the MeshInstance.
|
||||||
indicator_mesh.material = indicator_material
|
indicator_mesh.material = indicator_material
|
||||||
_editor_indicator.mesh = indicator_mesh
|
_editor_indicator.mesh = indicator_mesh
|
||||||
@@ -158,12 +158,12 @@ 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 passed to update, enable the correct process.
|
# Based on the value of passed to update, enable the correct process.
|
||||||
if update_mode == 0:
|
if update_mode == 0:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
@@ -188,15 +188,15 @@ func _set_skeleton_path(new_value):
|
|||||||
if first_call:
|
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:
|
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:
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ onready var pistol_end = $CameraHolder/Weapon/Pistol/PistolEnd
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
anim_player.connect("animation_finished", self, "animation_finished")
|
anim_player.connect("animation_finished", self, "animation_finished")
|
||||||
|
|
||||||
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)
|
||||||
@@ -70,12 +70,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):
|
||||||
@@ -86,17 +86,17 @@ 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 not right_mouse_down:
|
if not right_mouse_down:
|
||||||
right_mouse_down = true
|
right_mouse_down = true
|
||||||
|
|
||||||
if anim_done:
|
if anim_done:
|
||||||
if current_anim != "Aiming":
|
if current_anim != "Aiming":
|
||||||
anim_player.play("Aiming")
|
anim_player.play("Aiming")
|
||||||
@@ -104,15 +104,15 @@ func process_input(delta):
|
|||||||
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)
|
||||||
@@ -121,8 +121,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):
|
||||||
@@ -130,7 +130,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):
|
||||||
@@ -141,8 +141,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):
|
||||||
@@ -158,7 +158,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:
|
||||||
@@ -171,24 +171,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 not is_sprinting:
|
if not is_sprinting:
|
||||||
@@ -197,32 +197,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
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ onready var targets = $Targets
|
|||||||
|
|
||||||
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:
|
if flip_axis:
|
||||||
mouse_to_world = -mouse_to_world
|
mouse_to_world = -mouse_to_world
|
||||||
else:
|
else:
|
||||||
mouse_to_world.z *= -1
|
mouse_to_world.z *= -1
|
||||||
|
|
||||||
targets.transform.origin = mouse_to_world
|
targets.transform.origin = mouse_to_world
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ func start_timer(timeout):
|
|||||||
_timer.connect("timeout", self, "_on_timer_done")
|
_timer.connect("timeout", self, "_on_timer_done")
|
||||||
else:
|
else:
|
||||||
cancel_timer()
|
cancel_timer()
|
||||||
|
|
||||||
_timer.start(timeout)
|
_timer.start(timeout)
|
||||||
_timer_started = true
|
_timer_started = true
|
||||||
|
|
||||||
return _timer
|
return _timer
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ func _ready():
|
|||||||
yield(start_timer(0.5), "timeout")
|
yield(start_timer(0.5), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
while $DynamicShapes.get_child_count():
|
while $DynamicShapes.get_child_count():
|
||||||
var type_node = $DynamicShapes.get_child(0)
|
var type_node = $DynamicShapes.get_child(0)
|
||||||
_object_templates.push_back(type_node)
|
_object_templates.push_back(type_node)
|
||||||
$DynamicShapes.remove_child(type_node)
|
$DynamicShapes.remove_child(type_node)
|
||||||
|
|
||||||
$Options.add_menu_item(OPTION_TYPE_ALL)
|
$Options.add_menu_item(OPTION_TYPE_ALL)
|
||||||
$Options.add_menu_item(OPTION_TYPE_BOX)
|
$Options.add_menu_item(OPTION_TYPE_BOX)
|
||||||
$Options.add_menu_item(OPTION_TYPE_CAPSULE)
|
$Options.add_menu_item(OPTION_TYPE_CAPSULE)
|
||||||
@@ -32,15 +32,15 @@ func _ready():
|
|||||||
$Options.add_menu_item(OPTION_TYPE_CONVEX)
|
$Options.add_menu_item(OPTION_TYPE_CONVEX)
|
||||||
$Options.add_menu_item(OPTION_TYPE_SPHERE)
|
$Options.add_menu_item(OPTION_TYPE_SPHERE)
|
||||||
$Options.connect("option_selected", self, "_on_option_selected")
|
$Options.connect("option_selected", self, "_on_option_selected")
|
||||||
|
|
||||||
_start_all_types()
|
_start_all_types()
|
||||||
|
|
||||||
|
|
||||||
func _on_option_selected(option):
|
func _on_option_selected(option):
|
||||||
cancel_timer()
|
cancel_timer()
|
||||||
|
|
||||||
_despawn_objects()
|
_despawn_objects()
|
||||||
|
|
||||||
match option:
|
match option:
|
||||||
OPTION_TYPE_ALL:
|
OPTION_TYPE_ALL:
|
||||||
_start_all_types()
|
_start_all_types()
|
||||||
@@ -61,7 +61,7 @@ func _find_type_index(type_name):
|
|||||||
var type_node = _object_templates[type_index]
|
var type_node = _object_templates[type_index]
|
||||||
if type_node.name.find(type_name) > -1:
|
if type_node.name.find(type_name) > -1:
|
||||||
return type_index
|
return type_index
|
||||||
|
|
||||||
Log.print_error("Invalid shape type: " + type_name)
|
Log.print_error("Invalid shape type: " + type_name)
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
@@ -71,25 +71,25 @@ func _start_type(type_index):
|
|||||||
return
|
return
|
||||||
if type_index >= _object_templates.size():
|
if type_index >= _object_templates.size():
|
||||||
return
|
return
|
||||||
|
|
||||||
yield(start_timer(1.0), "timeout")
|
yield(start_timer(1.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_spawn_objects(type_index)
|
_spawn_objects(type_index)
|
||||||
|
|
||||||
yield(start_timer(1.0), "timeout")
|
yield(start_timer(1.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_activate_objects()
|
_activate_objects()
|
||||||
|
|
||||||
yield(start_timer(5.0), "timeout")
|
yield(start_timer(5.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_despawn_objects()
|
_despawn_objects()
|
||||||
|
|
||||||
Log.print_log("* Done.")
|
Log.print_log("* Done.")
|
||||||
|
|
||||||
|
|
||||||
@@ -98,21 +98,21 @@ func _start_all_types():
|
|||||||
yield(start_timer(1.0), "timeout")
|
yield(start_timer(1.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_spawn_objects(type_index)
|
_spawn_objects(type_index)
|
||||||
|
|
||||||
yield(start_timer(1.0), "timeout")
|
yield(start_timer(1.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_activate_objects()
|
_activate_objects()
|
||||||
|
|
||||||
yield(start_timer(5.0), "timeout")
|
yield(start_timer(5.0), "timeout")
|
||||||
if is_timer_canceled():
|
if is_timer_canceled():
|
||||||
return
|
return
|
||||||
|
|
||||||
_despawn_objects()
|
_despawn_objects()
|
||||||
|
|
||||||
Log.print_log("* Done.")
|
Log.print_log("* Done.")
|
||||||
|
|
||||||
|
|
||||||
@@ -120,9 +120,9 @@ func _spawn_objects(type_index):
|
|||||||
var template_node = _object_templates[type_index]
|
var template_node = _object_templates[type_index]
|
||||||
for spawn in spawns:
|
for spawn in spawns:
|
||||||
var spawn_parent = get_node(spawn)
|
var spawn_parent = get_node(spawn)
|
||||||
|
|
||||||
Log.print_log("* Spawning: " + template_node.name)
|
Log.print_log("* Spawning: " + template_node.name)
|
||||||
|
|
||||||
for _index in range(spawn_multipiler):
|
for _index in range(spawn_multipiler):
|
||||||
for _node_index in spawn_count / spawn_multipiler:
|
for _node_index in spawn_count / spawn_multipiler:
|
||||||
var node = template_node.duplicate() as Spatial
|
var node = template_node.duplicate() as Spatial
|
||||||
@@ -131,9 +131,9 @@ func _spawn_objects(type_index):
|
|||||||
|
|
||||||
func _activate_objects():
|
func _activate_objects():
|
||||||
var spawn_parent = $SpawnTarget1
|
var spawn_parent = $SpawnTarget1
|
||||||
|
|
||||||
Log.print_log("* Activating")
|
Log.print_log("* Activating")
|
||||||
|
|
||||||
for node_index in spawn_parent.get_child_count():
|
for node_index in spawn_parent.get_child_count():
|
||||||
var node = spawn_parent.get_child(node_index) as RigidBody
|
var node = spawn_parent.get_child(node_index) as RigidBody
|
||||||
node.set_sleeping(false)
|
node.set_sleeping(false)
|
||||||
@@ -142,12 +142,12 @@ func _activate_objects():
|
|||||||
func _despawn_objects():
|
func _despawn_objects():
|
||||||
for spawn in spawns:
|
for spawn in spawns:
|
||||||
var spawn_parent = get_node(spawn)
|
var spawn_parent = get_node(spawn)
|
||||||
|
|
||||||
if spawn_parent.get_child_count() == 0:
|
if spawn_parent.get_child_count() == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
Log.print_log("* Despawning")
|
Log.print_log("* Despawning")
|
||||||
|
|
||||||
while spawn_parent.get_child_count():
|
while spawn_parent.get_child_count():
|
||||||
var node_index = spawn_parent.get_child_count() - 1
|
var node_index = spawn_parent.get_child_count() - 1
|
||||||
var node = spawn_parent.get_child(node_index)
|
var node = spawn_parent.get_child(node_index)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func add_test(id, scene_path):
|
|||||||
test_data.id = id
|
test_data.id = id
|
||||||
test_data.scene_path = scene_path
|
test_data.scene_path = scene_path
|
||||||
_test_list.append(test_data)
|
_test_list.append(test_data)
|
||||||
|
|
||||||
add_menu_item(id)
|
add_menu_item(id)
|
||||||
|
|
||||||
|
|
||||||
@@ -39,15 +39,15 @@ func _on_option_selected(item_path):
|
|||||||
|
|
||||||
func _start_test(test):
|
func _start_test(test):
|
||||||
_current_test = test
|
_current_test = test
|
||||||
|
|
||||||
if _current_test_scene:
|
if _current_test_scene:
|
||||||
_current_test_scene.queue_free()
|
_current_test_scene.queue_free()
|
||||||
_current_test_scene = null
|
_current_test_scene = null
|
||||||
|
|
||||||
Log.print_log("*** STARTING TEST: " + test.id)
|
Log.print_log("*** STARTING TEST: " + test.id)
|
||||||
var scene = load(test.scene_path)
|
var scene = load(test.scene_path)
|
||||||
_current_test_scene = scene.instance()
|
_current_test_scene = scene.instance()
|
||||||
get_tree().root.add_child(_current_test_scene)
|
get_tree().root.add_child(_current_test_scene)
|
||||||
|
|
||||||
var label_test = get_node("../LabelTest")
|
var label_test = get_node("../LabelTest")
|
||||||
label_test.test_name = test.id
|
label_test.test_name = test.id
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ func _unhandled_input(event):
|
|||||||
if mouse_button_event.button_index == BUTTON_LEFT:
|
if mouse_button_event.button_index == BUTTON_LEFT:
|
||||||
_rotation_enabled = mouse_button_event.pressed
|
_rotation_enabled = mouse_button_event.pressed
|
||||||
return
|
return
|
||||||
|
|
||||||
if not _rotation_enabled:
|
if not _rotation_enabled:
|
||||||
return
|
return
|
||||||
|
|
||||||
var mouse_motion_event = event as InputEventMouseMotion
|
var mouse_motion_event = event as InputEventMouseMotion
|
||||||
if mouse_motion_event:
|
if mouse_motion_event:
|
||||||
var rotation_delta = mouse_motion_event.relative.x
|
var rotation_delta = mouse_motion_event.relative.x
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ var _entry_template
|
|||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
Log.connect("entry_logged", self, "_on_log_entry")
|
Log.connect("entry_logged", self, "_on_log_entry")
|
||||||
|
|
||||||
_entry_template = get_child(0) as Label
|
_entry_template = get_child(0) as Label
|
||||||
remove_child(_entry_template)
|
remove_child(_entry_template)
|
||||||
|
|
||||||
@@ -22,16 +22,16 @@ func clear():
|
|||||||
|
|
||||||
func _on_log_entry(message, type):
|
func _on_log_entry(message, type):
|
||||||
var new_entry = _entry_template.duplicate() as Label
|
var new_entry = _entry_template.duplicate() as Label
|
||||||
|
|
||||||
new_entry.set_text(message)
|
new_entry.set_text(message)
|
||||||
if type == Log.LogType.ERROR:
|
if type == Log.LogType.ERROR:
|
||||||
new_entry.modulate = Color.red
|
new_entry.modulate = Color.red
|
||||||
else:
|
else:
|
||||||
new_entry.modulate = Color.white
|
new_entry.modulate = Color.white
|
||||||
|
|
||||||
if get_child_count() >= MAX_ENTRIES:
|
if get_child_count() >= MAX_ENTRIES:
|
||||||
var first_entry = get_child(0) as Label
|
var first_entry = get_child(0) as Label
|
||||||
remove_child(first_entry)
|
remove_child(first_entry)
|
||||||
first_entry.queue_free()
|
first_entry.queue_free()
|
||||||
|
|
||||||
add_child(new_entry)
|
add_child(new_entry)
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ func _ready():
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if _attachment == null:
|
if _attachment == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
var viewport = get_viewport()
|
var viewport = get_viewport()
|
||||||
if viewport == null:
|
if viewport == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
var camera = viewport.get_camera()
|
var camera = viewport.get_camera()
|
||||||
if camera == null:
|
if camera == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
var world_pos = world_offset + _attachment.global_transform.origin
|
var world_pos = world_offset + _attachment.global_transform.origin
|
||||||
var screen_pos = camera.unproject_position(world_pos)
|
var screen_pos = camera.unproject_position(world_pos)
|
||||||
|
|
||||||
rect_position = _pos_offset + screen_pos - 0.5 * rect_size
|
rect_position = _pos_offset + screen_pos - 0.5 * rect_size
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ func add_menu_item(item_path):
|
|||||||
var path_elements = item_path.split("/", false)
|
var path_elements = item_path.split("/", false)
|
||||||
var path_element_count = path_elements.size()
|
var path_element_count = path_elements.size()
|
||||||
assert(path_element_count > 0)
|
assert(path_element_count > 0)
|
||||||
|
|
||||||
var path = ""
|
var path = ""
|
||||||
var popup = get_popup()
|
var popup = get_popup()
|
||||||
for element_index in path_element_count - 1:
|
for element_index in path_element_count - 1:
|
||||||
var popup_label = path_elements[element_index]
|
var popup_label = path_elements[element_index]
|
||||||
path += popup_label + "/"
|
path += popup_label + "/"
|
||||||
popup = _add_popup(popup, path, popup_label)
|
popup = _add_popup(popup, path, popup_label)
|
||||||
|
|
||||||
_add_item(popup, path_elements[path_element_count - 1])
|
_add_item(popup, path_elements[path_element_count - 1])
|
||||||
|
|
||||||
|
|
||||||
@@ -30,15 +30,15 @@ func _add_popup(parent_popup, path, label):
|
|||||||
var popup_menu = popup_node as PopupMenu
|
var popup_menu = popup_node as PopupMenu
|
||||||
assert(popup_menu)
|
assert(popup_menu)
|
||||||
return popup_menu
|
return popup_menu
|
||||||
|
|
||||||
var popup_menu = PopupMenu.new()
|
var popup_menu = PopupMenu.new()
|
||||||
popup_menu.name = label
|
popup_menu.name = label
|
||||||
|
|
||||||
parent_popup.add_child(popup_menu)
|
parent_popup.add_child(popup_menu)
|
||||||
parent_popup.add_submenu_item(label, label)
|
parent_popup.add_submenu_item(label, label)
|
||||||
|
|
||||||
popup_menu.connect("index_pressed", self, "_on_item_pressed", [popup_menu, path])
|
popup_menu.connect("index_pressed", self, "_on_item_pressed", [popup_menu, path])
|
||||||
|
|
||||||
return popup_menu
|
return popup_menu
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ var _engine = PhysicsEngine.OTHER
|
|||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
get_tree().debug_collisions_hint = true
|
get_tree().debug_collisions_hint = true
|
||||||
|
|
||||||
var engine_string = ProjectSettings.get_setting("physics/3d/physics_engine")
|
var engine_string = ProjectSettings.get_setting("physics/3d/physics_engine")
|
||||||
match engine_string:
|
match engine_string:
|
||||||
"DEFAULT":
|
"DEFAULT":
|
||||||
@@ -28,7 +28,7 @@ func _enter_tree():
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if Input.is_action_just_pressed("toggle_full_screen"):
|
if Input.is_action_just_pressed("toggle_full_screen"):
|
||||||
OS.window_fullscreen = not OS.window_fullscreen
|
OS.window_fullscreen = not OS.window_fullscreen
|
||||||
|
|
||||||
if Input.is_action_just_pressed("toggle_debug_collision"):
|
if Input.is_action_just_pressed("toggle_debug_collision"):
|
||||||
var debug_collision_enabled = not _is_debug_collision_enabled()
|
var debug_collision_enabled = not _is_debug_collision_enabled()
|
||||||
_set_debug_collision_enabled(debug_collision_enabled)
|
_set_debug_collision_enabled(debug_collision_enabled)
|
||||||
@@ -36,7 +36,7 @@ func _process(_delta):
|
|||||||
Log.print_log("Debug Collision ON")
|
Log.print_log("Debug Collision ON")
|
||||||
else:
|
else:
|
||||||
Log.print_log("Debug Collision OFF")
|
Log.print_log("Debug Collision OFF")
|
||||||
|
|
||||||
if Input.is_action_just_pressed("exit"):
|
if Input.is_action_just_pressed("exit"):
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
|||||||
@@ -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://player/bullet/bullet.gd") and cc.enabled:
|
if cc is preload("res://player/bullet/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
|
||||||
|
|
||||||
|
|||||||
@@ -30,15 +30,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.
|
||||||
@@ -46,45 +46,45 @@ func _physics_process(delta):
|
|||||||
dir += (Input.get_action_strength("move_backwards") - Input.get_action_strength("move_forward")) * cam_basis[2]
|
dir += (Input.get_action_strength("move_backwards") - 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)
|
||||||
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
|
||||||
get_node("SoundJump").play()
|
get_node("SoundJump").play()
|
||||||
else:
|
else:
|
||||||
anim = ANIM_AIR
|
anim = ANIM_AIR
|
||||||
|
|
||||||
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:
|
||||||
@@ -95,22 +95,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://player/bullet/bullet.tscn").instance()
|
var bullet = preload("res://player/bullet/bullet.tscn").instance()
|
||||||
@@ -119,12 +119,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():
|
||||||
$AnimationTree["parameters/walk/blend_amount"] = hspeed / max_speed
|
$AnimationTree["parameters/walk/blend_amount"] = hspeed / max_speed
|
||||||
|
|
||||||
$AnimationTree["parameters/state/current"] = anim
|
$AnimationTree["parameters/state/current"] = anim
|
||||||
$AnimationTree["parameters/air_dir/blend_amount"] = clamp(-linear_velocity.y / 4 + 0.5, 0, 1)
|
$AnimationTree["parameters/air_dir/blend_amount"] = clamp(-linear_velocity.y / 4 + 0.5, 0, 1)
|
||||||
$AnimationTree["parameters/gun/blend_amount"] = min(shoot_blend, 1.0)
|
$AnimationTree["parameters/gun/blend_amount"] = min(shoot_blend, 1.0)
|
||||||
@@ -133,15 +133,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
|
||||||
@@ -151,5 +151,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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -9,15 +9,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
|
||||||
@@ -25,5 +25,5 @@ func _physics_process(delta):
|
|||||||
brake = 1
|
brake = 1
|
||||||
else:
|
else:
|
||||||
brake = 0.0
|
brake = 0.0
|
||||||
|
|
||||||
steering = move_toward(steering, steer_target, STEER_SPEED * delta)
|
steering = move_toward(steering, steer_target, STEER_SPEED * delta)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ onready var voxel_world = $"../VoxelWorld"
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if Input.is_action_just_pressed("debug"):
|
if Input.is_action_just_pressed("debug"):
|
||||||
visible = !visible
|
visible = !visible
|
||||||
|
|
||||||
text = "Position: " + _vector_to_string_appropriate_digits(player.transform.origin)
|
text = "Position: " + _vector_to_string_appropriate_digits(player.transform.origin)
|
||||||
text += "\nEffective render distance: " + str(voxel_world.effective_render_distance)
|
text += "\nEffective render distance: " + str(voxel_world.effective_render_distance)
|
||||||
text += "\nLooking: " + _cardinal_string_from_radians(player.transform.basis.get_euler().y)
|
text += "\nLooking: " + _cardinal_string_from_radians(player.transform.basis.get_euler().y)
|
||||||
@@ -26,7 +26,7 @@ func _vector_to_string_appropriate_digits(vector):
|
|||||||
factors[i] = factors[i] / 10
|
factors[i] = factors[i] / 10
|
||||||
if abs(vector[i]) > 524288:
|
if abs(vector[i]) > 524288:
|
||||||
factors[i] = factors[i] / 10
|
factors[i] = factors[i] / 10
|
||||||
|
|
||||||
return "(" + \
|
return "(" + \
|
||||||
str(round(vector.x * factors[0]) / factors[0]) + ", " + \
|
str(round(vector.x * factors[0]) / factors[0]) + ", " + \
|
||||||
str(round(vector.y * factors[1]) / factors[1]) + ", " + \
|
str(round(vector.y * factors[1]) / factors[1]) + ", " + \
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func _process(_delta):
|
|||||||
_mouse_motion.y = clamp(_mouse_motion.y, -1550, 1550)
|
_mouse_motion.y = clamp(_mouse_motion.y, -1550, 1550)
|
||||||
transform.basis = Basis(Vector3(0, _mouse_motion.x * -0.001, 0))
|
transform.basis = Basis(Vector3(0, _mouse_motion.x * -0.001, 0))
|
||||||
head.transform.basis = Basis(Vector3(_mouse_motion.y * -0.001, 0, 0))
|
head.transform.basis = Basis(Vector3(_mouse_motion.y * -0.001, 0, 0))
|
||||||
|
|
||||||
# Block selection.
|
# Block selection.
|
||||||
var position = raycast.get_collision_point()
|
var position = raycast.get_collision_point()
|
||||||
var normal = raycast.get_collision_normal()
|
var normal = raycast.get_collision_normal()
|
||||||
@@ -41,7 +41,7 @@ func _process(_delta):
|
|||||||
# Set the appropriate texture.
|
# Set the appropriate texture.
|
||||||
var uv = Chunk.calculate_block_uvs(_selected_block)
|
var uv = Chunk.calculate_block_uvs(_selected_block)
|
||||||
selected_block_texture.texture.region = Rect2(uv[0] * 512, Vector2.ONE * 64)
|
selected_block_texture.texture.region = Rect2(uv[0] * 512, Vector2.ONE * 64)
|
||||||
|
|
||||||
# Block breaking/placing.
|
# Block breaking/placing.
|
||||||
if crosshair.visible and raycast.is_colliding():
|
if crosshair.visible and raycast.is_colliding():
|
||||||
var breaking = Input.is_action_just_pressed("break")
|
var breaking = Input.is_action_just_pressed("break")
|
||||||
@@ -49,7 +49,7 @@ func _process(_delta):
|
|||||||
# Either both buttons were pressed or neither are, so stop.
|
# Either both buttons were pressed or neither are, so stop.
|
||||||
if breaking == placing:
|
if breaking == placing:
|
||||||
return
|
return
|
||||||
|
|
||||||
if breaking:
|
if breaking:
|
||||||
var block_global_position = (position - normal / 2).floor()
|
var block_global_position = (position - normal / 2).floor()
|
||||||
voxel_world.set_block_global_position(block_global_position, 0)
|
voxel_world.set_block_global_position(block_global_position, 0)
|
||||||
@@ -65,20 +65,20 @@ func _physics_process(delta):
|
|||||||
head.transform.origin = Vector3(0, 1.2, 0)
|
head.transform.origin = Vector3(0, 1.2, 0)
|
||||||
else:
|
else:
|
||||||
head.transform.origin = Vector3(0, 1.6, 0)
|
head.transform.origin = Vector3(0, 1.6, 0)
|
||||||
|
|
||||||
# Keyboard movement.
|
# Keyboard movement.
|
||||||
var movement = transform.basis.xform(Vector3(
|
var movement = transform.basis.xform(Vector3(
|
||||||
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
|
Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
|
||||||
0,
|
0,
|
||||||
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
|
Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
|
||||||
).normalized() * (1 if crouching else 5))
|
).normalized() * (1 if crouching else 5))
|
||||||
|
|
||||||
# Gravity.
|
# Gravity.
|
||||||
velocity.y -= gravity * delta
|
velocity.y -= gravity * delta
|
||||||
|
|
||||||
#warning-ignore:return_value_discarded
|
#warning-ignore:return_value_discarded
|
||||||
velocity = move_and_slide(Vector3(movement.x, velocity.y, movement.z), Vector3.UP)
|
velocity = move_and_slide(Vector3(movement.x, velocity.y, movement.z), Vector3.UP)
|
||||||
|
|
||||||
# Jumping, applied next frame.
|
# Jumping, applied next frame.
|
||||||
if is_on_floor() and Input.is_action_pressed("jump"):
|
if is_on_floor() and Input.is_action_pressed("jump"):
|
||||||
velocity.y = 5
|
velocity.y = 5
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func _enter_tree():
|
|||||||
printerr("Please delete the instance at: " + get_path())
|
printerr("Please delete the instance at: " + get_path())
|
||||||
else:
|
else:
|
||||||
Settings._loaded = true
|
Settings._loaded = true
|
||||||
|
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
if file.file_exists(_save_path):
|
if file.file_exists(_save_path):
|
||||||
file.open(_save_path, File.READ)
|
file.open(_save_path, File.READ)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func _ready():
|
|||||||
data = TerrainGenerator.random_blocks()
|
data = TerrainGenerator.random_blocks()
|
||||||
else:
|
else:
|
||||||
data = TerrainGenerator.flat(chunk_position)
|
data = TerrainGenerator.flat(chunk_position)
|
||||||
|
|
||||||
# We can only add colliders in the main thread due to physics limitations.
|
# We can only add colliders in the main thread due to physics limitations.
|
||||||
_generate_chunk_collider()
|
_generate_chunk_collider()
|
||||||
# However, we can use a thread for mesh generation.
|
# However, we can use a thread for mesh generation.
|
||||||
@@ -38,7 +38,7 @@ func regenerate():
|
|||||||
for c in get_children():
|
for c in get_children():
|
||||||
remove_child(c)
|
remove_child(c)
|
||||||
c.queue_free()
|
c.queue_free()
|
||||||
|
|
||||||
# Then generate new ones.
|
# Then generate new ones.
|
||||||
_generate_chunk_collider()
|
_generate_chunk_collider()
|
||||||
_generate_chunk_mesh(0)
|
_generate_chunk_mesh(0)
|
||||||
@@ -51,7 +51,7 @@ func _generate_chunk_collider():
|
|||||||
collision_layer = 0
|
collision_layer = 0
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
# For each block, generate a collider. Ensure collision layers are enabled.
|
# For each block, generate a collider. Ensure collision layers are enabled.
|
||||||
collision_layer = 0xFFFFF
|
collision_layer = 0xFFFFF
|
||||||
collision_mask = 0xFFFFF
|
collision_mask = 0xFFFFF
|
||||||
@@ -64,15 +64,15 @@ func _generate_chunk_collider():
|
|||||||
func _generate_chunk_mesh(_this_argument_exists_due_to_bug_9924):
|
func _generate_chunk_mesh(_this_argument_exists_due_to_bug_9924):
|
||||||
if data.empty():
|
if data.empty():
|
||||||
return
|
return
|
||||||
|
|
||||||
var surface_tool = SurfaceTool.new()
|
var surface_tool = SurfaceTool.new()
|
||||||
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
|
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
|
||||||
# For each block, add data to the SurfaceTool and generate a collider.
|
# For each block, add data to the SurfaceTool and generate a collider.
|
||||||
for block_position in data.keys():
|
for block_position in data.keys():
|
||||||
var block_id = data[block_position]
|
var block_id = data[block_position]
|
||||||
_draw_block_mesh(surface_tool, block_position, block_id)
|
_draw_block_mesh(surface_tool, block_position, block_id)
|
||||||
|
|
||||||
# Create the chunk's mesh from the SurfaceTool data.
|
# Create the chunk's mesh from the SurfaceTool data.
|
||||||
surface_tool.generate_normals()
|
surface_tool.generate_normals()
|
||||||
surface_tool.generate_tangents()
|
surface_tool.generate_tangents()
|
||||||
@@ -89,7 +89,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
var uvs = calculate_block_uvs(block_id)
|
var uvs = calculate_block_uvs(block_id)
|
||||||
var top_uvs = uvs
|
var top_uvs = uvs
|
||||||
var bottom_uvs = uvs
|
var bottom_uvs = uvs
|
||||||
|
|
||||||
# Bush blocks get drawn in their own special way.
|
# Bush blocks get drawn in their own special way.
|
||||||
if block_id == 27 or block_id == 28:
|
if block_id == 27 or block_id == 28:
|
||||||
_draw_block_face(surface_tool, [verts[2], verts[0], verts[7], verts[5]], uvs)
|
_draw_block_face(surface_tool, [verts[2], verts[0], verts[7], verts[5]], uvs)
|
||||||
@@ -97,7 +97,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
_draw_block_face(surface_tool, [verts[3], verts[1], verts[6], verts[4]], uvs)
|
_draw_block_face(surface_tool, [verts[3], verts[1], verts[6], verts[4]], uvs)
|
||||||
_draw_block_face(surface_tool, [verts[6], verts[4], verts[3], verts[1]], uvs)
|
_draw_block_face(surface_tool, [verts[6], verts[4], verts[3], verts[1]], uvs)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Allow some blocks to have different top/bottom textures.
|
# Allow some blocks to have different top/bottom textures.
|
||||||
if block_id == 3: # Grass.
|
if block_id == 3: # Grass.
|
||||||
top_uvs = calculate_block_uvs(0)
|
top_uvs = calculate_block_uvs(0)
|
||||||
@@ -111,7 +111,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
elif block_id == 19: # Bookshelf.
|
elif block_id == 19: # Bookshelf.
|
||||||
top_uvs = calculate_block_uvs(4)
|
top_uvs = calculate_block_uvs(4)
|
||||||
bottom_uvs = top_uvs
|
bottom_uvs = top_uvs
|
||||||
|
|
||||||
# Main rendering code for normal blocks.
|
# Main rendering code for normal blocks.
|
||||||
var other_block_position = block_sub_position + Vector3.LEFT
|
var other_block_position = block_sub_position + Vector3.LEFT
|
||||||
var other_block_id = 0
|
var other_block_id = 0
|
||||||
@@ -121,7 +121,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
other_block_id = data[other_block_position]
|
other_block_id = data[other_block_position]
|
||||||
if block_id != other_block_id and is_block_transparent(other_block_id):
|
if block_id != other_block_id and is_block_transparent(other_block_id):
|
||||||
_draw_block_face(surface_tool, [verts[2], verts[0], verts[3], verts[1]], uvs)
|
_draw_block_face(surface_tool, [verts[2], verts[0], verts[3], verts[1]], uvs)
|
||||||
|
|
||||||
other_block_position = block_sub_position + Vector3.RIGHT
|
other_block_position = block_sub_position + Vector3.RIGHT
|
||||||
other_block_id = 0
|
other_block_id = 0
|
||||||
if other_block_position.x == CHUNK_SIZE:
|
if other_block_position.x == CHUNK_SIZE:
|
||||||
@@ -130,7 +130,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
other_block_id = data[other_block_position]
|
other_block_id = data[other_block_position]
|
||||||
if block_id != other_block_id and is_block_transparent(other_block_id):
|
if block_id != other_block_id and is_block_transparent(other_block_id):
|
||||||
_draw_block_face(surface_tool, [verts[7], verts[5], verts[6], verts[4]], uvs)
|
_draw_block_face(surface_tool, [verts[7], verts[5], verts[6], verts[4]], uvs)
|
||||||
|
|
||||||
other_block_position = block_sub_position + Vector3.FORWARD
|
other_block_position = block_sub_position + Vector3.FORWARD
|
||||||
other_block_id = 0
|
other_block_id = 0
|
||||||
if other_block_position.z == -1:
|
if other_block_position.z == -1:
|
||||||
@@ -139,7 +139,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
other_block_id = data[other_block_position]
|
other_block_id = data[other_block_position]
|
||||||
if block_id != other_block_id and is_block_transparent(other_block_id):
|
if block_id != other_block_id and is_block_transparent(other_block_id):
|
||||||
_draw_block_face(surface_tool, [verts[6], verts[4], verts[2], verts[0]], uvs)
|
_draw_block_face(surface_tool, [verts[6], verts[4], verts[2], verts[0]], uvs)
|
||||||
|
|
||||||
other_block_position = block_sub_position + Vector3.BACK
|
other_block_position = block_sub_position + Vector3.BACK
|
||||||
other_block_id = 0
|
other_block_id = 0
|
||||||
if other_block_position.z == CHUNK_SIZE:
|
if other_block_position.z == CHUNK_SIZE:
|
||||||
@@ -148,7 +148,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
other_block_id = data[other_block_position]
|
other_block_id = data[other_block_position]
|
||||||
if block_id != other_block_id and is_block_transparent(other_block_id):
|
if block_id != other_block_id and is_block_transparent(other_block_id):
|
||||||
_draw_block_face(surface_tool, [verts[3], verts[1], verts[7], verts[5]], uvs)
|
_draw_block_face(surface_tool, [verts[3], verts[1], verts[7], verts[5]], uvs)
|
||||||
|
|
||||||
other_block_position = block_sub_position + Vector3.DOWN
|
other_block_position = block_sub_position + Vector3.DOWN
|
||||||
other_block_id = 0
|
other_block_id = 0
|
||||||
if other_block_position.y == -1:
|
if other_block_position.y == -1:
|
||||||
@@ -157,7 +157,7 @@ func _draw_block_mesh(surface_tool, block_sub_position, block_id):
|
|||||||
other_block_id = data[other_block_position]
|
other_block_id = data[other_block_position]
|
||||||
if block_id != other_block_id and is_block_transparent(other_block_id):
|
if block_id != other_block_id and is_block_transparent(other_block_id):
|
||||||
_draw_block_face(surface_tool, [verts[4], verts[5], verts[0], verts[1]], bottom_uvs)
|
_draw_block_face(surface_tool, [verts[4], verts[5], verts[0], verts[1]], bottom_uvs)
|
||||||
|
|
||||||
other_block_position = block_sub_position + Vector3.UP
|
other_block_position = block_sub_position + Vector3.UP
|
||||||
other_block_id = 0
|
other_block_id = 0
|
||||||
if other_block_position.y == CHUNK_SIZE:
|
if other_block_position.y == CHUNK_SIZE:
|
||||||
@@ -172,7 +172,7 @@ func _draw_block_face(surface_tool, verts, uvs):
|
|||||||
surface_tool.add_uv(uvs[1]); surface_tool.add_vertex(verts[1])
|
surface_tool.add_uv(uvs[1]); surface_tool.add_vertex(verts[1])
|
||||||
surface_tool.add_uv(uvs[2]); surface_tool.add_vertex(verts[2])
|
surface_tool.add_uv(uvs[2]); surface_tool.add_vertex(verts[2])
|
||||||
surface_tool.add_uv(uvs[3]); surface_tool.add_vertex(verts[3])
|
surface_tool.add_uv(uvs[3]); surface_tool.add_vertex(verts[3])
|
||||||
|
|
||||||
surface_tool.add_uv(uvs[2]); surface_tool.add_vertex(verts[2])
|
surface_tool.add_uv(uvs[2]); surface_tool.add_vertex(verts[2])
|
||||||
surface_tool.add_uv(uvs[1]); surface_tool.add_vertex(verts[1])
|
surface_tool.add_uv(uvs[1]); surface_tool.add_vertex(verts[1])
|
||||||
surface_tool.add_uv(uvs[0]); surface_tool.add_vertex(verts[0])
|
surface_tool.add_uv(uvs[0]); surface_tool.add_vertex(verts[0])
|
||||||
@@ -190,7 +190,7 @@ static func calculate_block_uvs(block_id):
|
|||||||
# This method only supports square texture sheets.
|
# This method only supports square texture sheets.
|
||||||
var row = block_id / TEXTURE_SHEET_WIDTH
|
var row = block_id / TEXTURE_SHEET_WIDTH
|
||||||
var col = block_id % TEXTURE_SHEET_WIDTH
|
var col = block_id % TEXTURE_SHEET_WIDTH
|
||||||
|
|
||||||
return [
|
return [
|
||||||
TEXTURE_TILE_SIZE * Vector2(col, row),
|
TEXTURE_TILE_SIZE * Vector2(col, row),
|
||||||
TEXTURE_TILE_SIZE * Vector2(col, row + 1),
|
TEXTURE_TILE_SIZE * Vector2(col, row + 1),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ onready var voxel_world = $"../VoxelWorld"
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
environment.fog_enabled = Settings.fog_enabled
|
environment.fog_enabled = Settings.fog_enabled
|
||||||
environment.dof_blur_far_enabled = Settings.fog_enabled
|
environment.dof_blur_far_enabled = Settings.fog_enabled
|
||||||
|
|
||||||
var target_distance = clamp(voxel_world.effective_render_distance, 2, voxel_world.render_distance - 1) * Chunk.CHUNK_SIZE
|
var target_distance = clamp(voxel_world.effective_render_distance, 2, voxel_world.render_distance - 1) * Chunk.CHUNK_SIZE
|
||||||
var rate = delta * 4
|
var rate = delta * 4
|
||||||
if environment.fog_depth_end > target_distance:
|
if environment.fog_depth_end > target_distance:
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ static func random_blocks():
|
|||||||
|
|
||||||
static func flat(chunk_position):
|
static func flat(chunk_position):
|
||||||
var data = {}
|
var data = {}
|
||||||
|
|
||||||
if chunk_position.y != -1:
|
if chunk_position.y != -1:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
for x in range(CHUNK_SIZE):
|
for x in range(CHUNK_SIZE):
|
||||||
for z in range(CHUNK_SIZE):
|
for z in range(CHUNK_SIZE):
|
||||||
data[Vector3(x, 0, z)] = 3
|
data[Vector3(x, 0, z)] = 3
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@@ -38,5 +38,5 @@ static func flat(chunk_position):
|
|||||||
static func origin_grass(chunk_position):
|
static func origin_grass(chunk_position):
|
||||||
if chunk_position == Vector3.ZERO:
|
if chunk_position == Vector3.ZERO:
|
||||||
return {Vector3.ZERO: 3}
|
return {Vector3.ZERO: 3}
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|||||||
@@ -20,17 +20,17 @@ onready var player = $"../Player"
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
_set_render_distance(Settings.render_distance)
|
_set_render_distance(Settings.render_distance)
|
||||||
var player_chunk = (player.transform.origin / Chunk.CHUNK_SIZE).round()
|
var player_chunk = (player.transform.origin / Chunk.CHUNK_SIZE).round()
|
||||||
|
|
||||||
if _deleting or player_chunk != _old_player_chunk:
|
if _deleting or player_chunk != _old_player_chunk:
|
||||||
_delete_far_away_chunks(player_chunk)
|
_delete_far_away_chunks(player_chunk)
|
||||||
_generating = true
|
_generating = true
|
||||||
|
|
||||||
if not _generating:
|
if not _generating:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Try to generate chunks ahead of time based on where the player is moving.
|
# Try to generate chunks ahead of time based on where the player is moving.
|
||||||
player_chunk.y += round(clamp(player.velocity.y, -render_distance / 4, render_distance / 4))
|
player_chunk.y += round(clamp(player.velocity.y, -render_distance / 4, render_distance / 4))
|
||||||
|
|
||||||
# Check existing chunks within range. If it doesn't exist, create it.
|
# Check existing chunks within range. If it doesn't exist, create it.
|
||||||
for x in range(player_chunk.x - effective_render_distance, player_chunk.x + effective_render_distance):
|
for x in range(player_chunk.x - effective_render_distance, player_chunk.x + effective_render_distance):
|
||||||
for y in range(player_chunk.y - effective_render_distance, player_chunk.y + effective_render_distance):
|
for y in range(player_chunk.y - effective_render_distance, player_chunk.y + effective_render_distance):
|
||||||
@@ -38,16 +38,16 @@ func _process(_delta):
|
|||||||
var chunk_position = Vector3(x, y, z)
|
var chunk_position = Vector3(x, y, z)
|
||||||
if player_chunk.distance_to(chunk_position) > render_distance:
|
if player_chunk.distance_to(chunk_position) > render_distance:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if _chunks.has(chunk_position):
|
if _chunks.has(chunk_position):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var chunk = Chunk.new()
|
var chunk = Chunk.new()
|
||||||
chunk.chunk_position = chunk_position
|
chunk.chunk_position = chunk_position
|
||||||
_chunks[chunk_position] = chunk
|
_chunks[chunk_position] = chunk
|
||||||
add_child(chunk)
|
add_child(chunk)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If we didn't generate any chunks (and therefore didn't return), what next?
|
# If we didn't generate any chunks (and therefore didn't return), what next?
|
||||||
if effective_render_distance < render_distance:
|
if effective_render_distance < render_distance:
|
||||||
# We can move on to the next stage by increasing the effective distance.
|
# We can move on to the next stage by increasing the effective distance.
|
||||||
@@ -76,7 +76,7 @@ func set_block_global_position(block_global_position, block_id):
|
|||||||
else:
|
else:
|
||||||
chunk.data[sub_position] = block_id
|
chunk.data[sub_position] = block_id
|
||||||
chunk.regenerate()
|
chunk.regenerate()
|
||||||
|
|
||||||
# We also might need to regenerate some neighboring chunks.
|
# We also might need to regenerate some neighboring chunks.
|
||||||
if Chunk.is_block_transparent(block_id):
|
if Chunk.is_block_transparent(block_id):
|
||||||
if sub_position.x == 0:
|
if sub_position.x == 0:
|
||||||
@@ -108,7 +108,7 @@ func _delete_far_away_chunks(player_chunk):
|
|||||||
_old_player_chunk = player_chunk
|
_old_player_chunk = player_chunk
|
||||||
# If we need to delete chunks, give the new chunk system a chance to catch up.
|
# If we need to delete chunks, give the new chunk system a chance to catch up.
|
||||||
effective_render_distance = max(1, effective_render_distance - 1)
|
effective_render_distance = max(1, effective_render_distance - 1)
|
||||||
|
|
||||||
var deleted_this_frame = 0
|
var deleted_this_frame = 0
|
||||||
# We should delete old chunks more aggressively if moving fast.
|
# We should delete old chunks more aggressively if moving fast.
|
||||||
# An easy way to calculate this is by using the effective render distance.
|
# An easy way to calculate this is by using the effective render distance.
|
||||||
@@ -128,7 +128,7 @@ func _delete_far_away_chunks(player_chunk):
|
|||||||
# Continue deleting next frame.
|
# Continue deleting next frame.
|
||||||
_deleting = true
|
_deleting = true
|
||||||
return
|
return
|
||||||
|
|
||||||
# We're done deleting.
|
# We're done deleting.
|
||||||
_deleting = false
|
_deleting = false
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func strsec(secs):
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if !playing or !$Player.playing:
|
if !playing or !$Player.playing:
|
||||||
return
|
return
|
||||||
|
|
||||||
var time = 0.0
|
var time = 0.0
|
||||||
if sync_source == SyncSource.SYSTEM_CLOCK:
|
if sync_source == SyncSource.SYSTEM_CLOCK:
|
||||||
# Obtain from ticks.
|
# Obtain from ticks.
|
||||||
@@ -38,7 +38,7 @@ func _process(_delta):
|
|||||||
time -= time_delay
|
time -= time_delay
|
||||||
elif sync_source == SyncSource.SOUND_CLOCK:
|
elif sync_source == SyncSource.SOUND_CLOCK:
|
||||||
time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES
|
time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES
|
||||||
|
|
||||||
var beat = int(time * BPM / 60.0)
|
var beat = int(time * BPM / 60.0)
|
||||||
var seconds = int(time)
|
var seconds = int(time)
|
||||||
var seconds_total = int($Player.stream.get_length())
|
var seconds_total = int($Player.stream.get_length())
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ onready var item_list = get_node("ItemList")
|
|||||||
func _ready():
|
func _ready():
|
||||||
for item in AudioServer.get_device_list():
|
for item in AudioServer.get_device_list():
|
||||||
item_list.add_item(item)
|
item_list.add_item(item)
|
||||||
|
|
||||||
var device = AudioServer.get_device()
|
var device = AudioServer.get_device()
|
||||||
for i in range(item_list.get_item_count()):
|
for i in range(item_list.get_item_count()):
|
||||||
if device == item_list.get_item_text(i):
|
if device == item_list.get_item_text(i):
|
||||||
@@ -17,14 +17,14 @@ func _ready():
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
var speaker_mode_text = "Stereo"
|
var speaker_mode_text = "Stereo"
|
||||||
var speaker_mode = AudioServer.get_speaker_mode()
|
var speaker_mode = AudioServer.get_speaker_mode()
|
||||||
|
|
||||||
if speaker_mode == AudioServer.SPEAKER_SURROUND_31:
|
if speaker_mode == AudioServer.SPEAKER_SURROUND_31:
|
||||||
speaker_mode_text = "Surround 3.1"
|
speaker_mode_text = "Surround 3.1"
|
||||||
elif speaker_mode == AudioServer.SPEAKER_SURROUND_51:
|
elif speaker_mode == AudioServer.SPEAKER_SURROUND_51:
|
||||||
speaker_mode_text = "Surround 5.1"
|
speaker_mode_text = "Surround 5.1"
|
||||||
elif speaker_mode == AudioServer.SPEAKER_SURROUND_71:
|
elif speaker_mode == AudioServer.SPEAKER_SURROUND_71:
|
||||||
speaker_mode_text = "Surround 7.1"
|
speaker_mode_text = "Surround 7.1"
|
||||||
|
|
||||||
$DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n"
|
$DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n"
|
||||||
$DeviceInfo.text += "Speaker Mode: " + speaker_mode_text
|
$DeviceInfo.text += "Speaker Mode: " + speaker_mode_text
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -14,18 +14,15 @@ while IFS= read -rd '' f; do
|
|||||||
elif [[ "$f" == *"hdr" ]]; then
|
elif [[ "$f" == *"hdr" ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# Ensures that files are UTF-8 formatted.
|
# Ensure that files are UTF-8 formatted.
|
||||||
recode UTF-8 "$f" 2> /dev/null
|
recode UTF-8 "$f" 2> /dev/null
|
||||||
# Ensures that files have LF line endings.
|
# Ensure that files have LF line endings and do not contain a BOM.
|
||||||
dos2unix "$f" 2> /dev/null
|
dos2unix "$f" 2> /dev/null
|
||||||
# Ensures that files do not contain a BOM.
|
# Remove trailing space characters and ensures that files end
|
||||||
sed -i '1s/^\xEF\xBB\xBF//' "$f"
|
# with newline characters. -l option handles newlines conveniently.
|
||||||
# Ensures that files end with newline characters.
|
perl -i -ple 's/\s*$//g' "$f"
|
||||||
tail -c1 < "$f" | read -r _ || echo >> "$f";
|
|
||||||
# Remove trailing space characters.
|
|
||||||
sed -z -i 's/\x20\x0A/\x0A/g' "$f"
|
|
||||||
# Remove the character sequence "== true" if it has a leading space.
|
# Remove the character sequence "== true" if it has a leading space.
|
||||||
sed -z -i 's/\x20== true//g' "$f"
|
perl -i -pe 's/\x20== true//g' "$f"
|
||||||
# We don't want to change lines around braces in godot/tscn files.
|
# We don't want to change lines around braces in godot/tscn files.
|
||||||
if [[ "$f" == *"godot" ]]; then
|
if [[ "$f" == *"godot" ]]; then
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ func get_resource(path):
|
|||||||
var pos = queue.find(res)
|
var pos = queue.find(res)
|
||||||
queue.remove(pos)
|
queue.remove(pos)
|
||||||
queue.insert(0, res)
|
queue.insert(0, res)
|
||||||
|
|
||||||
res = _wait_for_resource(res, path)
|
res = _wait_for_resource(res, path)
|
||||||
pending.erase(path)
|
pending.erase(path)
|
||||||
_unlock("return")
|
_unlock("return")
|
||||||
@@ -116,13 +116,13 @@ func get_resource(path):
|
|||||||
func thread_process():
|
func thread_process():
|
||||||
_wait("thread_process")
|
_wait("thread_process")
|
||||||
_lock("process")
|
_lock("process")
|
||||||
|
|
||||||
while queue.size() > 0:
|
while queue.size() > 0:
|
||||||
var res = queue[0]
|
var res = queue[0]
|
||||||
_unlock("process_poll")
|
_unlock("process_poll")
|
||||||
var ret = res.poll()
|
var ret = res.poll()
|
||||||
_lock("process_check_queue")
|
_lock("process_check_queue")
|
||||||
|
|
||||||
if ret == ERR_FILE_EOF || ret != OK:
|
if ret == ERR_FILE_EOF || ret != OK:
|
||||||
var path = res.get_meta("path")
|
var path = res.get_meta("path")
|
||||||
if path in pending: # Else, it was already retrieved.
|
if path in pending: # Else, it was already retrieved.
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ func _process(_delta):
|
|||||||
# If we're not hovering over a line, ensure they are placed correctly.
|
# If we're not hovering over a line, ensure they are placed correctly.
|
||||||
lines_root.global_position = node_25d.global_position
|
lines_root.global_position = node_25d.global_position
|
||||||
return
|
return
|
||||||
|
|
||||||
lines[dominant_axis].modulate.a = 1
|
lines[dominant_axis].modulate.a = 1
|
||||||
if !wants_to_move:
|
if !wants_to_move:
|
||||||
_moving = false
|
_moving = false
|
||||||
elif wants_to_move and !_moving:
|
elif wants_to_move and !_moving:
|
||||||
_moving = true
|
_moving = true
|
||||||
_start_position = mouse_position
|
_start_position = mouse_position
|
||||||
|
|
||||||
if _moving:
|
if _moving:
|
||||||
# Change modulate of unselected axes.
|
# Change modulate of unselected axes.
|
||||||
lines[(dominant_axis + 1) % 3].modulate.a = 0.5
|
lines[(dominant_axis + 1) % 3].modulate.a = 0.5
|
||||||
@@ -94,12 +94,12 @@ func _distance_to_segment_at_index(index, point):
|
|||||||
return INF
|
return INF
|
||||||
if point.length_squared() < 400:
|
if point.length_squared() < 400:
|
||||||
return INF
|
return INF
|
||||||
|
|
||||||
var segment_end = lines[index].points[1]
|
var segment_end = lines[index].points[1]
|
||||||
var length_squared = segment_end.length_squared()
|
var length_squared = segment_end.length_squared()
|
||||||
if length_squared < 400:
|
if length_squared < 400:
|
||||||
return INF
|
return INF
|
||||||
|
|
||||||
var t = clamp(point.dot(segment_end) / length_squared, 0, 1)
|
var t = clamp(point.dot(segment_end) / length_squared, 0, 1)
|
||||||
var projection = t * segment_end
|
var projection = t * segment_end
|
||||||
return point.distance_to(projection)
|
return point.distance_to(projection)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func _ready():
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
if !editor_interface: # Something's not right... bail!
|
if !editor_interface: # Something's not right... bail!
|
||||||
return
|
return
|
||||||
|
|
||||||
# View mode polling.
|
# View mode polling.
|
||||||
var view_mode_changed_this_frame = false
|
var view_mode_changed_this_frame = false
|
||||||
var new_view_mode = view_mode_button_group.get_pressed_button().get_index()
|
var new_view_mode = view_mode_button_group.get_pressed_button().get_index()
|
||||||
@@ -44,18 +44,18 @@ func _process(delta):
|
|||||||
view_mode_index = new_view_mode
|
view_mode_index = new_view_mode
|
||||||
view_mode_changed_this_frame = true
|
view_mode_changed_this_frame = true
|
||||||
_recursive_change_view_mode(get_tree().edited_scene_root)
|
_recursive_change_view_mode(get_tree().edited_scene_root)
|
||||||
|
|
||||||
# Zooming.
|
# Zooming.
|
||||||
if Input.is_mouse_button_pressed(BUTTON_WHEEL_UP):
|
if Input.is_mouse_button_pressed(BUTTON_WHEEL_UP):
|
||||||
zoom_level += 1
|
zoom_level += 1
|
||||||
elif Input.is_mouse_button_pressed(BUTTON_WHEEL_DOWN):
|
elif Input.is_mouse_button_pressed(BUTTON_WHEEL_DOWN):
|
||||||
zoom_level -= 1
|
zoom_level -= 1
|
||||||
var zoom = _get_zoom_amount()
|
var zoom = _get_zoom_amount()
|
||||||
|
|
||||||
# Viewport size.
|
# Viewport size.
|
||||||
var size = get_global_rect().size
|
var size = get_global_rect().size
|
||||||
viewport_2d.size = size
|
viewport_2d.size = size
|
||||||
|
|
||||||
# Viewport transform.
|
# Viewport transform.
|
||||||
var viewport_trans = Transform2D.IDENTITY
|
var viewport_trans = Transform2D.IDENTITY
|
||||||
viewport_trans.x *= zoom
|
viewport_trans.x *= zoom
|
||||||
@@ -63,7 +63,7 @@ func _process(delta):
|
|||||||
viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
|
viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
|
||||||
viewport_2d.canvas_transform = viewport_trans
|
viewport_2d.canvas_transform = viewport_trans
|
||||||
viewport_overlay.canvas_transform = viewport_trans
|
viewport_overlay.canvas_transform = viewport_trans
|
||||||
|
|
||||||
# Delete unused gizmos.
|
# Delete unused gizmos.
|
||||||
var selection = editor_interface.get_selection().get_selected_nodes()
|
var selection = editor_interface.get_selection().get_selected_nodes()
|
||||||
var overlay_children = viewport_overlay.get_children()
|
var overlay_children = viewport_overlay.get_children()
|
||||||
@@ -74,7 +74,7 @@ func _process(delta):
|
|||||||
contains = true
|
contains = true
|
||||||
if !contains:
|
if !contains:
|
||||||
overlay_child.queue_free()
|
overlay_child.queue_free()
|
||||||
|
|
||||||
# Add new gizmos.
|
# Add new gizmos.
|
||||||
for selected in selection:
|
for selected in selection:
|
||||||
if selected is Node25D:
|
if selected is Node25D:
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ var main_panel_instance
|
|||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
main_panel_instance = MainPanel.instance()
|
main_panel_instance = MainPanel.instance()
|
||||||
main_panel_instance.get_child(1).editor_interface = get_editor_interface()
|
main_panel_instance.get_child(1).editor_interface = get_editor_interface()
|
||||||
|
|
||||||
# Add the main panel to the editor's main viewport.
|
# Add the main panel to the editor's main viewport.
|
||||||
get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
|
get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
|
||||||
|
|
||||||
# Hide the main panel.
|
# Hide the main panel.
|
||||||
make_visible(false)
|
make_visible(false)
|
||||||
# When this plugin node enters tree, add the custom types.
|
# When this plugin node enters tree, add the custom types.
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ func Node25D_process():
|
|||||||
if _spatial_node == null:
|
if _spatial_node == null:
|
||||||
return
|
return
|
||||||
_spatial_position = _spatial_node.translation
|
_spatial_position = _spatial_node.translation
|
||||||
|
|
||||||
var flat_pos = _spatial_position.x * _basisX
|
var flat_pos = _spatial_position.x * _basisX
|
||||||
flat_pos += _spatial_position.y * _basisY
|
flat_pos += _spatial_position.y * _basisY
|
||||||
flat_pos += _spatial_position.z * _basisZ
|
flat_pos += _spatial_position.z * _basisZ
|
||||||
|
|
||||||
global_position = flat_pos
|
global_position = flat_pos
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func _process(_delta):
|
|||||||
if _shadow_root != null:
|
if _shadow_root != null:
|
||||||
_shadow_root.visible = false
|
_shadow_root.visible = false
|
||||||
return # Shadow is not in a valid place or you're viewing the Shadow25D scene.
|
return # Shadow is not in a valid place or you're viewing the Shadow25D scene.
|
||||||
|
|
||||||
translation = _target_math.translation
|
translation = _target_math.translation
|
||||||
var k = move_and_collide(Vector3.DOWN * shadow_length)
|
var k = move_and_collide(Vector3.DOWN * shadow_length)
|
||||||
if k == null:
|
if k == null:
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func sort():
|
|||||||
# The Z index only goes from -4096 to 4096, and we want room for objects having multiple layers.
|
# The Z index only goes from -4096 to 4096, and we want room for objects having multiple layers.
|
||||||
printerr("Sorting failed: Max number of YSort25D nodes is 4000.")
|
printerr("Sorting failed: Max number of YSort25D nodes is 4000.")
|
||||||
return
|
return
|
||||||
|
|
||||||
# We only want to get Node25D children.
|
# We only want to get Node25D children.
|
||||||
# Currently, it also grabs Node2D children.
|
# Currently, it also grabs Node2D children.
|
||||||
var node25d_nodes = []
|
var node25d_nodes = []
|
||||||
@@ -37,7 +37,7 @@ func sort():
|
|||||||
if n.get_class() == "Node2D":
|
if n.get_class() == "Node2D":
|
||||||
node25d_nodes.append(n)
|
node25d_nodes.append(n)
|
||||||
node25d_nodes.sort_custom(Node25D, "y_sort_slight_xz")
|
node25d_nodes.sort_custom(Node25D, "y_sort_slight_xz")
|
||||||
|
|
||||||
var z_index = -4000
|
var z_index = -4000
|
||||||
for i in range(0, node25d_nodes.size()):
|
for i in range(0, node25d_nodes.size()):
|
||||||
node25d_nodes[i].z_index = z_index
|
node25d_nodes[i].z_index = z_index
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ var _cube_math_spatials = []
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_parent = get_parent()
|
_parent = get_parent()
|
||||||
|
|
||||||
for i in range(27):
|
for i in range(27):
|
||||||
# warning-ignore:integer_division
|
# warning-ignore:integer_division
|
||||||
var a: int = (i / 9) - 1
|
var a: int = (i / 9) - 1
|
||||||
@@ -26,12 +26,12 @@ func _ready():
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
if Input.is_action_pressed("exit"):
|
if Input.is_action_pressed("exit"):
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
if Input.is_action_just_pressed("view_cube_demo"):
|
if Input.is_action_just_pressed("view_cube_demo"):
|
||||||
# warning-ignore:return_value_discarded
|
# warning-ignore:return_value_discarded
|
||||||
get_tree().change_scene("res://assets/demo_scene.tscn")
|
get_tree().change_scene("res://assets/demo_scene.tscn")
|
||||||
return
|
return
|
||||||
|
|
||||||
if _is_parent_ready:
|
if _is_parent_ready:
|
||||||
if Input.is_action_just_pressed("reset_position"):
|
if Input.is_action_just_pressed("reset_position"):
|
||||||
transform = Transform.IDENTITY
|
transform = Transform.IDENTITY
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ onready var _parent_node25d: Node25D = get_parent()
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
if Input.is_action_pressed("exit"):
|
if Input.is_action_pressed("exit"):
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
if Input.is_action_just_pressed("view_cube_demo"):
|
if Input.is_action_just_pressed("view_cube_demo"):
|
||||||
#warning-ignore:return_value_discarded
|
#warning-ignore:return_value_discarded
|
||||||
get_tree().change_scene("res://assets/cube/cube.tscn")
|
get_tree().change_scene("res://assets/cube/cube.tscn")
|
||||||
return
|
return
|
||||||
|
|
||||||
if Input.is_action_just_pressed("toggle_isometric_controls"):
|
if Input.is_action_just_pressed("toggle_isometric_controls"):
|
||||||
isometric_controls = !isometric_controls
|
isometric_controls = !isometric_controls
|
||||||
if Input.is_action_just_pressed("reset_position"):
|
if Input.is_action_just_pressed("reset_position"):
|
||||||
@@ -29,20 +29,20 @@ func _process(delta):
|
|||||||
func _horizontal_movement(delta):
|
func _horizontal_movement(delta):
|
||||||
var localX = Vector3.RIGHT
|
var localX = Vector3.RIGHT
|
||||||
var localZ = Vector3.BACK
|
var localZ = Vector3.BACK
|
||||||
|
|
||||||
if isometric_controls && is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
|
if isometric_controls && is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
|
||||||
localX = Vector3(0.70710678118, 0, -0.70710678118)
|
localX = Vector3(0.70710678118, 0, -0.70710678118)
|
||||||
localZ = Vector3(0.70710678118, 0, 0.70710678118)
|
localZ = Vector3(0.70710678118, 0, 0.70710678118)
|
||||||
|
|
||||||
# Gather player input and add directional movement to a Vector3 variable.
|
# Gather player input and add directional movement to a Vector3 variable.
|
||||||
var move_dir = Vector3()
|
var move_dir = Vector3()
|
||||||
move_dir += localX * (Input.get_action_strength("move_right") - Input.get_action_strength("move_left"))
|
move_dir += localX * (Input.get_action_strength("move_right") - Input.get_action_strength("move_left"))
|
||||||
move_dir += localZ * (Input.get_action_strength("move_back") - Input.get_action_strength("move_forward"))
|
move_dir += localZ * (Input.get_action_strength("move_back") - Input.get_action_strength("move_forward"))
|
||||||
|
|
||||||
move_dir = move_dir.normalized() * delta * 600;
|
move_dir = move_dir.normalized() * delta * 600;
|
||||||
if Input.is_action_pressed("movement_modifier"):
|
if Input.is_action_pressed("movement_modifier"):
|
||||||
move_dir /= 2;
|
move_dir /= 2;
|
||||||
|
|
||||||
#warning-ignore:return_value_discarded
|
#warning-ignore:return_value_discarded
|
||||||
move_and_slide(move_dir)
|
move_and_slide(move_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ func _ready():
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
return # Don't run this in the editor.
|
return # Don't run this in the editor.
|
||||||
|
|
||||||
_sprite_basis()
|
_sprite_basis()
|
||||||
var movement = _check_movement() # Always run to get direction, but don't always use return bool.
|
var movement = _check_movement() # Always run to get direction, but don't always use return bool.
|
||||||
|
|
||||||
# Test-only move and collide, check if the player is on the ground.
|
# Test-only move and collide, check if the player is on the ground.
|
||||||
var k = _parent_math.move_and_collide(Vector3.DOWN * 10 * delta, true, true, true)
|
var k = _parent_math.move_and_collide(Vector3.DOWN * 10 * delta, true, true, true)
|
||||||
if k != null:
|
if k != null:
|
||||||
@@ -90,7 +90,7 @@ func _check_movement() -> bool:
|
|||||||
# Gather player input and store movement to these int variables. Note: These indeed have to be integers.
|
# Gather player input and store movement to these int variables. Note: These indeed have to be integers.
|
||||||
var x := 0
|
var x := 0
|
||||||
var z := 0
|
var z := 0
|
||||||
|
|
||||||
if Input.is_action_pressed("move_right"):
|
if Input.is_action_pressed("move_right"):
|
||||||
x += 1
|
x += 1
|
||||||
if Input.is_action_pressed("move_left"):
|
if Input.is_action_pressed("move_left"):
|
||||||
@@ -99,7 +99,7 @@ func _check_movement() -> bool:
|
|||||||
z -= 1
|
z -= 1
|
||||||
if Input.is_action_pressed("move_back"):
|
if Input.is_action_pressed("move_back"):
|
||||||
z += 1
|
z += 1
|
||||||
|
|
||||||
# Check for isometric controls and add more to movement accordingly.
|
# Check for isometric controls and add more to movement accordingly.
|
||||||
# For efficiency, only check the X axis since this X axis value isn't used anywhere else.
|
# For efficiency, only check the X axis since this X axis value isn't used anywhere else.
|
||||||
if !_parent_math.isometric_controls && is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
|
if !_parent_math.isometric_controls && is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
|
||||||
@@ -111,7 +111,7 @@ func _check_movement() -> bool:
|
|||||||
x += 1
|
x += 1
|
||||||
if Input.is_action_pressed("move_back"):
|
if Input.is_action_pressed("move_back"):
|
||||||
x -= 1
|
x -= 1
|
||||||
|
|
||||||
# Set the direction based on which inputs were pressed.
|
# Set the direction based on which inputs were pressed.
|
||||||
if x == 0:
|
if x == 0:
|
||||||
if z == 0:
|
if z == 0:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ extends Node2D
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
var line: Line2D = get_child(0).get_child(0)
|
var line: Line2D = get_child(0).get_child(0)
|
||||||
var marker_parent: Node2D = get_parent()
|
var marker_parent: Node2D = get_parent()
|
||||||
|
|
||||||
line.points[1] = transform.origin
|
line.points[1] = transform.origin
|
||||||
if marker_parent as Node2D != null:
|
if marker_parent as Node2D != null:
|
||||||
line.transform = marker_parent.global_transform
|
line.transform = marker_parent.global_transform
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ func _process(_delta):
|
|||||||
holder.transform = Transform()
|
holder.transform = Transform()
|
||||||
cube.transform = Transform().scaled(Vector3.ONE * 0.0001)
|
cube.transform = Transform().scaled(Vector3.ONE * 0.0001)
|
||||||
return
|
return
|
||||||
|
|
||||||
holder.transform = Transform(Basis(), translation / 2)
|
holder.transform = Transform(Basis(), translation / 2)
|
||||||
holder.transform = holder.transform.looking_at(translation, Vector3.UP)
|
holder.transform = holder.transform.looking_at(translation, Vector3.UP)
|
||||||
holder.transform = get_parent().global_transform * holder.transform
|
holder.transform = get_parent().global_transform * holder.transform
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _unhandled_input(event):
|
|||||||
else: # Up.
|
else: # Up.
|
||||||
state.erase(event.index)
|
state.erase(event.index)
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
elif event is InputEventScreenDrag: # Movement.
|
elif event is InputEventScreenDrag: # Movement.
|
||||||
state[event.index] = event.position
|
state[event.index] = event.position
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|||||||
@@ -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:
|
||||||
@@ -111,27 +111,27 @@ func _process(delta):
|
|||||||
# 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()
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class Gizmo25D : Node2D
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Color modulate = lines[dominantAxis].Modulate;
|
Color modulate = lines[dominantAxis].Modulate;
|
||||||
modulate.a = 1;
|
modulate.a = 1;
|
||||||
lines[dominantAxis].Modulate = modulate;
|
lines[dominantAxis].Modulate = modulate;
|
||||||
@@ -86,7 +86,7 @@ public class Gizmo25D : Node2D
|
|||||||
_moving = true;
|
_moving = true;
|
||||||
_startPosition = mousePosition;
|
_startPosition = mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_moving)
|
if (_moving)
|
||||||
{
|
{
|
||||||
// Change modulate of unselected axes.
|
// Change modulate of unselected axes.
|
||||||
@@ -153,14 +153,14 @@ public class Gizmo25D : Node2D
|
|||||||
{
|
{
|
||||||
return Mathf.Inf;
|
return Mathf.Inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 segmentEnd = lines[index].Points[1];
|
Vector2 segmentEnd = lines[index].Points[1];
|
||||||
float lengthSquared = segmentEnd.LengthSquared();
|
float lengthSquared = segmentEnd.LengthSquared();
|
||||||
if (lengthSquared < 400)
|
if (lengthSquared < 400)
|
||||||
{
|
{
|
||||||
return Mathf.Inf;
|
return Mathf.Inf;
|
||||||
}
|
}
|
||||||
|
|
||||||
var t = Mathf.Clamp(point.Dot(segmentEnd) / lengthSquared, 0, 1);
|
var t = Mathf.Clamp(point.Dot(segmentEnd) / lengthSquared, 0, 1);
|
||||||
var projection = t * segmentEnd;
|
var projection = t * segmentEnd;
|
||||||
return point.DistanceTo(projection);
|
return point.DistanceTo(projection);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func _ready():
|
|||||||
func _process(delta):
|
func _process(delta):
|
||||||
if !editor_interface: # Something's not right... bail!
|
if !editor_interface: # Something's not right... bail!
|
||||||
return
|
return
|
||||||
|
|
||||||
# View mode polling.
|
# View mode polling.
|
||||||
var view_mode_changed_this_frame = false
|
var view_mode_changed_this_frame = false
|
||||||
var new_view_mode = view_mode_button_group.get_pressed_button().get_index()
|
var new_view_mode = view_mode_button_group.get_pressed_button().get_index()
|
||||||
@@ -44,18 +44,18 @@ func _process(delta):
|
|||||||
view_mode_index = new_view_mode
|
view_mode_index = new_view_mode
|
||||||
view_mode_changed_this_frame = true
|
view_mode_changed_this_frame = true
|
||||||
_recursive_change_view_mode(get_tree().edited_scene_root)
|
_recursive_change_view_mode(get_tree().edited_scene_root)
|
||||||
|
|
||||||
# Zooming.
|
# Zooming.
|
||||||
if Input.is_mouse_button_pressed(BUTTON_WHEEL_UP):
|
if Input.is_mouse_button_pressed(BUTTON_WHEEL_UP):
|
||||||
zoom_level += 1
|
zoom_level += 1
|
||||||
elif Input.is_mouse_button_pressed(BUTTON_WHEEL_DOWN):
|
elif Input.is_mouse_button_pressed(BUTTON_WHEEL_DOWN):
|
||||||
zoom_level -= 1
|
zoom_level -= 1
|
||||||
var zoom = _get_zoom_amount()
|
var zoom = _get_zoom_amount()
|
||||||
|
|
||||||
# Viewport size.
|
# Viewport size.
|
||||||
var size = get_global_rect().size
|
var size = get_global_rect().size
|
||||||
viewport_2d.size = size
|
viewport_2d.size = size
|
||||||
|
|
||||||
# Viewport transform.
|
# Viewport transform.
|
||||||
var viewport_trans = Transform2D.IDENTITY
|
var viewport_trans = Transform2D.IDENTITY
|
||||||
viewport_trans.x *= zoom
|
viewport_trans.x *= zoom
|
||||||
@@ -63,7 +63,7 @@ func _process(delta):
|
|||||||
viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
|
viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
|
||||||
viewport_2d.canvas_transform = viewport_trans
|
viewport_2d.canvas_transform = viewport_trans
|
||||||
viewport_overlay.canvas_transform = viewport_trans
|
viewport_overlay.canvas_transform = viewport_trans
|
||||||
|
|
||||||
# Delete unused gizmos.
|
# Delete unused gizmos.
|
||||||
var selection = editor_interface.get_selection().get_selected_nodes()
|
var selection = editor_interface.get_selection().get_selected_nodes()
|
||||||
var overlay_children = viewport_overlay.get_children()
|
var overlay_children = viewport_overlay.get_children()
|
||||||
@@ -74,7 +74,7 @@ func _process(delta):
|
|||||||
contains = true
|
contains = true
|
||||||
if !contains:
|
if !contains:
|
||||||
overlay_child.queue_free()
|
overlay_child.queue_free()
|
||||||
|
|
||||||
# Add new gizmos.
|
# Add new gizmos.
|
||||||
for selected in selection:
|
for selected in selection:
|
||||||
if selected.has_method("Node25DReady"):
|
if selected.has_method("Node25DReady"):
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ func _enter_tree():
|
|||||||
main_panel_instance = MainPanel.instance()
|
main_panel_instance = MainPanel.instance()
|
||||||
#main_panel_instance.get_child(1).set("editorInterface", get_editor_interface()) # For C#
|
#main_panel_instance.get_child(1).set("editorInterface", get_editor_interface()) # For C#
|
||||||
main_panel_instance.get_child(1).editor_interface = get_editor_interface()
|
main_panel_instance.get_child(1).editor_interface = get_editor_interface()
|
||||||
|
|
||||||
# Add the main panel to the editor's main viewport.
|
# Add the main panel to the editor's main viewport.
|
||||||
get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
|
get_editor_interface().get_editor_viewport().add_child(main_panel_instance)
|
||||||
|
|
||||||
# Hide the main panel.
|
# Hide the main panel.
|
||||||
make_visible(false)
|
make_visible(false)
|
||||||
|
|
||||||
# When this plugin node enters tree, add the custom types.
|
# When this plugin node enters tree, add the custom types.
|
||||||
add_custom_type("Node25D", "Node2D", preload("Node25D.cs"), preload("icons/node_25d_icon.png"))
|
add_custom_type("Node25D", "Node2D", preload("Node25D.cs"), preload("icons/node_25d_icon.png"))
|
||||||
add_custom_type("YSort25D", "Node", preload("YSort25D.cs"), preload("icons/y_sort_25d_icon.png"))
|
add_custom_type("YSort25D", "Node", preload("YSort25D.cs"), preload("icons/y_sort_25d_icon.png"))
|
||||||
@@ -24,7 +24,7 @@ func _enter_tree():
|
|||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
main_panel_instance.queue_free()
|
main_panel_instance.queue_free()
|
||||||
|
|
||||||
# When the plugin node exits the tree, remove the custom types.
|
# When the plugin node exits the tree, remove the custom types.
|
||||||
remove_custom_type("ShadowMath25D")
|
remove_custom_type("ShadowMath25D")
|
||||||
remove_custom_type("YSort25D")
|
remove_custom_type("YSort25D")
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ func _process(delta):
|
|||||||
# so each player sees the motion as smooth and not jerky.
|
# so each player sees the motion as smooth and not jerky.
|
||||||
if not stopped:
|
if not stopped:
|
||||||
translate(_speed * delta * direction)
|
translate(_speed * delta * direction)
|
||||||
|
|
||||||
# Check screen bounds to make ball bounce.
|
# Check screen bounds to make ball bounce.
|
||||||
var ball_pos = position
|
var ball_pos = position
|
||||||
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > _screen_size.y and direction.y > 0):
|
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > _screen_size.y and direction.y > 0):
|
||||||
direction.y = -direction.y
|
direction.y = -direction.y
|
||||||
|
|
||||||
if is_network_master():
|
if is_network_master():
|
||||||
# Only master will decide when the ball is out in the left side (it's own side).
|
# Only master will decide when the ball is out in the left side (it's own side).
|
||||||
# This makes the game playable even if latency is high and ball is going fast.
|
# This makes the game playable even if latency is high and ball is going fast.
|
||||||
@@ -43,7 +43,7 @@ sync func bounce(left, random):
|
|||||||
direction.x = abs(direction.x)
|
direction.x = abs(direction.x)
|
||||||
else:
|
else:
|
||||||
direction.x = -abs(direction.x)
|
direction.x = -abs(direction.x)
|
||||||
|
|
||||||
_speed *= 1.1
|
_speed *= 1.1
|
||||||
direction.y = random * 2.0 - 1
|
direction.y = random * 2.0 - 1
|
||||||
direction = direction.normalized()
|
direction = direction.normalized()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func _player_connected(_id):
|
|||||||
var pong = load("res://pong.tscn").instance()
|
var pong = load("res://pong.tscn").instance()
|
||||||
# Connect deferred so we can safely erase it from the callback.
|
# Connect deferred so we can safely erase it from the callback.
|
||||||
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED)
|
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED)
|
||||||
|
|
||||||
get_tree().get_root().add_child(pong)
|
get_tree().get_root().add_child(pong)
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ func _connected_ok():
|
|||||||
# Callback from SceneTree, only for clients (not server).
|
# Callback from SceneTree, only for clients (not server).
|
||||||
func _connected_fail():
|
func _connected_fail():
|
||||||
_set_status("Couldn't connect", false)
|
_set_status("Couldn't connect", false)
|
||||||
|
|
||||||
get_tree().set_network_peer(null) # Remove peer.
|
get_tree().set_network_peer(null) # Remove peer.
|
||||||
host_button.set_disabled(false)
|
host_button.set_disabled(false)
|
||||||
join_button.set_disabled(false)
|
join_button.set_disabled(false)
|
||||||
@@ -62,11 +62,11 @@ func _end_game(with_error = ""):
|
|||||||
# Erase immediately, otherwise network might show errors (this is why we connected deferred above).
|
# Erase immediately, otherwise network might show errors (this is why we connected deferred above).
|
||||||
get_node("/root/Pong").free()
|
get_node("/root/Pong").free()
|
||||||
show()
|
show()
|
||||||
|
|
||||||
get_tree().set_network_peer(null) # Remove peer.
|
get_tree().set_network_peer(null) # Remove peer.
|
||||||
host_button.set_disabled(false)
|
host_button.set_disabled(false)
|
||||||
join_button.set_disabled(false)
|
join_button.set_disabled(false)
|
||||||
|
|
||||||
_set_status(with_error, false)
|
_set_status(with_error, false)
|
||||||
|
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ func _on_host_pressed():
|
|||||||
# Is another server running?
|
# Is another server running?
|
||||||
_set_status("Can't host, address in use.",false)
|
_set_status("Can't host, address in use.",false)
|
||||||
return
|
return
|
||||||
|
|
||||||
get_tree().set_network_peer(peer)
|
get_tree().set_network_peer(peer)
|
||||||
host_button.set_disabled(true)
|
host_button.set_disabled(true)
|
||||||
join_button.set_disabled(true)
|
join_button.set_disabled(true)
|
||||||
@@ -100,10 +100,10 @@ func _on_join_pressed():
|
|||||||
if not ip.is_valid_ip_address():
|
if not ip.is_valid_ip_address():
|
||||||
_set_status("IP address is invalid", false)
|
_set_status("IP address is invalid", false)
|
||||||
return
|
return
|
||||||
|
|
||||||
peer = NetworkedMultiplayerENet.new()
|
peer = NetworkedMultiplayerENet.new()
|
||||||
peer.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
peer.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||||
peer.create_client(ip, DEFAULT_PORT)
|
peer.create_client(ip, DEFAULT_PORT)
|
||||||
get_tree().set_network_peer(peer)
|
get_tree().set_network_peer(peer)
|
||||||
|
|
||||||
_set_status("Connecting...", true)
|
_set_status("Connecting...", true)
|
||||||
|
|||||||
@@ -13,21 +13,21 @@ func _process(delta):
|
|||||||
# Is the master of the paddle.
|
# Is the master of the paddle.
|
||||||
if is_network_master():
|
if is_network_master():
|
||||||
motion = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
motion = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
|
||||||
|
|
||||||
if not you_hidden and motion != 0:
|
if not you_hidden and motion != 0:
|
||||||
_hide_you_label()
|
_hide_you_label()
|
||||||
|
|
||||||
motion *= MOTION_SPEED
|
motion *= MOTION_SPEED
|
||||||
|
|
||||||
# Using unreliable to make sure position is updated as fast
|
# Using unreliable to make sure position is updated as fast
|
||||||
# as possible, even if one of the calls is dropped.
|
# as possible, even if one of the calls is dropped.
|
||||||
rpc_unreliable("set_pos_and_motion", position, motion)
|
rpc_unreliable("set_pos_and_motion", position, motion)
|
||||||
else:
|
else:
|
||||||
if not you_hidden:
|
if not you_hidden:
|
||||||
_hide_you_label()
|
_hide_you_label()
|
||||||
|
|
||||||
translate(Vector2(0, motion * delta))
|
translate(Vector2(0, motion * delta))
|
||||||
|
|
||||||
# Set screen limits.
|
# Set screen limits.
|
||||||
position.y = clamp(position.y, 16, _screen_size_y - 16)
|
position.y = clamp(position.y, 16, _screen_size_y - 16)
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ sync func update_score(add_to_left):
|
|||||||
else:
|
else:
|
||||||
score_right += 1
|
score_right += 1
|
||||||
score_right_node.set_text(str(score_right))
|
score_right_node.set_text(str(score_right))
|
||||||
|
|
||||||
var game_ended = false
|
var game_ended = false
|
||||||
if score_left == SCORE_TO_WIN:
|
if score_left == SCORE_TO_WIN:
|
||||||
winner_left.show()
|
winner_left.show()
|
||||||
@@ -41,7 +41,7 @@ sync func update_score(add_to_left):
|
|||||||
elif score_right == SCORE_TO_WIN:
|
elif score_right == SCORE_TO_WIN:
|
||||||
winner_right.show()
|
winner_right.show()
|
||||||
game_ended = true
|
game_ended = true
|
||||||
|
|
||||||
if game_ended:
|
if game_ended:
|
||||||
$ExitGame.show()
|
$ExitGame.show()
|
||||||
$Ball.rpc("stop")
|
$Ball.rpc("stop")
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func apply_pressed():
|
|||||||
var selected_nodes = editor_selection.get_selected_nodes()
|
var selected_nodes = editor_selection.get_selected_nodes()
|
||||||
if selected_nodes.size() == 0:
|
if selected_nodes.size() == 0:
|
||||||
printerr("Material Creator: Can't apply the material, because there are no nodes selected!")
|
printerr("Material Creator: Can't apply the material, because there are no nodes selected!")
|
||||||
|
|
||||||
var material = _silly_resource_from_values().make_material()
|
var material = _silly_resource_from_values().make_material()
|
||||||
# Go through the selected nodes and see if they have the "set_surface_material"
|
# Go through the selected nodes and see if they have the "set_surface_material"
|
||||||
# function (which only MeshInstance has by default). If they do, then set the material
|
# function (which only MeshInstance has by default). If they do, then set the material
|
||||||
@@ -46,23 +46,23 @@ func save_file_selected(path):
|
|||||||
file.open(path, File.WRITE)
|
file.open(path, File.WRITE)
|
||||||
file.store_string(silly_resource.make_json())
|
file.store_string(silly_resource.make_json())
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
||||||
func load_file_selected(path):
|
func load_file_selected(path):
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
var SpatialMaterial_Silly = null
|
var SpatialMaterial_Silly = null
|
||||||
|
|
||||||
# Make a new silly resource (which in this case actually is a node)
|
# Make a new silly resource (which in this case actually is a node)
|
||||||
# and initialize it
|
# and initialize it
|
||||||
var silly_resource = silly_material_resource.new()
|
var silly_resource = silly_material_resource.new()
|
||||||
silly_resource.init()
|
silly_resource.init()
|
||||||
|
|
||||||
# If the file exists, then open it
|
# If the file exists, then open it
|
||||||
if file.file_exists(path):
|
if file.file_exists(path):
|
||||||
file.open(path, File.READ)
|
file.open(path, File.READ)
|
||||||
|
|
||||||
# Get the JSON string and convert it into a silly material.
|
# Get the JSON string and convert it into a silly material.
|
||||||
var json_dict_as_string = file.get_line()
|
var json_dict_as_string = file.get_line()
|
||||||
if json_dict_as_string != null:
|
if json_dict_as_string != null:
|
||||||
@@ -70,15 +70,15 @@ func load_file_selected(path):
|
|||||||
else:
|
else:
|
||||||
file.close()
|
file.close()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
get_node("VBoxContainer/AlbedoColorPicker").color = silly_resource.albedo_color
|
get_node("VBoxContainer/AlbedoColorPicker").color = silly_resource.albedo_color
|
||||||
get_node("VBoxContainer/MetallicSlider").value = silly_resource.metallic_strength
|
get_node("VBoxContainer/MetallicSlider").value = silly_resource.metallic_strength
|
||||||
get_node("VBoxContainer/RoughnessSlider").value = silly_resource.roughness_strength
|
get_node("VBoxContainer/RoughnessSlider").value = silly_resource.roughness_strength
|
||||||
|
|
||||||
# Close the file and return true (success!)
|
# Close the file and return true (success!)
|
||||||
file.close()
|
file.close()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
#else: If the file does not exist, then return false (failure)
|
#else: If the file does not exist, then return false (failure)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ func _silly_resource_from_values():
|
|||||||
# Make a new silly resource (which in this case actually is a node) and initialize it
|
# Make a new silly resource (which in this case actually is a node) and initialize it
|
||||||
var silly_resource = silly_material_resource.new()
|
var silly_resource = silly_material_resource.new()
|
||||||
silly_resource.init()
|
silly_resource.init()
|
||||||
|
|
||||||
# Assign the values
|
# Assign the values
|
||||||
silly_resource.albedo_color = color
|
silly_resource.albedo_color = color
|
||||||
silly_resource.metallic_strength = metallic
|
silly_resource.metallic_strength = metallic
|
||||||
silly_resource.roughness_strength = roughness
|
silly_resource.roughness_strength = roughness
|
||||||
|
|
||||||
return silly_resource
|
return silly_resource
|
||||||
|
|||||||
@@ -21,15 +21,15 @@ func init():
|
|||||||
# into the JSON format
|
# into the JSON format
|
||||||
func make_json():
|
func make_json():
|
||||||
var json_dict = {}
|
var json_dict = {}
|
||||||
|
|
||||||
json_dict["albedo_color"] = {}
|
json_dict["albedo_color"] = {}
|
||||||
json_dict["albedo_color"]["r"] = albedo_color.r
|
json_dict["albedo_color"]["r"] = albedo_color.r
|
||||||
json_dict["albedo_color"]["g"] = albedo_color.g
|
json_dict["albedo_color"]["g"] = albedo_color.g
|
||||||
json_dict["albedo_color"]["b"] = albedo_color.b
|
json_dict["albedo_color"]["b"] = albedo_color.b
|
||||||
|
|
||||||
json_dict["metallic_strength"] = metallic_strength
|
json_dict["metallic_strength"] = metallic_strength
|
||||||
json_dict["roughness_strength"] = roughness_strength
|
json_dict["roughness_strength"] = roughness_strength
|
||||||
|
|
||||||
return to_json(json_dict)
|
return to_json(json_dict)
|
||||||
|
|
||||||
|
|
||||||
@@ -37,11 +37,11 @@ func make_json():
|
|||||||
# fill in our data.
|
# fill in our data.
|
||||||
func from_json(json_dict_as_string):
|
func from_json(json_dict_as_string):
|
||||||
var json_dict = parse_json(json_dict_as_string)
|
var json_dict = parse_json(json_dict_as_string)
|
||||||
|
|
||||||
albedo_color.r = json_dict["albedo_color"]["r"]
|
albedo_color.r = json_dict["albedo_color"]["r"]
|
||||||
albedo_color.g = json_dict["albedo_color"]["g"]
|
albedo_color.g = json_dict["albedo_color"]["g"]
|
||||||
albedo_color.b = json_dict["albedo_color"]["b"]
|
albedo_color.b = json_dict["albedo_color"]["b"]
|
||||||
|
|
||||||
metallic_strength = json_dict["metallic_strength"]
|
metallic_strength = json_dict["metallic_strength"]
|
||||||
roughness_strength = json_dict["roughness_strength"]
|
roughness_strength = json_dict["roughness_strength"]
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ func from_json(json_dict_as_string):
|
|||||||
# Make a SpatialMaterial using our variables.
|
# Make a SpatialMaterial using our variables.
|
||||||
func make_material():
|
func make_material():
|
||||||
var mat = SpatialMaterial.new()
|
var mat = SpatialMaterial.new()
|
||||||
|
|
||||||
mat.albedo_color = albedo_color
|
mat.albedo_color = albedo_color
|
||||||
mat.metallic = metallic_strength
|
mat.metallic = metallic_strength
|
||||||
mat.roughness = roughness_strength
|
mat.roughness = roughness_strength
|
||||||
|
|
||||||
return mat
|
return mat
|
||||||
|
|||||||
@@ -24,44 +24,44 @@ func _process(delta):
|
|||||||
var ball_pos = ball.get_position()
|
var ball_pos = ball.get_position()
|
||||||
var left_rect = Rect2(left_paddle.get_position() - pad_size * 0.5, pad_size)
|
var left_rect = Rect2(left_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||||
var right_rect = Rect2(right_paddle.get_position() - pad_size * 0.5, pad_size)
|
var right_rect = Rect2(right_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||||
|
|
||||||
# Integrate new ball postion.
|
# Integrate new ball postion.
|
||||||
ball_pos += direction * ball_speed * delta
|
ball_pos += direction * ball_speed * delta
|
||||||
|
|
||||||
# Flip when touching roof or floor.
|
# Flip when touching roof or floor.
|
||||||
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0):
|
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0):
|
||||||
direction.y = -direction.y
|
direction.y = -direction.y
|
||||||
|
|
||||||
# Flip, change direction and increase speed when touching pads.
|
# Flip, change direction and increase speed when touching pads.
|
||||||
if (left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0):
|
if (left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0):
|
||||||
direction.x = -direction.x
|
direction.x = -direction.x
|
||||||
ball_speed *= 1.1
|
ball_speed *= 1.1
|
||||||
direction.y = randf() * 2.0 - 1
|
direction.y = randf() * 2.0 - 1
|
||||||
direction = direction.normalized()
|
direction = direction.normalized()
|
||||||
|
|
||||||
# Check gameover.
|
# Check gameover.
|
||||||
if ball_pos.x < 0 or ball_pos.x > screen_size.x:
|
if ball_pos.x < 0 or ball_pos.x > screen_size.x:
|
||||||
ball_pos = screen_size * 0.5
|
ball_pos = screen_size * 0.5
|
||||||
ball_speed = INITIAL_BALL_SPEED
|
ball_speed = INITIAL_BALL_SPEED
|
||||||
direction = Vector2(-1, 0)
|
direction = Vector2(-1, 0)
|
||||||
|
|
||||||
ball.set_position(ball_pos)
|
ball.set_position(ball_pos)
|
||||||
|
|
||||||
# Move left pad.
|
# Move left pad.
|
||||||
var left_pos = left_paddle.get_position()
|
var left_pos = left_paddle.get_position()
|
||||||
|
|
||||||
if left_pos.y > 0 and Input.is_action_pressed("left_move_up"):
|
if left_pos.y > 0 and Input.is_action_pressed("left_move_up"):
|
||||||
left_pos.y += -PAD_SPEED * delta
|
left_pos.y += -PAD_SPEED * delta
|
||||||
if left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down"):
|
if left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down"):
|
||||||
left_pos.y += PAD_SPEED * delta
|
left_pos.y += PAD_SPEED * delta
|
||||||
|
|
||||||
left_paddle.set_position(left_pos)
|
left_paddle.set_position(left_pos)
|
||||||
|
|
||||||
# Move right pad.
|
# Move right pad.
|
||||||
var right_pos = right_paddle.get_position()
|
var right_pos = right_paddle.get_position()
|
||||||
if right_pos.y > 0 and Input.is_action_pressed("right_move_up"):
|
if right_pos.y > 0 and Input.is_action_pressed("right_move_up"):
|
||||||
right_pos.y += -PAD_SPEED * delta
|
right_pos.y += -PAD_SPEED * delta
|
||||||
if right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down"):
|
if right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down"):
|
||||||
right_pos.y += PAD_SPEED * delta
|
right_pos.y += PAD_SPEED * delta
|
||||||
|
|
||||||
right_paddle.set_position(right_pos)
|
right_paddle.set_position(right_pos)
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ onready var camera2 = viewport2.get_node(@"Camera2")
|
|||||||
func _ready():
|
func _ready():
|
||||||
_on_size_changed()
|
_on_size_changed()
|
||||||
_update_splitscreen()
|
_update_splitscreen()
|
||||||
|
|
||||||
get_viewport().connect("size_changed", self, "_on_size_changed")
|
get_viewport().connect("size_changed", self, "_on_size_changed")
|
||||||
|
|
||||||
view.material.set_shader_param("viewport1", viewport1.get_texture())
|
view.material.set_shader_param("viewport1", viewport1.get_texture())
|
||||||
view.material.set_shader_param("viewport2", viewport2.get_texture())
|
view.material.set_shader_param("viewport2", viewport2.get_texture())
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ func _process(_delta):
|
|||||||
|
|
||||||
func _move_cameras():
|
func _move_cameras():
|
||||||
var position_difference = _compute_position_difference_in_world()
|
var position_difference = _compute_position_difference_in_world()
|
||||||
|
|
||||||
var distance = clamp(_compute_horizontal_length(position_difference), 0, max_separation)
|
var distance = clamp(_compute_horizontal_length(position_difference), 0, max_separation)
|
||||||
|
|
||||||
position_difference = position_difference.normalized() * distance
|
position_difference = position_difference.normalized() * distance
|
||||||
@@ -66,7 +66,7 @@ func _update_splitscreen():
|
|||||||
var screen_size = get_viewport().get_visible_rect().size
|
var screen_size = get_viewport().get_visible_rect().size
|
||||||
var player1_position = camera1.unproject_position(player1.translation) / screen_size
|
var player1_position = camera1.unproject_position(player1.translation) / screen_size
|
||||||
var player2_position = camera2.unproject_position(player2.translation) / screen_size
|
var player2_position = camera2.unproject_position(player2.translation) / screen_size
|
||||||
|
|
||||||
var thickness
|
var thickness
|
||||||
if adaptive_split_line_thickness:
|
if adaptive_split_line_thickness:
|
||||||
var position_difference = _compute_position_difference_in_world()
|
var position_difference = _compute_position_difference_in_world()
|
||||||
@@ -75,7 +75,7 @@ func _update_splitscreen():
|
|||||||
thickness = clamp(thickness, 0, split_line_thickness)
|
thickness = clamp(thickness, 0, split_line_thickness)
|
||||||
else:
|
else:
|
||||||
thickness = split_line_thickness
|
thickness = split_line_thickness
|
||||||
|
|
||||||
view.material.set_shader_param("split_active", _get_split_state())
|
view.material.set_shader_param("split_active", _get_split_state())
|
||||||
view.material.set_shader_param("player1_position", player1_position)
|
view.material.set_shader_param("player1_position", player1_position)
|
||||||
view.material.set_shader_param("player2_position", player2_position)
|
view.material.set_shader_param("player2_position", player2_position)
|
||||||
@@ -93,10 +93,10 @@ func _get_split_state():
|
|||||||
|
|
||||||
func _on_size_changed():
|
func _on_size_changed():
|
||||||
var screen_size = get_viewport().get_visible_rect().size
|
var screen_size = get_viewport().get_visible_rect().size
|
||||||
|
|
||||||
$Viewport1.size = screen_size
|
$Viewport1.size = screen_size
|
||||||
$Viewport2.size = screen_size
|
$Viewport2.size = screen_size
|
||||||
|
|
||||||
view.material.set_shader_param("viewport_size", screen_size)
|
view.material.set_shader_param("viewport_size", screen_size)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ func _physics_process(_delta):
|
|||||||
velocity.z += Input.get_action_strength("move_down_player" + str(player_id))
|
velocity.z += Input.get_action_strength("move_down_player" + str(player_id))
|
||||||
velocity.x = -Input.get_action_strength("move_left_player" + str(player_id))
|
velocity.x = -Input.get_action_strength("move_left_player" + str(player_id))
|
||||||
velocity.x += Input.get_action_strength("move_right_player" + str(player_id))
|
velocity.x += Input.get_action_strength("move_right_player" + str(player_id))
|
||||||
|
|
||||||
move_and_slide(velocity.normalized() * walk_speed)
|
move_and_slide(velocity.normalized() * walk_speed)
|
||||||
|
|||||||
@@ -24,22 +24,22 @@ void fragment() {
|
|||||||
|
|
||||||
float width = viewport_size.x;
|
float width = viewport_size.x;
|
||||||
float height = viewport_size.y;
|
float height = viewport_size.y;
|
||||||
|
|
||||||
if (split_active) {
|
if (split_active) {
|
||||||
vec2 dx = player2_position - player1_position;
|
vec2 dx = player2_position - player1_position;
|
||||||
float split_slope;
|
float split_slope;
|
||||||
|
|
||||||
if (dx.y != 0.0) {
|
if (dx.y != 0.0) {
|
||||||
split_slope = dx.x / dx.y;
|
split_slope = dx.x / dx.y;
|
||||||
} else {
|
} else {
|
||||||
split_slope = 100000.0; // High value (vertical split) if dx.y = 0
|
split_slope = 100000.0; // High value (vertical split) if dx.y = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 split_origin = vec2(0.5, 0.5);
|
vec2 split_origin = vec2(0.5, 0.5);
|
||||||
vec2 split_line_start = vec2(0.0, height * ((split_origin.x - 0.0) * split_slope + split_origin.y));
|
vec2 split_line_start = vec2(0.0, height * ((split_origin.x - 0.0) * split_slope + split_origin.y));
|
||||||
vec2 split_line_end = vec2(width, height * ((split_origin.x - 1.0) * split_slope + split_origin.y));
|
vec2 split_line_end = vec2(width, height * ((split_origin.x - 1.0) * split_slope + split_origin.y));
|
||||||
float distance_to_split_line = distanceToLine(split_line_start, split_line_end, vec2(UV.x * width, UV.y * height));
|
float distance_to_split_line = distanceToLine(split_line_start, split_line_end, vec2(UV.x * width, UV.y * height));
|
||||||
|
|
||||||
// Draw split border if close enough
|
// Draw split border if close enough
|
||||||
if (distance_to_split_line < split_line_thickness) {
|
if (distance_to_split_line < split_line_thickness) {
|
||||||
COLOR = split_line_color;
|
COLOR = split_line_color;
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ func _ready():
|
|||||||
for wall in walls:
|
for wall in walls:
|
||||||
var material = SpatialMaterial.new()
|
var material = SpatialMaterial.new()
|
||||||
material.albedo_color = Color(randf(), randf(), randf())
|
material.albedo_color = Color(randf(), randf(), randf())
|
||||||
|
|
||||||
wall.material_override = material
|
wall.material_override = material
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ onready var node_area = $Quad/Area
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
node_area.connect("mouse_entered", self, "_mouse_entered_area")
|
node_area.connect("mouse_entered", self, "_mouse_entered_area")
|
||||||
|
|
||||||
# If the material is NOT set to use billboard settings, then avoid running billboard specific code
|
# If the material is NOT set to use billboard settings, then avoid running billboard specific code
|
||||||
if node_quad.get_surface_material(0).params_billboard_mode == 0:
|
if node_quad.get_surface_material(0).params_billboard_mode == 0:
|
||||||
set_process(false)
|
set_process(false)
|
||||||
@@ -39,7 +39,7 @@ func _unhandled_input(event):
|
|||||||
if event is mouse_event:
|
if event is mouse_event:
|
||||||
is_mouse_event = true
|
is_mouse_event = true
|
||||||
break
|
break
|
||||||
|
|
||||||
# If the event is a mouse/touch event and/or the mouse is either held or inside the area, then
|
# If the event is a mouse/touch event and/or the mouse is either held or inside the area, then
|
||||||
# we need to do some additional processing in the handle_mouse function before passing the event to the viewport.
|
# we need to do some additional processing in the handle_mouse function before passing the event to the viewport.
|
||||||
# If the event is not a mouse/touch event, then we can just pass the event directly to the viewport.
|
# If the event is not a mouse/touch event, then we can just pass the event directly to the viewport.
|
||||||
@@ -53,14 +53,14 @@ func _unhandled_input(event):
|
|||||||
func handle_mouse(event):
|
func handle_mouse(event):
|
||||||
# Get mesh size to detect edges and make conversions. This code only support PlaneMesh and QuadMesh.
|
# Get mesh size to detect edges and make conversions. This code only support PlaneMesh and QuadMesh.
|
||||||
quad_mesh_size = node_quad.mesh.size
|
quad_mesh_size = node_quad.mesh.size
|
||||||
|
|
||||||
# Detect mouse being held to mantain event while outside of bounds. Avoid orphan clicks
|
# Detect mouse being held to mantain event while outside of bounds. Avoid orphan clicks
|
||||||
if event is InputEventMouseButton or event is InputEventScreenTouch:
|
if event is InputEventMouseButton or event is InputEventScreenTouch:
|
||||||
is_mouse_held = event.pressed
|
is_mouse_held = event.pressed
|
||||||
|
|
||||||
# Find mouse position in Area
|
# Find mouse position in Area
|
||||||
var mouse_pos3D = find_mouse(event.global_position)
|
var mouse_pos3D = find_mouse(event.global_position)
|
||||||
|
|
||||||
# Check if the mouse is outside of bounds, use last position to avoid errors
|
# Check if the mouse is outside of bounds, use last position to avoid errors
|
||||||
# NOTE: mouse_exited signal was unrealiable in this situation
|
# NOTE: mouse_exited signal was unrealiable in this situation
|
||||||
is_mouse_inside = mouse_pos3D != null
|
is_mouse_inside = mouse_pos3D != null
|
||||||
@@ -73,12 +73,12 @@ func handle_mouse(event):
|
|||||||
mouse_pos3D = last_mouse_pos3D
|
mouse_pos3D = last_mouse_pos3D
|
||||||
if mouse_pos3D == null:
|
if mouse_pos3D == null:
|
||||||
mouse_pos3D = Vector3.ZERO
|
mouse_pos3D = Vector3.ZERO
|
||||||
|
|
||||||
# TODO: adapt to bilboard mode or avoid completely
|
# TODO: adapt to bilboard mode or avoid completely
|
||||||
|
|
||||||
# convert the relative event position from 3D to 2D
|
# convert the relative event position from 3D to 2D
|
||||||
var mouse_pos2D = Vector2(mouse_pos3D.x, -mouse_pos3D.y)
|
var mouse_pos2D = Vector2(mouse_pos3D.x, -mouse_pos3D.y)
|
||||||
|
|
||||||
# Right now the event position's range is the following: (-quad_size/2) -> (quad_size/2)
|
# Right now the event position's range is the following: (-quad_size/2) -> (quad_size/2)
|
||||||
# We need to convert it into the following range: 0 -> quad_size
|
# We need to convert it into the following range: 0 -> quad_size
|
||||||
mouse_pos2D.x += quad_mesh_size.x / 2
|
mouse_pos2D.x += quad_mesh_size.x / 2
|
||||||
@@ -86,16 +86,16 @@ func handle_mouse(event):
|
|||||||
# Then we need to convert it into the following range: 0 -> 1
|
# Then we need to convert it into the following range: 0 -> 1
|
||||||
mouse_pos2D.x = mouse_pos2D.x / quad_mesh_size.x
|
mouse_pos2D.x = mouse_pos2D.x / quad_mesh_size.x
|
||||||
mouse_pos2D.y = mouse_pos2D.y / quad_mesh_size.y
|
mouse_pos2D.y = mouse_pos2D.y / quad_mesh_size.y
|
||||||
|
|
||||||
# Finally, we convert the position to the following range: 0 -> viewport.size
|
# Finally, we convert the position to the following range: 0 -> viewport.size
|
||||||
mouse_pos2D.x = mouse_pos2D.x * node_viewport.size.x
|
mouse_pos2D.x = mouse_pos2D.x * node_viewport.size.x
|
||||||
mouse_pos2D.y = mouse_pos2D.y * node_viewport.size.y
|
mouse_pos2D.y = mouse_pos2D.y * node_viewport.size.y
|
||||||
# We need to do these conversions so the event's position is in the viewport's coordinate system.
|
# We need to do these conversions so the event's position is in the viewport's coordinate system.
|
||||||
|
|
||||||
# Set the event's position and global position.
|
# Set the event's position and global position.
|
||||||
event.position = mouse_pos2D
|
event.position = mouse_pos2D
|
||||||
event.global_position = mouse_pos2D
|
event.global_position = mouse_pos2D
|
||||||
|
|
||||||
# If the event is a mouse motion event...
|
# If the event is a mouse motion event...
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
# If there is not a stored previous position, then we'll assume there is no relative motion.
|
# If there is not a stored previous position, then we'll assume there is no relative motion.
|
||||||
@@ -107,23 +107,23 @@ func handle_mouse(event):
|
|||||||
event.relative = mouse_pos2D - last_mouse_pos2D
|
event.relative = mouse_pos2D - last_mouse_pos2D
|
||||||
# Update last_mouse_pos2D with the position we just calculated.
|
# Update last_mouse_pos2D with the position we just calculated.
|
||||||
last_mouse_pos2D = mouse_pos2D
|
last_mouse_pos2D = mouse_pos2D
|
||||||
|
|
||||||
# Finally, send the processed input event to the viewport.
|
# Finally, send the processed input event to the viewport.
|
||||||
node_viewport.input(event)
|
node_viewport.input(event)
|
||||||
|
|
||||||
|
|
||||||
func find_mouse(global_position):
|
func find_mouse(global_position):
|
||||||
var camera = get_viewport().get_camera()
|
var camera = get_viewport().get_camera()
|
||||||
|
|
||||||
# From camera center to the mouse position in the Area
|
# From camera center to the mouse position in the Area
|
||||||
var from = camera.project_ray_origin(global_position)
|
var from = camera.project_ray_origin(global_position)
|
||||||
var dist = find_further_distance_to(camera.transform.origin)
|
var dist = find_further_distance_to(camera.transform.origin)
|
||||||
var to = from + camera.project_ray_normal(global_position) * dist
|
var to = from + camera.project_ray_normal(global_position) * dist
|
||||||
|
|
||||||
|
|
||||||
# Manually raycasts the are to find the mouse position
|
# Manually raycasts the are to find the mouse position
|
||||||
var result = get_world().direct_space_state.intersect_ray(from, to, [], node_area.collision_layer,false,true) #for 3.1 changes
|
var result = get_world().direct_space_state.intersect_ray(from, to, [], node_area.collision_layer,false,true) #for 3.1 changes
|
||||||
|
|
||||||
if result.size() > 0:
|
if result.size() > 0:
|
||||||
return result.position
|
return result.position
|
||||||
else:
|
else:
|
||||||
@@ -137,7 +137,7 @@ func find_further_distance_to(origin):
|
|||||||
edges.append(node_area.to_global(Vector3(quad_mesh_size.x / 2, -quad_mesh_size.y / 2, 0)))
|
edges.append(node_area.to_global(Vector3(quad_mesh_size.x / 2, -quad_mesh_size.y / 2, 0)))
|
||||||
edges.append(node_area.to_global(Vector3(-quad_mesh_size.x / 2, quad_mesh_size.y / 2, 0)))
|
edges.append(node_area.to_global(Vector3(-quad_mesh_size.x / 2, quad_mesh_size.y / 2, 0)))
|
||||||
edges.append(node_area.to_global(Vector3(-quad_mesh_size.x / 2, -quad_mesh_size.y / 2, 0)))
|
edges.append(node_area.to_global(Vector3(-quad_mesh_size.x / 2, -quad_mesh_size.y / 2, 0)))
|
||||||
|
|
||||||
# Get the furthest distance between the camera and collision to avoid raycasting too far or too short
|
# Get the furthest distance between the camera and collision to avoid raycasting too far or too short
|
||||||
var far_dist = 0
|
var far_dist = 0
|
||||||
var temp_dist
|
var temp_dist
|
||||||
@@ -145,13 +145,13 @@ func find_further_distance_to(origin):
|
|||||||
temp_dist = origin.distance_to(edge)
|
temp_dist = origin.distance_to(edge)
|
||||||
if temp_dist > far_dist:
|
if temp_dist > far_dist:
|
||||||
far_dist = temp_dist
|
far_dist = temp_dist
|
||||||
|
|
||||||
return far_dist
|
return far_dist
|
||||||
|
|
||||||
|
|
||||||
func rotate_area_to_billboard():
|
func rotate_area_to_billboard():
|
||||||
var billboard_mode = node_quad.get_surface_material(0).params_billboard_mode
|
var billboard_mode = node_quad.get_surface_material(0).params_billboard_mode
|
||||||
|
|
||||||
# Try to match the area with the material's billboard setting, if enabled
|
# Try to match the area with the material's billboard setting, if enabled
|
||||||
if billboard_mode > 0:
|
if billboard_mode > 0:
|
||||||
# Get the camera
|
# Get the camera
|
||||||
@@ -159,12 +159,12 @@ func rotate_area_to_billboard():
|
|||||||
# Look in the same direction as the camera
|
# Look in the same direction as the camera
|
||||||
var look = camera.to_global(Vector3(0, 0, -100)) - camera.global_transform.origin
|
var look = camera.to_global(Vector3(0, 0, -100)) - camera.global_transform.origin
|
||||||
look = node_area.translation + look
|
look = node_area.translation + look
|
||||||
|
|
||||||
# Y-Billboard: Lock Y rotation, but gives bad results if the camera is tilted.
|
# Y-Billboard: Lock Y rotation, but gives bad results if the camera is tilted.
|
||||||
if billboard_mode == 2:
|
if billboard_mode == 2:
|
||||||
look = Vector3(look.x, 0, look.z)
|
look = Vector3(look.x, 0, look.z)
|
||||||
|
|
||||||
node_area.look_at(look, Vector3.UP)
|
node_area.look_at(look, Vector3.UP)
|
||||||
|
|
||||||
# Rotate in the Z axis to compensate camera tilt
|
# Rotate in the Z axis to compensate camera tilt
|
||||||
node_area.rotate_object_local(Vector3.BACK, camera.rotation.z)
|
node_area.rotate_object_local(Vector3.BACK, camera.rotation.z)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _unhandled_input(event):
|
|||||||
else: # Up.
|
else: # Up.
|
||||||
state.erase(event.index)
|
state.erase(event.index)
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|
||||||
elif event is InputEventScreenDrag: # Movement.
|
elif event is InputEventScreenDrag: # Movement.
|
||||||
state[event.index] = event.position
|
state[event.index] = event.position
|
||||||
get_tree().set_input_as_handled()
|
get_tree().set_input_as_handled()
|
||||||
|
|||||||
Reference in New Issue
Block a user