mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 06:50:07 +01:00
[3.0] Simplify list of branches in the README (#1255)
This commit is contained in:
@@ -1,6 +1,16 @@
|
|||||||
# Top-most EditorConfig file.
|
# Top-most EditorConfig file.
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file.
|
||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.cs]
|
||||||
|
csharp_space_after_cast = false
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.csproj]
|
||||||
|
insert_final_newline = false
|
||||||
|
indent_size = 2
|
||||||
|
|||||||
19
.github/workflows/static_checks.yml
vendored
Normal file
19
.github/workflows/static_checks.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
name: Static Checks
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
format:
|
||||||
|
name: File formatting (file_format.sh)
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -qq dos2unix recode
|
||||||
|
|
||||||
|
- name: File formatting checks (file_format.sh)
|
||||||
|
run: |
|
||||||
|
bash ./file_format.sh
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -18,4 +18,5 @@ mono_crash.*.json
|
|||||||
|
|
||||||
# System/tool-specific ignores
|
# System/tool-specific ignores
|
||||||
.directory
|
.directory
|
||||||
|
.DS_Store
|
||||||
*~
|
*~
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ func _on_StartButton_pressed():
|
|||||||
emit_signal("start_game")
|
emit_signal("start_game")
|
||||||
|
|
||||||
func _on_MessageTimer_timeout():
|
func _on_MessageTimer_timeout():
|
||||||
$MessageLabel.hide()
|
$MessageLabel.hide()
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ size_flags_vertical = 4
|
|||||||
custom_fonts/bold_font = ExtResource( 1 )
|
custom_fonts/bold_font = ExtResource( 1 )
|
||||||
custom_fonts/normal_font = ExtResource( 2 )
|
custom_fonts/normal_font = ExtResource( 2 )
|
||||||
bbcode_enabled = true
|
bbcode_enabled = true
|
||||||
bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
bbcode_text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
||||||
|
|
||||||
States are common in games. You can use the pattern to:
|
States are common in games. You can use the pattern to:
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ visible_characters = -1
|
|||||||
percent_visible = 1.0
|
percent_visible = 1.0
|
||||||
meta_underlined = true
|
meta_underlined = true
|
||||||
tab_size = 4
|
tab_size = 4
|
||||||
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
text = "This example shows how to apply the State programming pattern in GDscript, including Hierarchical States, and a pushdown automaton.
|
||||||
|
|
||||||
States are common in games. You can use the pattern to:
|
States are common in games. You can use the pattern to:
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
The Player is a KinematicBody2D, in other words a physics-driven object.
|
The Player is a KinematicBody2D, in other words a physics-driven object.
|
||||||
It can move, collide with the world...
|
It can move, collide with the world...
|
||||||
It HAS a state machine, but the body and the state machine are separate.
|
It HAS a state machine, but the body and the state machine are separate.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
The stagger state end with the stagger animation from the AnimationPlayer
|
The stagger state end with the stagger animation from the AnimationPlayer
|
||||||
The animation only affects the Body Sprite"s modulate property so
|
The animation only affects the Body Sprite"s modulate property so
|
||||||
it could stack with other animations if we had two AnimationPlayer nodes
|
it could stack with other animations if we had two AnimationPlayer nodes
|
||||||
"""
|
"""
|
||||||
extends "res://state_machine/state.gd"
|
extends "res://state_machine/state.gd"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ signal state_changed(current_state)
|
|||||||
"""
|
"""
|
||||||
You must set a starting node from the inspector or on
|
You must set a starting node from the inspector or on
|
||||||
the node that inherits from this state machine interface
|
the node that inherits from this state machine interface
|
||||||
If you don't the game will crash (on purpose, so you won't
|
If you don't the game will crash (on purpose, so you won't
|
||||||
forget to initialize the state machine)
|
forget to initialize the state machine)
|
||||||
"""
|
"""
|
||||||
export(NodePath) var START_STATE
|
export(NodePath) var START_STATE
|
||||||
@@ -58,14 +58,14 @@ func _change_state(state_name):
|
|||||||
if not _active:
|
if not _active:
|
||||||
return
|
return
|
||||||
current_state.exit()
|
current_state.exit()
|
||||||
|
|
||||||
if state_name == "previous":
|
if state_name == "previous":
|
||||||
states_stack.pop_front()
|
states_stack.pop_front()
|
||||||
else:
|
else:
|
||||||
states_stack[0] = states_map[state_name]
|
states_stack[0] = states_map[state_name]
|
||||||
|
|
||||||
current_state = states_stack[0]
|
current_state = states_stack[0]
|
||||||
emit_signal("state_changed", current_state)
|
emit_signal("state_changed", current_state)
|
||||||
|
|
||||||
if state_name != "previous":
|
if state_name != "previous":
|
||||||
current_state.enter()
|
current_state.enter()
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func get_cell_pawn(coordinates):
|
|||||||
func request_move(pawn, direction):
|
func request_move(pawn, direction):
|
||||||
var cell_start = world_to_map(pawn.position)
|
var cell_start = world_to_map(pawn.position)
|
||||||
var cell_target = cell_start + direction
|
var cell_target = cell_start + direction
|
||||||
|
|
||||||
var cell_target_type = get_cellv(cell_target)
|
var cell_target_type = get_cellv(cell_target)
|
||||||
match cell_target_type:
|
match cell_target_type:
|
||||||
EMPTY:
|
EMPTY:
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func move_to(target_position):
|
|||||||
|
|
||||||
# Stop the function execution until the animation finished
|
# Stop the function execution until the animation finished
|
||||||
yield($AnimationPlayer, "animation_finished")
|
yield($AnimationPlayer, "animation_finished")
|
||||||
|
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const MOTION_SPEED = 160 # Pixels/second
|
|||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
var motion = Vector2()
|
var motion = Vector2()
|
||||||
|
|
||||||
if Input.is_action_pressed("move_up"):
|
if Input.is_action_pressed("move_up"):
|
||||||
motion += Vector2(0, -1)
|
motion += Vector2(0, -1)
|
||||||
if Input.is_action_pressed("move_bottom"):
|
if Input.is_action_pressed("move_bottom"):
|
||||||
@@ -18,7 +18,7 @@ func _physics_process(delta):
|
|||||||
motion += Vector2(-1, 0)
|
motion += Vector2(-1, 0)
|
||||||
if Input.is_action_pressed("move_right"):
|
if Input.is_action_pressed("move_right"):
|
||||||
motion += Vector2(1, 0)
|
motion += Vector2(1, 0)
|
||||||
|
|
||||||
motion = motion.normalized() * MOTION_SPEED
|
motion = motion.normalized() * MOTION_SPEED
|
||||||
|
|
||||||
move_and_slide(motion)
|
move_and_slide(motion)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const MOTION_SPEED = 160 # Pixels/second
|
|||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
var motion = Vector2()
|
var motion = Vector2()
|
||||||
|
|
||||||
if Input.is_action_pressed("move_up"):
|
if Input.is_action_pressed("move_up"):
|
||||||
motion += Vector2(0, -1)
|
motion += Vector2(0, -1)
|
||||||
if Input.is_action_pressed("move_bottom"):
|
if Input.is_action_pressed("move_bottom"):
|
||||||
@@ -18,7 +18,7 @@ func _physics_process(delta):
|
|||||||
motion += Vector2(-1, 0)
|
motion += Vector2(-1, 0)
|
||||||
if Input.is_action_pressed("move_right"):
|
if Input.is_action_pressed("move_right"):
|
||||||
motion += Vector2(1, 0)
|
motion += Vector2(1, 0)
|
||||||
|
|
||||||
motion = motion.normalized() * MOTION_SPEED
|
motion = motion.normalized() * MOTION_SPEED
|
||||||
|
|
||||||
move_and_slide(motion)
|
move_and_slide(motion)
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ var prev_jump_pressed = false
|
|||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
# Create forces
|
# Create forces
|
||||||
var force = Vector2(0, GRAVITY)
|
var force = Vector2(0, GRAVITY)
|
||||||
|
|
||||||
var walk_left = Input.is_action_pressed("move_left")
|
var walk_left = Input.is_action_pressed("move_left")
|
||||||
var walk_right = Input.is_action_pressed("move_right")
|
var walk_right = Input.is_action_pressed("move_right")
|
||||||
var jump = Input.is_action_pressed("jump")
|
var jump = Input.is_action_pressed("jump")
|
||||||
|
|
||||||
var stop = true
|
var stop = true
|
||||||
|
|
||||||
if walk_left:
|
if walk_left:
|
||||||
if velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED:
|
if velocity.x <= WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED:
|
||||||
force.x -= WALK_FORCE
|
force.x -= WALK_FORCE
|
||||||
@@ -42,34 +42,34 @@ func _physics_process(delta):
|
|||||||
if velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED:
|
if velocity.x >= -WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED:
|
||||||
force.x += WALK_FORCE
|
force.x += WALK_FORCE
|
||||||
stop = false
|
stop = false
|
||||||
|
|
||||||
if stop:
|
if stop:
|
||||||
var vsign = sign(velocity.x)
|
var vsign = sign(velocity.x)
|
||||||
var vlen = abs(velocity.x)
|
var vlen = abs(velocity.x)
|
||||||
|
|
||||||
vlen -= STOP_FORCE * delta
|
vlen -= STOP_FORCE * delta
|
||||||
if vlen < 0:
|
if vlen < 0:
|
||||||
vlen = 0
|
vlen = 0
|
||||||
|
|
||||||
velocity.x = vlen * vsign
|
velocity.x = vlen * vsign
|
||||||
|
|
||||||
# Integrate forces to velocity
|
# Integrate forces to velocity
|
||||||
velocity += force * delta
|
velocity += force * delta
|
||||||
# Integrate velocity into motion and move
|
# Integrate velocity into motion and move
|
||||||
velocity = move_and_slide(velocity, Vector2(0, -1))
|
velocity = move_and_slide(velocity, Vector2(0, -1))
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
on_air_time = 0
|
on_air_time = 0
|
||||||
|
|
||||||
if jumping and velocity.y > 0:
|
if jumping and velocity.y > 0:
|
||||||
# If falling, no longer jumping
|
# If falling, no longer jumping
|
||||||
jumping = false
|
jumping = false
|
||||||
|
|
||||||
if on_air_time < JUMP_MAX_AIRBORNE_TIME and jump and not prev_jump_pressed and not jumping:
|
if on_air_time < JUMP_MAX_AIRBORNE_TIME and jump and not prev_jump_pressed and not jumping:
|
||||||
# Jump must also be allowed to happen if the character left the floor a little bit ago.
|
# Jump must also be allowed to happen if the character left the floor a little bit ago.
|
||||||
# Makes controls more snappy.
|
# Makes controls more snappy.
|
||||||
velocity.y = -JUMP_SPEED
|
velocity.y = -JUMP_SPEED
|
||||||
jumping = true
|
jumping = true
|
||||||
|
|
||||||
on_air_time += delta
|
on_air_time += delta
|
||||||
prev_jump_pressed = jump
|
prev_jump_pressed = jump
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const MOTION_SPEED = 160 # Pixels/second
|
|||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
var motion = Vector2()
|
var motion = Vector2()
|
||||||
|
|
||||||
if Input.is_action_pressed("move_up"):
|
if Input.is_action_pressed("move_up"):
|
||||||
motion += Vector2(0, -1)
|
motion += Vector2(0, -1)
|
||||||
if Input.is_action_pressed("move_bottom"):
|
if Input.is_action_pressed("move_bottom"):
|
||||||
@@ -18,7 +18,7 @@ func _physics_process(delta):
|
|||||||
motion += Vector2(-1, 0)
|
motion += Vector2(-1, 0)
|
||||||
if Input.is_action_pressed("move_right"):
|
if Input.is_action_pressed("move_right"):
|
||||||
motion += Vector2(1, 0)
|
motion += Vector2(1, 0)
|
||||||
|
|
||||||
motion = motion.normalized() * MOTION_SPEED
|
motion = motion.normalized() * MOTION_SPEED
|
||||||
|
|
||||||
move_and_slide(motion)
|
move_and_slide(motion)
|
||||||
|
|||||||
@@ -183,4 +183,4 @@ func _set_path_end_position(value):
|
|||||||
set_cell(value.x, value.y, 2)
|
set_cell(value.x, value.y, 2)
|
||||||
path_end_position = value
|
path_end_position = value
|
||||||
if path_start_position != value:
|
if path_start_position != value:
|
||||||
_recalculate_path()
|
_recalculate_path()
|
||||||
|
|||||||
@@ -26,7 +26,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
|
||||||
$sound_explode.play()
|
$sound_explode.play()
|
||||||
@@ -40,13 +40,13 @@ 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_class and not cc.disabled:
|
if cc is bullet_class and not cc.disabled:
|
||||||
mode = MODE_RIGID
|
mode = MODE_RIGID
|
||||||
@@ -57,12 +57,12 @@ func _integrate_forces(s):
|
|||||||
cc.disable()
|
cc.disable()
|
||||||
$sound_hit.play()
|
$sound_hit.play()
|
||||||
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.scale.x = -direction
|
$sprite.scale.x = -direction
|
||||||
@@ -72,11 +72,11 @@ 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.scale.x = -direction
|
$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
|
||||||
$anim.play(anim)
|
$anim.play(anim)
|
||||||
|
|
||||||
s.set_linear_velocity(lv)
|
s.set_linear_velocity(lv)
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ func _physics_process(delta):
|
|||||||
accum = fmod(accum, PI * 2.0)
|
accum = fmod(accum, PI * 2.0)
|
||||||
var d = sin(accum)
|
var d = sin(accum)
|
||||||
var xf = Transform2D()
|
var xf = Transform2D()
|
||||||
xf[2]= motion * d
|
xf[2]= motion * d
|
||||||
$platform.transform = xf
|
$platform.transform = xf
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ extends RigidBody2D
|
|||||||
# -Interaction with other physics-based objects is free
|
# -Interaction with other physics-based objects is free
|
||||||
# -Only have to deal with the object linear velocity, not position
|
# -Only have to deal with the object linear velocity, not position
|
||||||
# -All collision/area framework available
|
# -All collision/area framework available
|
||||||
#
|
#
|
||||||
# But also has the following disadvantages:
|
# But also has the following disadvantages:
|
||||||
#
|
#
|
||||||
# -Objects may bounce a little bit sometimes
|
# -Objects may bounce a little bit sometimes
|
||||||
# -Going up ramps sends the chracter flying up, small hack is needed.
|
# -Going up ramps sends the chracter flying up, small hack is needed.
|
||||||
# -A ray collider is needed to avoid sliding down on ramps and
|
# -A ray collider is needed to avoid sliding down on ramps and
|
||||||
# undesiderd bumps, small steps and rare numerical precision errors.
|
# undesiderd bumps, small steps and rare numerical precision errors.
|
||||||
# (another alternative may be to turn on friction when the character is not moving).
|
# (another alternative may be to turn on friction when the character is not moving).
|
||||||
# -Friction cant be used, so floor velocity must be considered
|
# -Friction cant be used, so floor velocity must be considered
|
||||||
@@ -55,38 +55,38 @@ onready var enemy = load("res://enemy.tscn")
|
|||||||
func _integrate_forces(s):
|
func _integrate_forces(s):
|
||||||
var lv = s.get_linear_velocity()
|
var lv = s.get_linear_velocity()
|
||||||
var step = s.get_step()
|
var step = s.get_step()
|
||||||
|
|
||||||
var new_anim = anim
|
var new_anim = anim
|
||||||
var new_siding_left = siding_left
|
var new_siding_left = siding_left
|
||||||
|
|
||||||
# Get the controls
|
# Get the controls
|
||||||
var move_left = Input.is_action_pressed("move_left")
|
var move_left = Input.is_action_pressed("move_left")
|
||||||
var move_right = Input.is_action_pressed("move_right")
|
var move_right = Input.is_action_pressed("move_right")
|
||||||
var jump = Input.is_action_pressed("jump")
|
var jump = Input.is_action_pressed("jump")
|
||||||
var shoot = Input.is_action_pressed("shoot")
|
var shoot = Input.is_action_pressed("shoot")
|
||||||
var spawn = Input.is_action_pressed("spawn")
|
var spawn = Input.is_action_pressed("spawn")
|
||||||
|
|
||||||
if spawn:
|
if spawn:
|
||||||
var e = enemy.instance()
|
var e = enemy.instance()
|
||||||
var p = position
|
var p = position
|
||||||
p.y = p.y - 100
|
p.y = p.y - 100
|
||||||
e.position = p
|
e.position = p
|
||||||
get_parent().add_child(e)
|
get_parent().add_child(e)
|
||||||
|
|
||||||
# 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:
|
||||||
@@ -98,24 +98,24 @@ func _integrate_forces(s):
|
|||||||
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(800.0 * ss, -80)
|
bi.linear_velocity = Vector2(800.0 * ss, -80)
|
||||||
|
|
||||||
$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
|
||||||
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
|
||||||
@@ -125,10 +125,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:
|
||||||
@@ -143,14 +143,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
|
||||||
@@ -182,7 +182,7 @@ 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
|
||||||
|
|
||||||
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"
|
||||||
@@ -193,28 +193,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
|
||||||
$anim.play(anim)
|
$anim.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)
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ func reset():
|
|||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
position += direction * speed * delta
|
position += direction * speed * delta
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ const MOVE_SPEED = 100
|
|||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
var which = get_name()
|
var which = get_name()
|
||||||
|
|
||||||
# move up and down based on input
|
# move up and down based on input
|
||||||
if Input.is_action_pressed(which+"_move_up") and position.y > 0:
|
if Input.is_action_pressed(which+"_move_up") and position.y > 0:
|
||||||
position.y -= MOVE_SPEED * delta
|
position.y -= MOVE_SPEED * delta
|
||||||
if Input.is_action_pressed(which+"_move_down") and position.y < get_viewport_rect().size.y:
|
if Input.is_action_pressed(which+"_move_down") and position.y < get_viewport_rect().size.y:
|
||||||
position.y += MOVE_SPEED * delta
|
position.y += MOVE_SPEED * delta
|
||||||
|
|
||||||
|
|
||||||
func _on_area_entered( area ):
|
func _on_area_entered( area ):
|
||||||
if area.get_name() == "ball":
|
if area.get_name() == "ball":
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func _ready():
|
|||||||
continue
|
continue
|
||||||
if not n.has_node("DialoguePlayer"):
|
if not n.has_node("DialoguePlayer"):
|
||||||
continue
|
continue
|
||||||
n.get_node("DialoguePlayer").connect("dialogue_finished", self,
|
n.get_node("DialoguePlayer").connect("dialogue_finished", self,
|
||||||
"_on_opponent_dialogue_finished", [n])
|
"_on_opponent_dialogue_finished", [n])
|
||||||
remove_child(combat_screen)
|
remove_child(combat_screen)
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ func _on_opponent_dialogue_finished(opponent):
|
|||||||
var player = $Exploration/Grid/Player
|
var player = $Exploration/Grid/Player
|
||||||
var combatents = [player.combat_actor, opponent.combat_actor]
|
var combatents = [player.combat_actor, opponent.combat_actor]
|
||||||
start_combat(combatents)
|
start_combat(combatents)
|
||||||
|
|
||||||
func start_combat(combat_actors):
|
func start_combat(combat_actors):
|
||||||
remove_child($Exploration)
|
remove_child($Exploration)
|
||||||
$AnimationPlayer.play("fade")
|
$AnimationPlayer.play("fade")
|
||||||
@@ -34,7 +34,7 @@ func start_combat(combat_actors):
|
|||||||
combat_screen.show()
|
combat_screen.show()
|
||||||
combat_screen.initialize(combat_actors)
|
combat_screen.initialize(combat_actors)
|
||||||
$AnimationPlayer.play_backwards("fade")
|
$AnimationPlayer.play_backwards("fade")
|
||||||
|
|
||||||
func _on_combat_finished(winner, loser):
|
func _on_combat_finished(winner, loser):
|
||||||
remove_child(combat_screen)
|
remove_child(combat_screen)
|
||||||
$AnimationPlayer.play_backwards("fade")
|
$AnimationPlayer.play_backwards("fade")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ func start_dialogue():
|
|||||||
index_dialogue()
|
index_dialogue()
|
||||||
dialogue_text = dialogue_keys[current].text
|
dialogue_text = dialogue_keys[current].text
|
||||||
dialogue_name = dialogue_keys[current].name
|
dialogue_name = dialogue_keys[current].name
|
||||||
|
|
||||||
func next_dialogue():
|
func next_dialogue():
|
||||||
current += 1
|
current += 1
|
||||||
if current == dialogue_keys.size():
|
if current == dialogue_keys.size():
|
||||||
@@ -23,13 +23,13 @@ func next_dialogue():
|
|||||||
return
|
return
|
||||||
dialogue_text = dialogue_keys[current].text
|
dialogue_text = dialogue_keys[current].text
|
||||||
dialogue_name = dialogue_keys[current].name
|
dialogue_name = dialogue_keys[current].name
|
||||||
|
|
||||||
func index_dialogue():
|
func index_dialogue():
|
||||||
var dialogue = load_dialogue(dialogue_file)
|
var dialogue = load_dialogue(dialogue_file)
|
||||||
dialogue_keys.clear()
|
dialogue_keys.clear()
|
||||||
for key in dialogue:
|
for key in dialogue:
|
||||||
dialogue_keys.append(dialogue[key])
|
dialogue_keys.append(dialogue[key])
|
||||||
|
|
||||||
func load_dialogue(file_path):
|
func load_dialogue(file_path):
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
if file.file_exists(file_path):
|
if file.file_exists(file_path):
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func show_dialogue(player, dialogue):
|
|||||||
$Name.text = dialogue_node.dialogue_name
|
$Name.text = dialogue_node.dialogue_name
|
||||||
$Text.text = dialogue_node.dialogue_text
|
$Text.text = dialogue_node.dialogue_text
|
||||||
|
|
||||||
|
|
||||||
func _on_Button_button_up():
|
func _on_Button_button_up():
|
||||||
dialogue_node.next_dialogue()
|
dialogue_node.next_dialogue()
|
||||||
$Name.text = dialogue_node.dialogue_name
|
$Name.text = dialogue_node.dialogue_name
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func get_cell_pawn(cell, type = 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,8 +29,8 @@ func request_move(pawn, direction):
|
|||||||
OBJECT, ACTOR:
|
OBJECT, 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"))
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ extends 'actor.gd'
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
set_process(false)
|
set_process(false)
|
||||||
|
|
||||||
func get_input_direction():
|
func get_input_direction():
|
||||||
return Vector2(0, 0)
|
return Vector2(0, 0)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -36,9 +36,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)
|
||||||
|
|
||||||
func bump():
|
func bump():
|
||||||
|
|||||||
@@ -35,9 +35,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)
|
||||||
|
|
||||||
func bump():
|
func bump():
|
||||||
|
|||||||
@@ -33,4 +33,4 @@ func clear_combat():
|
|||||||
|
|
||||||
func finish_combat(winner, loser):
|
func finish_combat(winner, loser):
|
||||||
emit_signal("combat_finished", winner, loser)
|
emit_signal("combat_finished", winner, loser)
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,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
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export (PackedScene) var info_scene
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
combatants_node = get_node(combatants_node)
|
combatants_node = get_node(combatants_node)
|
||||||
|
|
||||||
func initialize():
|
func initialize():
|
||||||
for combatant in combatants_node.get_children():
|
for combatant in combatants_node.get_children():
|
||||||
var health = combatant.get_node("Health")
|
var health = combatant.get_node("Health")
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ 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:
|
||||||
$Health.armor = $Health.base_armor
|
$Health.armor = $Health.base_armor
|
||||||
|
|
||||||
func attack(target):
|
func attack(target):
|
||||||
target.take_damage(damage)
|
target.take_damage(damage)
|
||||||
emit_signal("turn_finished")
|
emit_signal("turn_finished")
|
||||||
@@ -27,10 +27,10 @@ func defend():
|
|||||||
func consume(item):
|
func consume(item):
|
||||||
item.use(self)
|
item.use(self)
|
||||||
emit_signal("turn_finished")
|
emit_signal("turn_finished")
|
||||||
|
|
||||||
func flee():
|
func flee():
|
||||||
emit_signal("turn_finished")
|
emit_signal("turn_finished")
|
||||||
|
|
||||||
func take_damage(damage):
|
func take_damage(damage):
|
||||||
$Health.take_damage(damage)
|
$Health.take_damage(damage)
|
||||||
$Sprite/AnimationPlayer.play("take_damage")
|
$Sprite/AnimationPlayer.play("take_damage")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func get_next_in_queue():
|
|||||||
queue.append(current_combatant)
|
queue.append(current_combatant)
|
||||||
self.active_combatant = queue[0]
|
self.active_combatant = queue[0]
|
||||||
return active_combatant
|
return active_combatant
|
||||||
|
|
||||||
func remove(combatant):
|
func remove(combatant):
|
||||||
var new_queue = []
|
var new_queue = []
|
||||||
for n in queue:
|
for n in queue:
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ code = "shader_type canvas_item;
|
|||||||
uniform float amount : hint_range(0,5);
|
uniform float amount : hint_range(0,5);
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
|
|
||||||
COLOR.rgb = textureLod(SCREEN_TEXTURE,SCREEN_UV,amount).rgb;
|
COLOR.rgb = textureLod(SCREEN_TEXTURE,SCREEN_UV,amount).rgb;
|
||||||
}"
|
}"
|
||||||
|
|
||||||
@@ -57,7 +56,7 @@ 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;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
@@ -102,13 +101,12 @@ uniform vec4 base : hint_color;
|
|||||||
|
|
||||||
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;
|
||||||
COLOR.rgb= base.rgb*v;
|
COLOR.rgb= base.rgb*v;
|
||||||
|
|
||||||
}"
|
}"
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=10]
|
[sub_resource type="ShaderMaterial" id=10]
|
||||||
@@ -123,7 +121,6 @@ _sections_unfolded = [ "shader", "shader_param" ]
|
|||||||
code = "shader_type canvas_item;
|
code = "shader_type canvas_item;
|
||||||
|
|
||||||
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=vec3(1.0)-c;
|
c=vec3(1.0)-c;
|
||||||
COLOR.rgb=c;
|
COLOR.rgb=c;
|
||||||
@@ -141,7 +138,6 @@ _sections_unfolded = [ "shader" ]
|
|||||||
code = "shader_type canvas_item;
|
code = "shader_type canvas_item;
|
||||||
|
|
||||||
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=mod(c+vec3(0.5),vec3(1.0));
|
c=mod(c+vec3(0.5),vec3(1.0));
|
||||||
COLOR.rgb=c;
|
COLOR.rgb=c;
|
||||||
@@ -179,13 +175,12 @@ uniform float contrast=1.5;
|
|||||||
uniform float saturation=1.8;
|
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;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
@@ -207,13 +202,12 @@ uniform float frequency=60;
|
|||||||
uniform float depth = 0.005;
|
uniform float depth = 0.005;
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
|
|
||||||
vec2 uv = SCREEN_UV;
|
vec2 uv = SCREEN_UV;
|
||||||
uv.x += sin(uv.y*frequency+TIME)*depth;
|
uv.x += sin(uv.y*frequency+TIME)*depth;
|
||||||
uv.x = clamp(uv.x,0,1);
|
uv.x = clamp(uv.x,0,1);
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,uv,0.0).rgb;
|
vec3 c = textureLod(SCREEN_TEXTURE,uv,0.0).rgb;
|
||||||
|
|
||||||
|
|
||||||
COLOR.rgb=c;
|
COLOR.rgb=c;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
@@ -239,25 +233,24 @@ uniform float stretch = 0.5;
|
|||||||
uniform float flashing=0.01;
|
uniform float flashing=0.01;
|
||||||
|
|
||||||
float make_grain(float time,vec2 uv) {
|
float make_grain(float time,vec2 uv) {
|
||||||
|
|
||||||
vec2 ofs = vec2(sin(41.0*time*sin(time*123.0)),sin(27.0*time*sin(time*312.0)));
|
vec2 ofs = vec2(sin(41.0*time*sin(time*123.0)),sin(27.0*time*sin(time*312.0)));
|
||||||
return texture(grain,(uv+mod(ofs,vec2(1,1)))*stretch).r;
|
return texture(grain,(uv+mod(ofs,vec2(1,1)))*stretch).r;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@@ -1,570 +0,0 @@
|
|||||||
[gd_scene load_steps=31 format=2]
|
|
||||||
|
|
||||||
[ext_resource path="res://screen_shaders.gd" type="Script" id=1]
|
|
||||||
[ext_resource path="res://art/burano.jpg" type="Texture" id=2]
|
|
||||||
[ext_resource path="res://art/platformer.jpg" type="Texture" id=3]
|
|
||||||
[ext_resource path="res://art/mountains.jpg" type="Texture" id=4]
|
|
||||||
[ext_resource path="res://art/forest.jpg" type="Texture" id=5]
|
|
||||||
[ext_resource path="res://art/vignette.png" type="Texture" id=6]
|
|
||||||
[ext_resource path="res://art/white.png" type="Texture" id=7]
|
|
||||||
[ext_resource path="res://art/filmgrain.png" type="Texture" id=8]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=1]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform sampler2D vignette;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec3 vignette_color = texture(vignette,UV).rgb;
|
|
||||||
//screen texture stores gaussian blurred copies on mipmaps
|
|
||||||
COLOR.rgb = textureLod(SCREEN_TEXTURE,SCREEN_UV,(1.0-vignette_color.r)*4.0).rgb;
|
|
||||||
COLOR.rgb*= texture(vignette,UV).rgb;
|
|
||||||
}"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=2]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 1 )
|
|
||||||
shader_param/vignette = ExtResource( 6 )
|
|
||||||
_sections_unfolded = [ "shader", "shader_param" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=3]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform float amount : hint_range(0,5);
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
|
|
||||||
COLOR.rgb = textureLod(SCREEN_TEXTURE,SCREEN_UV,amount).rgb;
|
|
||||||
}"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=4]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 3 )
|
|
||||||
shader_param/amount = 4.0
|
|
||||||
_sections_unfolded = [ "shader", "shader_param" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=5]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform float size_x=0.008;
|
|
||||||
uniform float size_y=0.008;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 uv = SCREEN_UV;
|
|
||||||
uv-=mod(uv,vec2(size_x,size_y));
|
|
||||||
|
|
||||||
COLOR.rgb= textureLod(SCREEN_TEXTURE,uv,0.0).rgb;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=6]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 5 )
|
|
||||||
shader_param/size_x = null
|
|
||||||
shader_param/size_y = null
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=7]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform float rotation=3.0;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec2 uv = SCREEN_UV;
|
|
||||||
vec2 rel = uv-vec2(0.5,0.5);
|
|
||||||
float angle = length(rel)*rotation;
|
|
||||||
mat2 rot = mat2(vec2(cos(angle),-sin(angle)),vec2(sin(angle),cos(angle)));
|
|
||||||
rel = rot * rel;
|
|
||||||
uv = clamp(rel + vec2(0.5,0.5),vec2(0,0),vec2(1,1));
|
|
||||||
COLOR.rgb= textureLod(SCREEN_TEXTURE,uv,0.0).rgb;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=8]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 7 )
|
|
||||||
shader_param/rotation = null
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=9]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform vec4 base : hint_color;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
|
|
||||||
//float v = max(c.r,max(c.g,c.b));
|
|
||||||
float v = dot(c,vec3(0.33333,0.33333,0.33333));
|
|
||||||
v=sqrt(v);
|
|
||||||
//v*=v;
|
|
||||||
COLOR.rgb= base.rgb*v;
|
|
||||||
|
|
||||||
}"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=10]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 9 )
|
|
||||||
shader_param/base = Color( 0.54451, 0.408353, 0.403137, 1 )
|
|
||||||
_sections_unfolded = [ "shader", "shader_param" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=11]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
c=vec3(1.0)-c;
|
|
||||||
COLOR.rgb=c;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=12]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 11 )
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=13]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
c=mod(c+vec3(0.5),vec3(1.0));
|
|
||||||
COLOR.rgb=c;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=14]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 13 )
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=15]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
COLOR.rgb=normalize(c);
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=16]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 15 )
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=17]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform float brightness=0.8;
|
|
||||||
uniform float contrast=1.5;
|
|
||||||
uniform float saturation=1.8;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
|
|
||||||
c.rgb = mix(vec3(0.0),c.rgb,brightness);
|
|
||||||
c.rgb = mix(vec3(0.5),c.rgb,contrast);
|
|
||||||
c.rgb = mix(vec3(dot(vec3(1.0),c.rgb)*0.33333),c.rgb,saturation);
|
|
||||||
|
|
||||||
COLOR.rgb=c;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=18]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 17 )
|
|
||||||
shader_param/brightness = null
|
|
||||||
shader_param/contrast = null
|
|
||||||
shader_param/saturation = null
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=19]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform float frequency=60;
|
|
||||||
uniform float depth = 0.005;
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
|
|
||||||
vec2 uv = SCREEN_UV;
|
|
||||||
uv.x += sin(uv.y*frequency+TIME)*depth;
|
|
||||||
uv.x = clamp(uv.x,0,1);
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,uv,0.0).rgb;
|
|
||||||
|
|
||||||
|
|
||||||
COLOR.rgb=c;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=20]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 19 )
|
|
||||||
shader_param/frequency = null
|
|
||||||
shader_param/depth = null
|
|
||||||
_sections_unfolded = [ "shader" ]
|
|
||||||
|
|
||||||
[sub_resource type="Shader" id=21]
|
|
||||||
|
|
||||||
code = "shader_type canvas_item;
|
|
||||||
|
|
||||||
uniform vec4 base : hint_color;
|
|
||||||
uniform sampler2D grain;
|
|
||||||
uniform float grain_strength=0.3;
|
|
||||||
uniform sampler2D vignette;
|
|
||||||
uniform float fps=12;
|
|
||||||
uniform float stretch = 0.5;
|
|
||||||
uniform float flashing=0.01;
|
|
||||||
|
|
||||||
float make_grain(float time,vec2 uv) {
|
|
||||||
|
|
||||||
vec2 ofs = vec2(sin(41.0*time*sin(time*123.0)),sin(27.0*time*sin(time*312.0)));
|
|
||||||
return texture(grain,(uv+mod(ofs,vec2(1,1)))*stretch).r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
vec3 c = textureLod(SCREEN_TEXTURE,SCREEN_UV,0.0).rgb;
|
|
||||||
|
|
||||||
//float v = max(c.r,max(c.g,c.b));
|
|
||||||
float v = dot(c,vec3(0.33333,0.33333,0.33333));
|
|
||||||
v=sqrt(v);
|
|
||||||
//v*=v;
|
|
||||||
|
|
||||||
float f = 1.0/fps;
|
|
||||||
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*2.0,UV)*0.25);
|
|
||||||
|
|
||||||
|
|
||||||
COLOR.rgb= base.rgb*v-vec3(g)*grain_strength;
|
|
||||||
COLOR.rgb*=texture(vignette,UV).r;
|
|
||||||
float ft = TIME * 0.002;
|
|
||||||
COLOR.rgb+=vec3(sin(75.0*ft*sin(ft*123.0)))*flashing;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=22]
|
|
||||||
|
|
||||||
shader/shader = SubResource( 21 )
|
|
||||||
shader_param/base = Color( 0.450274, 0.361255, 0.335059, 1 )
|
|
||||||
shader_param/grain_strength = 0.3
|
|
||||||
shader_param/fps = 12
|
|
||||||
shader_param/stretch = 0.5
|
|
||||||
shader_param/flashing = 0.01
|
|
||||||
shader_param/grain = ExtResource( 8 )
|
|
||||||
shader_param/vignette = ExtResource( 6 )
|
|
||||||
_sections_unfolded = [ "shader", "shader_param" ]
|
|
||||||
|
|
||||||
[node name="Control" type="Control"]
|
|
||||||
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
script = ExtResource( 1 )
|
|
||||||
_sections_unfolded = [ "Pause" ]
|
|
||||||
|
|
||||||
[node name="pictures" type="Control" parent="."]
|
|
||||||
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
|
|
||||||
[node name="burano" type="TextureRect" parent="pictures"]
|
|
||||||
|
|
||||||
margin_right = 40.0
|
|
||||||
margin_bottom = 40.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 2 )
|
|
||||||
stretch_mode = 0
|
|
||||||
|
|
||||||
[node name="roby" type="TextureRect" parent="pictures"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
margin_right = 40.0
|
|
||||||
margin_bottom = 40.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 3 )
|
|
||||||
stretch_mode = 0
|
|
||||||
|
|
||||||
[node name="mountains" type="TextureRect" parent="pictures"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
margin_right = 40.0
|
|
||||||
margin_bottom = 40.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 4 )
|
|
||||||
stretch_mode = 0
|
|
||||||
|
|
||||||
[node name="forest" type="TextureRect" parent="pictures"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
margin_right = 40.0
|
|
||||||
margin_bottom = 40.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 5 )
|
|
||||||
stretch_mode = 0
|
|
||||||
|
|
||||||
[node name="effects" type="Control" parent="."]
|
|
||||||
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
margin_right = -20.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
|
|
||||||
[node name="disabled" type="Control" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
margin_right = 40.0
|
|
||||||
margin_bottom = 40.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
|
|
||||||
[node name="vignette" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 2 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="blur" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 4 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="pixelize" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 6 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="whirl" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 8 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="sepia" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 10 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
margin_right = 14.0
|
|
||||||
margin_bottom = -2.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material", "Visibility" ]
|
|
||||||
|
|
||||||
[node name="negative" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 12 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="contrasted" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 14 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="normalized" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 16 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="BCS" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 18 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
margin_top = 3.0
|
|
||||||
margin_bottom = -3.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="mirage" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 20 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="old_film" type="TextureRect" parent="effects"]
|
|
||||||
|
|
||||||
visible = false
|
|
||||||
material = SubResource( 22 )
|
|
||||||
anchor_right = 1
|
|
||||||
anchor_bottom = 1
|
|
||||||
margin_left = -3.0
|
|
||||||
margin_right = 3.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 1
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
texture = ExtResource( 7 )
|
|
||||||
expand = true
|
|
||||||
stretch_mode = 0
|
|
||||||
_sections_unfolded = [ "Material" ]
|
|
||||||
|
|
||||||
[node name="picture" type="OptionButton" parent="."]
|
|
||||||
|
|
||||||
margin_left = 8.0
|
|
||||||
margin_top = 7.0
|
|
||||||
margin_right = 131.0
|
|
||||||
margin_bottom = 28.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
toggle_mode = false
|
|
||||||
enabled_focus_mode = 2
|
|
||||||
shortcut = null
|
|
||||||
group = null
|
|
||||||
flat = false
|
|
||||||
align = 0
|
|
||||||
selected = -1
|
|
||||||
items = [ ]
|
|
||||||
|
|
||||||
[node name="effect" type="OptionButton" parent="."]
|
|
||||||
|
|
||||||
margin_left = 137.0
|
|
||||||
margin_top = 7.0
|
|
||||||
margin_right = 260.0
|
|
||||||
margin_bottom = 28.0
|
|
||||||
rect_clip_content = false
|
|
||||||
mouse_filter = 0
|
|
||||||
size_flags_horizontal = 2
|
|
||||||
size_flags_vertical = 2
|
|
||||||
toggle_mode = false
|
|
||||||
enabled_focus_mode = 2
|
|
||||||
shortcut = null
|
|
||||||
group = null
|
|
||||||
flat = false
|
|
||||||
align = 0
|
|
||||||
selected = -1
|
|
||||||
items = [ ]
|
|
||||||
|
|
||||||
[connection signal="item_selected" from="picture" to="." method="_on_picture_item_selected"]
|
|
||||||
|
|
||||||
[connection signal="item_selected" from="effect" to="." method="_on_effect_item_selected"]
|
|
||||||
|
|
||||||
|
|
||||||
@@ -15,16 +15,16 @@ float a;
|
|||||||
float maxa=col.a;
|
float maxa=col.a;
|
||||||
float mina=col.a;
|
float mina=col.a;
|
||||||
a=texture(TEXTURE,UV+vec2(0,-outline_width)*ps).a;
|
a=texture(TEXTURE,UV+vec2(0,-outline_width)*ps).a;
|
||||||
maxa=max(a,maxa);
|
maxa=max(a,maxa);
|
||||||
mina=min(a,mina);
|
mina=min(a,mina);
|
||||||
a=texture(TEXTURE,UV+vec2(0,outline_width)*ps).a;
|
a=texture(TEXTURE,UV+vec2(0,outline_width)*ps).a;
|
||||||
maxa=max(a,maxa);
|
maxa=max(a,maxa);
|
||||||
mina=min(a,mina);
|
mina=min(a,mina);
|
||||||
a=texture(TEXTURE,UV+vec2(-outline_width,0)*ps).a;
|
a=texture(TEXTURE,UV+vec2(-outline_width,0)*ps).a;
|
||||||
maxa=max(a,maxa);
|
maxa=max(a,maxa);
|
||||||
mina=min(a,mina);
|
mina=min(a,mina);
|
||||||
a=texture(TEXTURE,UV+vec2(outline_width,0)*ps).a;
|
a=texture(TEXTURE,UV+vec2(outline_width,0)*ps).a;
|
||||||
maxa=max(a,maxa);
|
maxa=max(a,maxa);
|
||||||
mina=min(a,mina);
|
mina=min(a,mina);
|
||||||
|
|
||||||
COLOR=mix(col,outline_color,maxa-mina);
|
COLOR=mix(col,outline_color,maxa-mina);
|
||||||
@@ -56,21 +56,21 @@ void fragment(){
|
|||||||
float mina = col.a;
|
float mina = col.a;
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(0, -outline_width)*ps).a;
|
a = texture(TEXTURE, UV + vec2(0, -outline_width)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(0, outline_width)*ps).a;
|
a = texture(TEXTURE, UV + vec2(0, outline_width)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(-outline_width,0)*ps).a;
|
a = texture(TEXTURE, UV + vec2(-outline_width,0)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(outline_width, 0)*ps).a;
|
a = texture(TEXTURE, UV + vec2(outline_width, 0)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
COLOR = mix(col, outline_color, maxa-mina);
|
COLOR = mix(col, outline_color, maxa-mina);
|
||||||
}"
|
}"
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ render_mode blend_premul_alpha;
|
|||||||
|
|
||||||
//this shader only works properly with premultiplied alpha blend mode
|
//this shader only works properly with premultiplied alpha blend mode
|
||||||
uniform float aura_width = 2.0;
|
uniform float aura_width = 2.0;
|
||||||
uniform vec4 aura_color:hint_color;
|
uniform vec4 aura_color:hint_color;
|
||||||
|
|
||||||
void fragment(){
|
void fragment(){
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
@@ -97,30 +97,30 @@ void fragment(){
|
|||||||
float a;
|
float a;
|
||||||
float maxa = col.a;
|
float maxa = col.a;
|
||||||
float mina = col.a;
|
float mina = col.a;
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(0, -aura_width)*ps).a;
|
a = texture(TEXTURE, UV + vec2(0, -aura_width)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(0, aura_width)*ps).a;
|
a = texture(TEXTURE, UV + vec2(0, aura_width)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(-aura_width, 0)*ps).a;
|
a = texture(TEXTURE, UV + vec2(-aura_width, 0)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
a = texture(TEXTURE, UV + vec2(aura_width, 0)*ps).a;
|
a = texture(TEXTURE, UV + vec2(aura_width, 0)*ps).a;
|
||||||
maxa = max(a, maxa);
|
maxa = max(a, maxa);
|
||||||
mina = min(a, mina);
|
mina = min(a, mina);
|
||||||
|
|
||||||
col.rgb *= col.a;
|
col.rgb *= col.a;
|
||||||
|
|
||||||
COLOR = col;
|
COLOR = col;
|
||||||
float auraa = (maxa-mina);
|
float auraa = (maxa-mina);
|
||||||
|
|
||||||
COLOR.rgb += aura_color.rgb*(auraa);
|
COLOR.rgb += aura_color.rgb*(auraa);
|
||||||
|
|
||||||
}"
|
}"
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=7]
|
[sub_resource type="ShaderMaterial" id=7]
|
||||||
@@ -141,13 +141,13 @@ uniform float radius = 4.0;
|
|||||||
void fragment(){
|
void fragment(){
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
vec2 ps = TEXTURE_PIXEL_SIZE;
|
vec2 ps = TEXTURE_PIXEL_SIZE;
|
||||||
|
|
||||||
col += texture(TEXTURE, UV + vec2(0, -radius)*ps);
|
col += texture(TEXTURE, UV + vec2(0, -radius)*ps);
|
||||||
col += texture(TEXTURE, UV + vec2(0, radius)*ps);
|
col += texture(TEXTURE, UV + vec2(0, radius)*ps);
|
||||||
col += texture(TEXTURE, UV + vec2(-radius, 0)*ps);
|
col += texture(TEXTURE, UV + vec2(-radius, 0)*ps);
|
||||||
col += texture(TEXTURE, UV + vec2(radius, 0)*ps);
|
col += texture(TEXTURE, UV + vec2(radius, 0)*ps);
|
||||||
col /= 5.0;
|
col /= 5.0;
|
||||||
|
|
||||||
COLOR = col;
|
COLOR = col;
|
||||||
}"
|
}"
|
||||||
|
|
||||||
@@ -168,13 +168,13 @@ uniform float fattyness = 2.0;
|
|||||||
void fragment(){
|
void fragment(){
|
||||||
vec2 ruv = UV - vec2(0.5,0.5);
|
vec2 ruv = UV - vec2(0.5,0.5);
|
||||||
vec2 dir = normalize(ruv);
|
vec2 dir = normalize(ruv);
|
||||||
float len = length(ruv);
|
float len = length(ruv);
|
||||||
|
|
||||||
len = pow(len*2.0, fattyness)*0.5;
|
len = pow(len*2.0, fattyness)*0.5;
|
||||||
ruv = len*dir;
|
ruv = len*dir;
|
||||||
|
|
||||||
vec4 col = texture(TEXTURE, ruv + vec2(0.5, 0.5));
|
vec4 col = texture(TEXTURE, ruv + vec2(0.5, 0.5));
|
||||||
|
|
||||||
COLOR = col;
|
COLOR = col;
|
||||||
}"
|
}"
|
||||||
|
|
||||||
@@ -195,9 +195,9 @@ uniform vec4 modulate:hint_color;
|
|||||||
|
|
||||||
void fragment(){
|
void fragment(){
|
||||||
vec2 ps = TEXTURE_PIXEL_SIZE;
|
vec2 ps = TEXTURE_PIXEL_SIZE;
|
||||||
|
|
||||||
vec4 shadow = texture(TEXTURE, UV + vec2(-radius, -radius)*ps);
|
vec4 shadow = texture(TEXTURE, UV + vec2(-radius, -radius)*ps);
|
||||||
|
|
||||||
shadow += texture(TEXTURE, UV + vec2(-radius, 0)*ps);
|
shadow += texture(TEXTURE, UV + vec2(-radius, 0)*ps);
|
||||||
shadow += texture(TEXTURE, UV + vec2(-radius, radius)*ps);
|
shadow += texture(TEXTURE, UV + vec2(-radius, radius)*ps);
|
||||||
shadow += texture(TEXTURE, UV + vec2(0, -radius)*ps);
|
shadow += texture(TEXTURE, UV + vec2(0, -radius)*ps);
|
||||||
@@ -207,7 +207,7 @@ void fragment(){
|
|||||||
shadow += texture(TEXTURE, UV + vec2(radius, radius)*ps);
|
shadow += texture(TEXTURE, UV + vec2(radius, radius)*ps);
|
||||||
shadow /= 8.0;
|
shadow /= 8.0;
|
||||||
shadow *= modulate;
|
shadow *= modulate;
|
||||||
|
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
COLOR = mix(shadow, col, col.a);
|
COLOR = mix(shadow, col, col.a);
|
||||||
}"
|
}"
|
||||||
@@ -230,10 +230,10 @@ uniform vec4 modulate:hint_color;
|
|||||||
|
|
||||||
void fragment(){
|
void fragment(){
|
||||||
vec2 ps = TEXTURE_PIXEL_SIZE;
|
vec2 ps = TEXTURE_PIXEL_SIZE;
|
||||||
|
|
||||||
vec4 shadow = vec4(modulate.rgb, texture(TEXTURE, UV - offset*ps).a*modulate.a);
|
vec4 shadow = vec4(modulate.rgb, texture(TEXTURE, UV - offset*ps).a*modulate.a);
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
|
|
||||||
COLOR = mix(shadow, col, col.a);
|
COLOR = mix(shadow, col, col.a);
|
||||||
}"
|
}"
|
||||||
|
|
||||||
@@ -253,9 +253,8 @@ render_mode blend_mix;
|
|||||||
uniform vec4 modulate:hint_color;
|
uniform vec4 modulate:hint_color;
|
||||||
|
|
||||||
void fragment(){
|
void fragment(){
|
||||||
|
|
||||||
COLOR = vec4(modulate.rgb, texture(TEXTURE, UV).a*modulate.a);
|
COLOR = vec4(modulate.rgb, texture(TEXTURE, UV).a*modulate.a);
|
||||||
|
|
||||||
}"
|
}"
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=17]
|
[sub_resource type="ShaderMaterial" id=17]
|
||||||
@@ -278,7 +277,7 @@ void fragment(){
|
|||||||
vec2 ps = TEXTURE_PIXEL_SIZE;
|
vec2 ps = TEXTURE_PIXEL_SIZE;
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
vec4 glow = col;
|
vec4 glow = col;
|
||||||
|
|
||||||
glow += texture(TEXTURE, UV + vec2(-r, -r)*ps);
|
glow += texture(TEXTURE, UV + vec2(-r, -r)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(-r, 0)*ps);
|
glow += texture(TEXTURE, UV + vec2(-r, 0)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(-r, r)*ps);
|
glow += texture(TEXTURE, UV + vec2(-r, r)*ps);
|
||||||
@@ -287,7 +286,7 @@ void fragment(){
|
|||||||
glow += texture(TEXTURE, UV + vec2(r, -r)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, -r)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(r, 0)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, 0)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(r, r)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, r)*ps);
|
||||||
|
|
||||||
r *= 2.0;
|
r *= 2.0;
|
||||||
glow += texture(TEXTURE, UV + vec2(-r, -r)*ps);
|
glow += texture(TEXTURE, UV + vec2(-r, -r)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(-r, 0)*ps);
|
glow += texture(TEXTURE, UV + vec2(-r, 0)*ps);
|
||||||
@@ -297,13 +296,13 @@ void fragment(){
|
|||||||
glow += texture(TEXTURE, UV + vec2(r, -r)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, -r)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(r, 0)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, 0)*ps);
|
||||||
glow += texture(TEXTURE, UV + vec2(r, r)*ps);
|
glow += texture(TEXTURE, UV + vec2(r, r)*ps);
|
||||||
|
|
||||||
glow /= 17.0;
|
glow /= 17.0;
|
||||||
glow *= amount;
|
glow *= amount;
|
||||||
col.rgb *= col.a;
|
col.rgb *= col.a;
|
||||||
|
|
||||||
COLOR = glow + col;
|
COLOR = glow + col;
|
||||||
|
|
||||||
}"
|
}"
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id=19]
|
[sub_resource type="ShaderMaterial" id=19]
|
||||||
@@ -322,13 +321,12 @@ render_mode blend_mix;
|
|||||||
uniform float amount = 20.0;
|
uniform float amount = 20.0;
|
||||||
|
|
||||||
void fragment(){
|
void fragment(){
|
||||||
|
|
||||||
vec2 uv = UV*0.05;
|
vec2 uv = UV*0.05;
|
||||||
float a = fract(sin(dot(UV, vec2(12.9898, 78.233)))*438.5453);
|
float a = fract(sin(dot(UV, vec2(12.9898, 78.233)))*438.5453);
|
||||||
vec4 col = texture(TEXTURE, UV);
|
vec4 col = texture(TEXTURE, UV);
|
||||||
|
|
||||||
col.a *= pow(a, amount);
|
col.a *= pow(a, amount);
|
||||||
|
|
||||||
COLOR = col;
|
COLOR = col;
|
||||||
}"
|
}"
|
||||||
|
|
||||||
|
|||||||
@@ -47,48 +47,48 @@ var first_call = true
|
|||||||
var debug_messages = false
|
var debug_messages = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
|
||||||
if (target == null):
|
if (target == null):
|
||||||
# NOTE: you HAVE to have a node called target as a child of this node!
|
# NOTE: you HAVE to have a node called target as a child of this node!
|
||||||
# so we create one if one doesn't already exist
|
# so we create one if one doesn't already exist
|
||||||
if has_node("target") == false:
|
if has_node("target") == false:
|
||||||
target = Spatial.new()
|
target = Spatial.new()
|
||||||
add_child(target)
|
add_child(target)
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
target.set_owner(get_tree().edited_scene_root)
|
target.set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
target.name = "target"
|
target.name = "target"
|
||||||
else:
|
else:
|
||||||
target = get_node("target")
|
target = get_node("target")
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
|
_make_editor_sphere_at_node(target, Color(1, 0, 1, 1))
|
||||||
|
|
||||||
if middle_joint_target == null:
|
if middle_joint_target == null:
|
||||||
if has_node("middle_joint_target") == false:
|
if has_node("middle_joint_target") == false:
|
||||||
middle_joint_target = Spatial.new()
|
middle_joint_target = Spatial.new()
|
||||||
add_child(middle_joint_target)
|
add_child(middle_joint_target)
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
middle_joint_target.set_owner(get_tree().edited_scene_root)
|
middle_joint_target.set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
middle_joint_target.name = "middle_joint_target"
|
middle_joint_target.name = "middle_joint_target"
|
||||||
else:
|
else:
|
||||||
middle_joint_target = get_node("middle_joint_target")
|
middle_joint_target = get_node("middle_joint_target")
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
|
_make_editor_sphere_at_node(middle_joint_target, Color(1, 0.24, 1, 1))
|
||||||
|
|
||||||
# Make all of the bone nodes for each bone in the IK chain
|
# Make all of the bone nodes for each bone in the IK chain
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
# Make sure we're using the right update mode
|
# Make sure we're using the right update mode
|
||||||
_set_update_mode(update_mode)
|
_set_update_mode(update_mode)
|
||||||
|
|
||||||
@@ -123,11 +123,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:
|
||||||
@@ -135,44 +135,44 @@ func _set_update_mode(new_value):
|
|||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
|
print (name, " - IK_FABRIK: Unknown update mode. NOT updating skeleton")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
func _set_skeleton_path(new_value):
|
func _set_skeleton_path(new_value):
|
||||||
|
|
||||||
# Because get_node doesn't work in the first call, we just want to assign instead
|
# Because get_node doesn't work in the first call, we just want to assign instead
|
||||||
if first_call == true:
|
if first_call:
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
return
|
return
|
||||||
|
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
|
|
||||||
if skeleton_path == null:
|
if skeleton_path == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||||
return
|
return
|
||||||
|
|
||||||
var temp = get_node(skeleton_path)
|
var temp = get_node(skeleton_path)
|
||||||
if temp != null:
|
if temp != null:
|
||||||
# If it has the method "get_bone_global_pose" it is likely a Skeleton
|
# If it has the method "get_bone_global_pose" it is likely a Skeleton
|
||||||
if temp.has_method("get_bone_global_pose") == true:
|
if temp.has_method("get_bone_global_pose"):
|
||||||
skeleton = temp
|
skeleton = temp
|
||||||
bone_IDs = {}
|
bone_IDs = {}
|
||||||
|
|
||||||
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
|
# (Delete all of the old bone nodes and) Make all of the bone nodes for each bone in the IK chain
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: Attached to a new skeleton")
|
print (name, " - IK_FABRIK: Attached to a new skeleton")
|
||||||
# If not, then it's (likely) not a Skeleton node
|
# If not, then it's (likely) not a Skeleton node
|
||||||
else:
|
else:
|
||||||
skeleton = null
|
skeleton = null
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
|
print (name, " - IK_FABRIK: skeleton_path does not point to a skeleton!")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_FABRIK: No Nodepath selected for skeleton_path!")
|
||||||
|
|
||||||
############# OTHER (NON IK SOLVER RELATED) FUNCTIONS #############
|
############# OTHER (NON IK SOLVER RELATED) FUNCTIONS #############
|
||||||
@@ -181,33 +181,33 @@ func _set_skeleton_path(new_value):
|
|||||||
func _make_bone_nodes():
|
func _make_bone_nodes():
|
||||||
# Remove all of the old bone nodes
|
# Remove all of the old bone nodes
|
||||||
# TODO: (not a huge concern, as these can be removed in the editor)
|
# TODO: (not a huge concern, as these can be removed in the editor)
|
||||||
|
|
||||||
for bone in range(0, bones_in_chain.size()):
|
for bone in range(0, bones_in_chain.size()):
|
||||||
|
|
||||||
var bone_name = bones_in_chain[bone]
|
var bone_name = bones_in_chain[bone]
|
||||||
if has_node(bone_name) == false:
|
if has_node(bone_name) == false:
|
||||||
var new_node = Spatial.new()
|
var new_node = Spatial.new()
|
||||||
bone_nodes[bone] = new_node
|
bone_nodes[bone] = new_node
|
||||||
add_child(bone_nodes[bone])
|
add_child(bone_nodes[bone])
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
if get_tree() != null:
|
if get_tree() != null:
|
||||||
if get_tree().edited_scene_root != null:
|
if get_tree().edited_scene_root != null:
|
||||||
bone_nodes[bone].set_owner(get_tree().edited_scene_root)
|
bone_nodes[bone].set_owner(get_tree().edited_scene_root)
|
||||||
|
|
||||||
bone_nodes[bone].name = bone_name
|
bone_nodes[bone].name = bone_name
|
||||||
|
|
||||||
else:
|
else:
|
||||||
bone_nodes[bone] = get_node(bone_name)
|
bone_nodes[bone] = get_node(bone_name)
|
||||||
|
|
||||||
# If we are in the editor, we want to make a sphere at this node
|
# If we are in the editor, we want to make a sphere at this node
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
|
_make_editor_sphere_at_node(bone_nodes[bone], Color(0.65, 0, 1, 1))
|
||||||
|
|
||||||
|
|
||||||
func _set_bone_chain_bones(new_value):
|
func _set_bone_chain_bones(new_value):
|
||||||
bones_in_chain = new_value
|
bones_in_chain = new_value
|
||||||
|
|
||||||
_make_bone_nodes()
|
_make_bone_nodes()
|
||||||
|
|
||||||
func _set_bone_chain_lengths(new_value):
|
func _set_bone_chain_lengths(new_value):
|
||||||
@@ -218,16 +218,16 @@ func _set_bone_chain_lengths(new_value):
|
|||||||
# Various upate methods
|
# Various upate methods
|
||||||
# ---------------------
|
# ---------------------
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
func _notification(what):
|
func _notification(what):
|
||||||
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
||||||
if reset_iterations_on_update == true:
|
if reset_iterations_on_update:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
|
|
||||||
@@ -235,71 +235,71 @@ func _notification(what):
|
|||||||
############# IK SOLVER RELATED FUNCTIONS #############
|
############# IK SOLVER RELATED FUNCTIONS #############
|
||||||
|
|
||||||
func update_skeleton():
|
func update_skeleton():
|
||||||
|
|
||||||
#### ERROR CHECKING conditions
|
#### ERROR CHECKING conditions
|
||||||
if first_call == true:
|
if first_call:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
first_call = false
|
first_call = false
|
||||||
|
|
||||||
if skeleton == null:
|
if skeleton == null:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if bones_in_chain == null:
|
if bones_in_chain == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: No Bones in IK chain defined!")
|
print (name, " - IK_FABRIK: No Bones in IK chain defined!")
|
||||||
return
|
return
|
||||||
if bones_in_chain_lengths == null:
|
if bones_in_chain_lengths == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
|
print (name, " - IK_FABRIK: No Bone lengths in IK chain defined!")
|
||||||
return
|
return
|
||||||
|
|
||||||
if bones_in_chain.size() != bones_in_chain_lengths.size():
|
if bones_in_chain.size() != bones_in_chain_lengths.size():
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_FABRIK: bones_in_chain and bones_in_chain_lengths!")
|
print (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(0, 1, 0))
|
bone_nodes[i].look_at(get_bone_transform(i+1).origin + skeleton.global_transform.origin, Vector3(0, 1, 0))
|
||||||
|
|
||||||
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 == null:
|
if total_length == null:
|
||||||
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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func solve_chain():
|
func solve_chain():
|
||||||
|
|
||||||
# If we have reached our max chain iteration, and we are limiting ourselves, then return.
|
# If we have reached our max chain iteration, and we are limiting ourselves, then return.
|
||||||
# Otherwise set chain_iterations to zero (so we constantly update)
|
# Otherwise set chain_iterations to zero (so we constantly update)
|
||||||
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations == true:
|
if chain_iterations >= CHAIN_MAX_ITER and limit_chain_iterations:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
chain_iterations = 0
|
chain_iterations = 0
|
||||||
|
|
||||||
# Update the origin with the current bone's origin
|
# Update the origin with the current bone's origin
|
||||||
chain_origin = get_bone_transform(0)
|
chain_origin = get_bone_transform(0)
|
||||||
|
|
||||||
# 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 = -target.global_transform.basis.z.normalized()
|
#var dir = -target.global_transform.basis.z.normalized()
|
||||||
@@ -308,58 +308,58 @@ func solve_chain():
|
|||||||
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
dir = bone_nodes[bone_nodes.size()-2].global_transform.basis.z.normalized()
|
||||||
else:
|
else:
|
||||||
dir = -target.global_transform.basis.z.normalized()
|
dir = -target.global_transform.basis.z.normalized()
|
||||||
|
|
||||||
# Get the target position (accounting for the final bone and it's length)
|
# Get the target position (accounting for the final bone and it's length)
|
||||||
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
var target_pos = target.global_transform.origin + (dir * bones_in_chain_lengths[bone_nodes.size()-1])
|
||||||
|
|
||||||
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
|
# If we are using middle joint target (and have more than 2 bones), move our middle joint towards it!
|
||||||
if use_middle_joint_target == true:
|
if use_middle_joint_target:
|
||||||
if bone_nodes.size() > 2:
|
if bone_nodes.size() > 2:
|
||||||
var middle_point_pos = middle_joint_target.global_transform
|
var middle_point_pos = middle_joint_target.global_transform
|
||||||
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
|
bone_nodes[bone_nodes.size()/2].global_transform.origin = middle_point_pos.origin
|
||||||
|
|
||||||
# Get the distance from the origin to the target
|
# Get the distance from the origin to the target
|
||||||
var distance = (chain_origin.origin - target_pos).length()
|
var distance = (chain_origin.origin - target_pos).length()
|
||||||
|
|
||||||
# If the distance is farther than our total reach, the target cannot be reached.
|
# If the distance is farther than our total reach, the target cannot be reached.
|
||||||
# Make the bone chain a straight line pointing towards the target
|
# Make the bone chain a straight line pointing towards the target
|
||||||
if distance > total_length:
|
if distance > total_length:
|
||||||
for i in range (0, bones_in_chain.size()):
|
for i in range (0, bones_in_chain.size()):
|
||||||
# Create a direct line to target and make this bone travel down that line
|
# Create a direct line to target and make this bone travel down that line
|
||||||
|
|
||||||
var r = (target_pos - bone_nodes[i].global_transform.origin).length()
|
var r = (target_pos - bone_nodes[i].global_transform.origin).length()
|
||||||
var l = bones_in_chain_lengths[i] / r
|
var l = bones_in_chain_lengths[i] / r
|
||||||
|
|
||||||
# Find new join position
|
# Find new join position
|
||||||
var new_pos = (1-l) * bone_nodes[i].global_transform.origin + l * target_pos
|
var new_pos = (1-l) * bone_nodes[i].global_transform.origin + l * target_pos
|
||||||
|
|
||||||
# Apply it to the bone node
|
# Apply it to the bone node
|
||||||
bone_nodes[i].look_at(new_pos, Vector3(0, 1, 0))
|
bone_nodes[i].look_at(new_pos, Vector3(0, 1, 0))
|
||||||
bone_nodes[i].global_transform.origin = new_pos
|
bone_nodes[i].global_transform.origin = new_pos
|
||||||
|
|
||||||
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
|
# Apply the rotation to the first node in the bone chain, making it look at the next bone in the bone chain
|
||||||
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3(0, 1, 0))
|
bone_nodes[0].look_at(bone_nodes[1].global_transform.origin, Vector3(0, 1, 0))
|
||||||
|
|
||||||
# If the distance is NOT farther than our total reach, the target can be reached.
|
# If the distance is NOT farther than our total reach, the target can be reached.
|
||||||
else:
|
else:
|
||||||
# Get the difference between our end effector (the final bone in the chain) and the target
|
# Get the difference between our end effector (the final bone in the chain) and the target
|
||||||
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
var dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
||||||
|
|
||||||
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
|
# Check to see if the distance from the end effector to the target is within our error margin (CHAIN_TOLERANCE).
|
||||||
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
|
# If it not, move the chain towards the target (going forwards, backwards, and then applying rotation)
|
||||||
while dif > CHAIN_TOLERANCE:
|
while dif > CHAIN_TOLERANCE:
|
||||||
chain_backward()
|
chain_backward()
|
||||||
chain_forward()
|
chain_forward()
|
||||||
chain_apply_rotation()
|
chain_apply_rotation()
|
||||||
|
|
||||||
# Update the difference between our end effector (the final bone in the chain) and the target
|
# Update the difference between our end effector (the final bone in the chain) and the target
|
||||||
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
dif = (bone_nodes[bone_nodes.size()-1].global_transform.origin - target_pos).length()
|
||||||
|
|
||||||
# Add one to chain_iterations. If we have reached our max iterations, then break
|
# Add one to chain_iterations. If we have reached our max iterations, then break
|
||||||
chain_iterations = chain_iterations + 1
|
chain_iterations = chain_iterations + 1
|
||||||
if chain_iterations >= CHAIN_MAX_ITER:
|
if chain_iterations >= CHAIN_MAX_ITER:
|
||||||
break
|
break
|
||||||
|
|
||||||
# Reset the bone node transforms to the skeleton bone transforms
|
# Reset the bone node transforms to the skeleton bone transforms
|
||||||
#if (constrained == false): # Resetting seems to break bone constraints...
|
#if (constrained == false): # Resetting seems to break bone constraints...
|
||||||
for i in range(0, bone_nodes.size()):
|
for i in range(0, bone_nodes.size()):
|
||||||
@@ -369,7 +369,7 @@ func solve_chain():
|
|||||||
|
|
||||||
func chain_backward():
|
func chain_backward():
|
||||||
# Backward reaching pass
|
# Backward reaching pass
|
||||||
|
|
||||||
# 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
|
||||||
@@ -377,16 +377,16 @@ 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:
|
||||||
|
|
||||||
i -= 1
|
i -= 1
|
||||||
|
|
||||||
var r = bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.origin
|
var r = bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.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
|
||||||
@@ -395,90 +395,90 @@ func chain_backward():
|
|||||||
|
|
||||||
func chain_forward():
|
func chain_forward():
|
||||||
# Forward reaching pass
|
# Forward reaching pass
|
||||||
|
|
||||||
# Set root at initial position
|
# Set root at initial position
|
||||||
bone_nodes[0].global_transform.origin = chain_origin.origin
|
bone_nodes[0].global_transform.origin = chain_origin.origin
|
||||||
|
|
||||||
# Go through every bone in the bone chain
|
# Go through every bone in the bone chain
|
||||||
var i = 0
|
var i = 0
|
||||||
while i < bones_in_chain.size() - 1:
|
while i < bones_in_chain.size() - 1:
|
||||||
|
|
||||||
var r = (bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.origin)
|
var r = (bone_nodes[i+1].global_transform.origin - bone_nodes[i].global_transform.origin)
|
||||||
var l = bones_in_chain_lengths[i] / r.length()
|
var l = bones_in_chain_lengths[i] / r.length()
|
||||||
|
|
||||||
# Set the new joint position
|
# Set the new joint position
|
||||||
var new_pos = (1 - l) * bone_nodes[i].global_transform.origin + l * bone_nodes[i+1].global_transform.origin
|
var new_pos = (1 - l) * bone_nodes[i].global_transform.origin + l * bone_nodes[i+1].global_transform.origin
|
||||||
|
|
||||||
# Apply the new joint position, (potentially with constraints), to the bone node
|
# Apply the new joint position, (potentially with constraints), to the bone node
|
||||||
bone_nodes[i+1].global_transform.origin = new_pos
|
bone_nodes[i+1].global_transform.origin = new_pos
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
func chain_apply_rotation():
|
func chain_apply_rotation():
|
||||||
# Make all of the bones rotated correctly.
|
# Make all of the bones rotated correctly.
|
||||||
|
|
||||||
# For each bone in the bone chain
|
# For each bone in the bone chain
|
||||||
for i in range(0, bones_in_chain.size()):
|
for i in range(0, bones_in_chain.size()):
|
||||||
|
|
||||||
# Get the bone's transform, NOT converted to world space
|
# Get the bone's transform, NOT converted to world space
|
||||||
var bone_trans = get_bone_transform(i, false)
|
var bone_trans = get_bone_transform(i, false)
|
||||||
|
|
||||||
# If this is the last bone in the bone chain, rotate the bone so it faces
|
# If this is the last bone in the bone chain, rotate the bone so it faces
|
||||||
# the same direction as the next to last bone in the bone chain if there are more than
|
# the same direction as the next to last bone in the bone chain if there are more than
|
||||||
# two bones. If there are only two bones, rotate the end effector towards the target
|
# two bones. If there are only two bones, rotate the end effector towards the target
|
||||||
if i == bones_in_chain.size()-1:
|
if i == bones_in_chain.size()-1:
|
||||||
|
|
||||||
if bones_in_chain.size() > 2:
|
if bones_in_chain.size() > 2:
|
||||||
# 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(0, 1, 0))
|
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3(0, 1, 0))
|
||||||
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(0, 1, 0))
|
bone_trans = bone_trans.looking_at(b_target.origin, Vector3(0, 1, 0))
|
||||||
|
|
||||||
# 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(0, 1, 0))
|
bone_trans = bone_trans.looking_at(b_target.origin + dir, Vector3(0, 1, 0))
|
||||||
|
|
||||||
# The the bone's (updated) transform
|
# The the bone's (updated) transform
|
||||||
set_bone_transform(i, bone_trans)
|
set_bone_transform(i, bone_trans)
|
||||||
|
|
||||||
|
|
||||||
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 = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
|
var ret = skeleton.get_bone_global_pose(bone_IDs[bones_in_chain[bone]])
|
||||||
|
|
||||||
# If we need to convert the bone position from bone/skeleton space to world space, we
|
# If we need to convert the bone position from bone/skeleton space to world space, we
|
||||||
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
|
# use the Xform of the skeleton (because bone/skeleton space is relative to the position of the skeleton node).
|
||||||
if convert_to_world_space == true:
|
if convert_to_world_space:
|
||||||
ret.origin = skeleton.global_transform.xform(ret.origin)
|
ret.origin = skeleton.global_transform.xform(ret.origin)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ var first_call = true
|
|||||||
const empty_vector = Vector3()
|
const empty_vector = Vector3()
|
||||||
|
|
||||||
func _ready():
|
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:
|
||||||
@@ -29,10 +29,10 @@ func _ready():
|
|||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
|
print (name, " - IK_LookAt: Unknown update mode. NOT updating skeleton")
|
||||||
|
|
||||||
if Engine.editor_hint == true:
|
if Engine.editor_hint:
|
||||||
_setup_for_editor()
|
_setup_for_editor()
|
||||||
|
|
||||||
|
|
||||||
@@ -63,96 +63,96 @@ func _setup_for_editor():
|
|||||||
|
|
||||||
func _set_update(new_value):
|
func _set_update(new_value):
|
||||||
update_mode = new_value
|
update_mode = new_value
|
||||||
|
|
||||||
# Set all of our processes to false
|
# Set all of our processes to false
|
||||||
set_process(false)
|
set_process(false)
|
||||||
set_physics_process(false)
|
set_physics_process(false)
|
||||||
set_notify_transform(false)
|
set_notify_transform(false)
|
||||||
|
|
||||||
# Based on the value of upate, change how we handle updating the skeleton
|
# Based on the value of upate, change how we handle updating the skeleton
|
||||||
if update_mode == 0:
|
if update_mode == 0:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _process...")
|
print (name, " - IK_LookAt: updating skeleton using _process...")
|
||||||
elif update_mode == 1:
|
elif update_mode == 1:
|
||||||
set_physics_process(true)
|
set_physics_process(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _physics_process...")
|
print (name, " - IK_LookAt: updating skeleton using _physics_process...")
|
||||||
elif update_mode == 2:
|
elif update_mode == 2:
|
||||||
set_notify_transform(true)
|
set_notify_transform(true)
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: updating skeleton using _notification...")
|
print (name, " - IK_LookAt: updating skeleton using _notification...")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
|
print (name, " - IK_LookAt: NOT updating skeleton due to unknown update method...")
|
||||||
|
|
||||||
|
|
||||||
func _set_skeleton_path(new_value):
|
func _set_skeleton_path(new_value):
|
||||||
|
|
||||||
# Because get_node doesn't work in the first call, we just want to assign instead
|
# Because get_node doesn't work in the first call, we just want to assign instead
|
||||||
# This is to get around a issue with NodePaths exposed to the editor
|
# This is to get around a issue with NodePaths exposed to the editor
|
||||||
if first_call == true:
|
if first_call:
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
return
|
return
|
||||||
|
|
||||||
# Assign skeleton_path to whatever value is passed
|
# Assign skeleton_path to whatever value is passed
|
||||||
skeleton_path = new_value
|
skeleton_path = new_value
|
||||||
|
|
||||||
if skeleton_path == null:
|
if skeleton_path == null:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the node at that location, if there is one
|
# Get the node at that location, if there is one
|
||||||
var temp = get_node(skeleton_path)
|
var temp = get_node(skeleton_path)
|
||||||
if temp != null:
|
if temp != null:
|
||||||
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton
|
# If the node has the method "find_bone" then we can assume it is (likely) a skeleton
|
||||||
if temp.has_method("find_bone") == true:
|
if temp.has_method("find_bone"):
|
||||||
skeleton_to_use = temp
|
skeleton_to_use = temp
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: attached to (new) skeleton")
|
print (name, " - IK_LookAt: attached to (new) skeleton")
|
||||||
# If not, then it's (likely) not a skeleton
|
# If not, then it's (likely) not a skeleton
|
||||||
else:
|
else:
|
||||||
skeleton_to_use = null
|
skeleton_to_use = null
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
|
print (name, " - IK_LookAt: skeleton_path does not point to a skeleton!")
|
||||||
else:
|
else:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
print (name, " - IK_LookAt: No Nodepath selected for skeleton_path!")
|
||||||
|
|
||||||
|
|
||||||
func update_skeleton():
|
func update_skeleton():
|
||||||
|
|
||||||
# NOTE: Because get_node doesn't work in _ready, we need to skip
|
# NOTE: Because get_node doesn't work in _ready, we need to skip
|
||||||
# a call before doing anything.
|
# a call before doing anything.
|
||||||
if first_call == true:
|
if first_call:
|
||||||
first_call = false
|
first_call = false
|
||||||
if skeleton_to_use == null:
|
if skeleton_to_use == null:
|
||||||
_set_skeleton_path(skeleton_path)
|
_set_skeleton_path(skeleton_path)
|
||||||
|
|
||||||
|
|
||||||
# If we do not have a skeleton and/or we're not supposed to update, then return.
|
# If we do not have a skeleton and/or we're not supposed to update, then return.
|
||||||
if skeleton_to_use == null:
|
if skeleton_to_use == null:
|
||||||
return
|
return
|
||||||
if update_mode >= 3:
|
if update_mode >= 3:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the bone
|
# Get the bone
|
||||||
var bone = skeleton_to_use.find_bone(bone_name)
|
var bone = skeleton_to_use.find_bone(bone_name)
|
||||||
|
|
||||||
# If no bone is found (-1), then return (and optionally print an error)
|
# If no bone is found (-1), then return (and optionally print an error)
|
||||||
if bone == -1:
|
if bone == -1:
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
|
print (name, " - IK_LookAt: No bone in skeleton found with name [", bone_name, "]!")
|
||||||
return
|
return
|
||||||
|
|
||||||
# get the bone's rest position, and our position
|
# get the bone's rest position, and our position
|
||||||
var rest = skeleton_to_use.get_bone_global_pose(bone)
|
var rest = skeleton_to_use.get_bone_global_pose(bone)
|
||||||
var our_position = global_transform.origin
|
var our_position = global_transform.origin
|
||||||
|
|
||||||
# Convert our position relative to the skeleton's transform
|
# Convert our position relative to the skeleton's transform
|
||||||
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
|
var target_pos = skeleton_to_use.global_transform.xform_inv(global_transform.origin)
|
||||||
|
|
||||||
# Call helper's look_at function with the chosen up axis.
|
# Call helper's look_at function with the chosen up axis.
|
||||||
if look_at_axis == 0:
|
if look_at_axis == 0:
|
||||||
rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
|
rest = rest.looking_at(target_pos, Vector3(1, 0, 0))
|
||||||
@@ -162,34 +162,34 @@ func update_skeleton():
|
|||||||
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
|
rest = rest.looking_at(target_pos, Vector3(0, 0, 1))
|
||||||
else:
|
else:
|
||||||
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
rest = rest.looking_at(target_pos, Vector3(0, 1, 0))
|
||||||
if debug_messages == true:
|
if debug_messages:
|
||||||
print (name, " - IK_LookAt: Unknown look_at_axis value!")
|
print (name, " - IK_LookAt: Unknown look_at_axis value!")
|
||||||
|
|
||||||
# Get our rotation euler, and the bone's rotation euler
|
# Get our rotation euler, and the bone's rotation euler
|
||||||
var rest_euler = rest.basis.get_euler()
|
var rest_euler = rest.basis.get_euler()
|
||||||
var self_euler = global_transform.basis.orthonormalized().get_euler()
|
var self_euler = global_transform.basis.orthonormalized().get_euler()
|
||||||
|
|
||||||
# If we using negative rotation, we flip our rotation euler
|
# If we using negative rotation, we flip our rotation euler
|
||||||
if use_negative_our_rot == true:
|
if use_negative_our_rot:
|
||||||
self_euler = -self_euler
|
self_euler = -self_euler
|
||||||
|
|
||||||
# Apply our rotation euler, if wanted/required
|
# Apply our rotation euler, if wanted/required
|
||||||
if use_our_rotation_x == true:
|
if use_our_rotation_x:
|
||||||
rest_euler.x = self_euler.x
|
rest_euler.x = self_euler.x
|
||||||
if use_our_rotation_y == true:
|
if use_our_rotation_y:
|
||||||
rest_euler.y = self_euler.y
|
rest_euler.y = self_euler.y
|
||||||
if use_our_rotation_z == true:
|
if use_our_rotation_z:
|
||||||
rest_euler.z = self_euler.z
|
rest_euler.z = self_euler.z
|
||||||
|
|
||||||
# Rotate the bone by the (potentially) changed euler angle(s)
|
# Rotate the bone by the (potentially) changed euler angle(s)
|
||||||
rest.basis = Basis(rest_euler)
|
rest.basis = Basis(rest_euler)
|
||||||
|
|
||||||
# If we have additional rotation, then rotate it by the local rotation vectors
|
# If we have additional rotation, then rotate it by the local rotation vectors
|
||||||
if additional_rotation != empty_vector:
|
if additional_rotation != empty_vector:
|
||||||
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
|
rest.basis = rest.basis.rotated(rest.basis.x, deg2rad(additional_rotation.x))
|
||||||
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
|
rest.basis = rest.basis.rotated(rest.basis.y, deg2rad(additional_rotation.y))
|
||||||
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
|
rest.basis = rest.basis.rotated(rest.basis.z, deg2rad(additional_rotation.z))
|
||||||
|
|
||||||
# Finally, apply the bone rotation to the skeleton
|
# Finally, apply the bone rotation to the skeleton
|
||||||
skeleton_to_use.set_bone_global_pose(bone, rest)
|
skeleton_to_use.set_bone_global_pose(bone, rest)
|
||||||
|
|
||||||
@@ -202,4 +202,4 @@ func _physics_process(delta):
|
|||||||
update_skeleton()
|
update_skeleton()
|
||||||
func _notification(what):
|
func _notification(what):
|
||||||
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
if what == NOTIFICATION_TRANSFORM_CHANGED:
|
||||||
update_skeleton()
|
update_skeleton()
|
||||||
|
|||||||
@@ -3,19 +3,19 @@ extends EditorPlugin
|
|||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
# Plugin Initialization here!
|
# Plugin Initialization here!
|
||||||
|
|
||||||
# ------ IK STUFF ------
|
# ------ IK STUFF ------
|
||||||
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
|
add_custom_type("IK_LookAt", "Spatial", preload("ik_look_at.gd"), preload("ik_look_at.png"))
|
||||||
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
|
add_custom_type("IK_FABRIK", "Spatial", preload("ik_fabrik.gd"), preload("ik_fabrik.png"))
|
||||||
# ------ ---------- ------
|
# ------ ---------- ------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
# Plugin Clean-up here!
|
# Plugin Clean-up here!
|
||||||
|
|
||||||
# ------ IK STUFF ------
|
# ------ IK STUFF ------
|
||||||
remove_custom_type("IK_LookAt")
|
remove_custom_type("IK_LookAt")
|
||||||
remove_custom_type("IK_FABRIK")
|
remove_custom_type("IK_FABRIK")
|
||||||
# ------ ---------- ------
|
# ------ ---------- ------
|
||||||
|
|
||||||
|
|||||||
@@ -56,16 +56,16 @@ var simple_bullet = preload("res://simple_bullet.tscn")
|
|||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
|
||||||
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
|
camera = get_node("CameraHolder/Lean_Path/PathFollow/IK_LookAt_Chest/Camera")
|
||||||
camera_holder = get_node("CameraHolder")
|
camera_holder = get_node("CameraHolder")
|
||||||
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
|
path_follow_node = get_node("CameraHolder/Lean_Path/PathFollow")
|
||||||
|
|
||||||
anim_player = get_node("CameraHolder/AnimationPlayer")
|
anim_player = get_node("CameraHolder/AnimationPlayer")
|
||||||
anim_player.connect("animation_finished", self, "animation_finished")
|
anim_player.connect("animation_finished", self, "animation_finished")
|
||||||
|
|
||||||
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
|
pistol_end = get_node("CameraHolder/Weapon/Pistol/Pistol_end")
|
||||||
|
|
||||||
set_physics_process(true)
|
set_physics_process(true)
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
set_process_input(true)
|
set_process_input(true)
|
||||||
@@ -77,12 +77,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):
|
||||||
@@ -93,33 +93,33 @@ func process_input(delta):
|
|||||||
dir += -cam_xform.basis[0]
|
dir += -cam_xform.basis[0]
|
||||||
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
if Input.is_key_pressed(KEY_RIGHT) or Input.is_key_pressed(KEY_D):
|
||||||
dir += cam_xform.basis[0]
|
dir += cam_xform.basis[0]
|
||||||
|
|
||||||
if Input.is_action_just_pressed("ui_cancel"):
|
if Input.is_action_just_pressed("ui_cancel"):
|
||||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
else:
|
else:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
|
|
||||||
if Input.is_mouse_button_pressed(2):
|
if Input.is_mouse_button_pressed(2):
|
||||||
if right_mouse_down == false:
|
if right_mouse_down == false:
|
||||||
right_mouse_down = true
|
right_mouse_down = true
|
||||||
|
|
||||||
if anim_done == true:
|
if anim_done:
|
||||||
if current_anim != "Aiming":
|
if current_anim != "Aiming":
|
||||||
anim_player.play("Aiming")
|
anim_player.play("Aiming")
|
||||||
current_anim = "Aiming"
|
current_anim = "Aiming"
|
||||||
else:
|
else:
|
||||||
anim_player.play("Idle")
|
anim_player.play("Idle")
|
||||||
current_anim = "Idle"
|
current_anim = "Idle"
|
||||||
|
|
||||||
anim_done = false
|
anim_done = false
|
||||||
else:
|
else:
|
||||||
right_mouse_down = false
|
right_mouse_down = false
|
||||||
|
|
||||||
if Input.is_mouse_button_pressed(1):
|
if Input.is_mouse_button_pressed(1):
|
||||||
if left_mouse_timer <= 0:
|
if left_mouse_timer <= 0:
|
||||||
left_mouse_timer = LEFT_MOUSE_FIRE_TIME
|
left_mouse_timer = LEFT_MOUSE_FIRE_TIME
|
||||||
|
|
||||||
# Create a bullet
|
# Create a bullet
|
||||||
var new_bullet = simple_bullet.instance()
|
var new_bullet = simple_bullet.instance()
|
||||||
get_tree().root.add_child(new_bullet)
|
get_tree().root.add_child(new_bullet)
|
||||||
@@ -128,8 +128,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):
|
||||||
@@ -137,7 +137,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):
|
||||||
@@ -148,8 +148,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):
|
||||||
@@ -165,7 +165,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:
|
||||||
@@ -175,27 +175,27 @@ func process_input(delta):
|
|||||||
var lerp_value = (lean_value - 0.5) * 2
|
var lerp_value = (lean_value - 0.5) * 2
|
||||||
path_follow_node.rotation_degrees.z = (-20 * lerp_value)
|
path_follow_node.rotation_degrees.z = (-20 * lerp_value)
|
||||||
# ----------------------------------
|
# ----------------------------------
|
||||||
|
|
||||||
|
|
||||||
func process_movement(delta):
|
func process_movement(delta):
|
||||||
|
|
||||||
var grav = norm_grav
|
var grav = norm_grav
|
||||||
|
|
||||||
dir.y = 0
|
dir.y = 0
|
||||||
dir = dir.normalized()
|
dir = dir.normalized()
|
||||||
|
|
||||||
vel.y += delta*grav
|
vel.y += delta*grav
|
||||||
|
|
||||||
var hvel = vel
|
var hvel = vel
|
||||||
hvel.y = 0
|
hvel.y = 0
|
||||||
|
|
||||||
var target = dir
|
var target = dir
|
||||||
if is_sprinting:
|
if is_sprinting:
|
||||||
target *= MAX_SPRINT_SPEED
|
target *= MAX_SPRINT_SPEED
|
||||||
else:
|
else:
|
||||||
target *= MAX_SPEED
|
target *= MAX_SPEED
|
||||||
|
|
||||||
|
|
||||||
var accel
|
var accel
|
||||||
if dir.dot(hvel) > 0:
|
if dir.dot(hvel) > 0:
|
||||||
if is_sprinting == false:
|
if is_sprinting == false:
|
||||||
@@ -204,32 +204,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
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ func _ready():
|
|||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
|
var mouse_to_world = project_local_ray_normal(get_viewport().get_mouse_position()) * MOVEMENT_SPEED
|
||||||
|
|
||||||
if flip_axis == false:
|
if flip_axis == false:
|
||||||
mouse_to_world.z *= -1
|
mouse_to_world.z *= -1
|
||||||
else:
|
else:
|
||||||
mouse_to_world = -mouse_to_world
|
mouse_to_world = -mouse_to_world
|
||||||
|
|
||||||
targets.transform.origin = mouse_to_world
|
targets.transform.origin = mouse_to_world
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends KinematicBody
|
extends KinematicBody
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Camera
|
extends Camera
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ var hdrs=[
|
|||||||
]
|
]
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
for h in hdrs:
|
for h in hdrs:
|
||||||
get_node("ui/bg").add_item(h.name)
|
get_node("ui/bg").add_item(h.name)
|
||||||
|
|
||||||
func _unhandled_input(ev):
|
func _unhandled_input(ev):
|
||||||
@@ -36,9 +36,9 @@ func _unhandled_input(ev):
|
|||||||
if zoom > 0:
|
if zoom > 0:
|
||||||
zoom -= ZOOM_SPEED
|
zoom -= ZOOM_SPEED
|
||||||
get_node("camera/base/rotation/camera").translation.z = -zoom
|
get_node("camera/base/rotation/camera").translation.z = -zoom
|
||||||
|
|
||||||
if ev is InputEventMouseMotion and ev.button_mask & BUTTON_MASK_LEFT:
|
if ev is InputEventMouseMotion and ev.button_mask & BUTTON_MASK_LEFT:
|
||||||
rot_y += ev.relative.x * ROT_SPEED
|
rot_y += ev.relative.x * ROT_SPEED
|
||||||
rot_x += ev.relative.y * ROT_SPEED
|
rot_x += ev.relative.y * ROT_SPEED
|
||||||
rot_y = clamp(rot_y, -180, 180)
|
rot_y = clamp(rot_y, -180, 180)
|
||||||
rot_x = clamp(rot_x, 0, 150)
|
rot_x = clamp(rot_x, 0, 150)
|
||||||
@@ -46,8 +46,8 @@ func _unhandled_input(ev):
|
|||||||
t = t.rotated(Vector3(0, 0, 1), rot_x * PI / 180.0)
|
t = t.rotated(Vector3(0, 0, 1), rot_x * PI / 180.0)
|
||||||
t = t.rotated(Vector3(0, 1, 0), -rot_y * PI / 180.0)
|
t = t.rotated(Vector3(0, 1, 0), -rot_y * PI / 180.0)
|
||||||
get_node("camera/base").transform.basis = t.basis
|
get_node("camera/base").transform.basis = t.basis
|
||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
var xform = get_node("testers").get_child(tester_index).get_node("MeshInstance").global_transform
|
var xform = get_node("testers").get_child(tester_index).get_node("MeshInstance").global_transform
|
||||||
var p = xform.origin
|
var p = xform.origin
|
||||||
@@ -55,17 +55,17 @@ func _process(delta):
|
|||||||
var from_xform = get_node("camera").transform
|
var from_xform = get_node("camera").transform
|
||||||
var from_p = from_xform.origin
|
var from_p = from_xform.origin
|
||||||
var from_r = Quat(from_xform.basis)
|
var from_r = Quat(from_xform.basis)
|
||||||
|
|
||||||
p = from_p.linear_interpolate(p, INTERP_SPEED * delta)
|
p = from_p.linear_interpolate(p, INTERP_SPEED * delta)
|
||||||
r = from_r.slerp(r, INTERP_SPEED * delta)
|
r = from_r.slerp(r, INTERP_SPEED * delta)
|
||||||
|
|
||||||
var m = Transform(r)
|
var m = Transform(r)
|
||||||
m.origin = p
|
m.origin = p
|
||||||
|
|
||||||
get_node("camera").transform = m
|
get_node("camera").transform = m
|
||||||
get_node("ui/label").text = get_node("testers").get_child(tester_index).get_name()
|
get_node("ui/label").text = get_node("testers").get_child(tester_index).get_name()
|
||||||
|
|
||||||
|
|
||||||
func _on_prev_pressed():
|
func _on_prev_pressed():
|
||||||
if tester_index > 0:
|
if tester_index > 0:
|
||||||
tester_index -= 1
|
tester_index -= 1
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Navigation
|
extends Navigation
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
@@ -29,16 +28,16 @@ func _process(delta):
|
|||||||
else:
|
else:
|
||||||
path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk/d)
|
path[path.size() - 1] = pfrom.linear_interpolate(pto, to_walk/d)
|
||||||
to_walk = 0
|
to_walk = 0
|
||||||
|
|
||||||
var atpos = path[path.size() - 1]
|
var atpos = path[path.size() - 1]
|
||||||
var atdir = to_watch
|
var atdir = to_watch
|
||||||
atdir.y = 0
|
atdir.y = 0
|
||||||
|
|
||||||
var t = Transform()
|
var t = Transform()
|
||||||
t.origin = atpos
|
t.origin = atpos
|
||||||
t = t.looking_at(atpos + atdir, Vector3(0, 1, 0))
|
t = t.looking_at(atpos + atdir, Vector3(0, 1, 0))
|
||||||
get_node("robot_base").set_transform(t)
|
get_node("robot_base").set_transform(t)
|
||||||
|
|
||||||
if path.size() < 2:
|
if path.size() < 2:
|
||||||
path = []
|
path = []
|
||||||
set_process(false)
|
set_process(false)
|
||||||
@@ -72,12 +71,12 @@ func _input(event):
|
|||||||
var from = get_node("cambase/Camera").project_ray_origin(event.position)
|
var from = get_node("cambase/Camera").project_ray_origin(event.position)
|
||||||
var to = from + get_node("cambase/Camera").project_ray_normal(event.position)*100
|
var to = from + get_node("cambase/Camera").project_ray_normal(event.position)*100
|
||||||
var p = get_closest_point_to_segment(from, to)
|
var p = get_closest_point_to_segment(from, to)
|
||||||
|
|
||||||
begin = get_closest_point(get_node("robot_base").get_translation())
|
begin = get_closest_point(get_node("robot_base").get_translation())
|
||||||
end = p
|
end = p
|
||||||
|
|
||||||
_update_path()
|
_update_path()
|
||||||
|
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
if event.button_mask&(BUTTON_MASK_MIDDLE+BUTTON_MASK_RIGHT):
|
if event.button_mask&(BUTTON_MASK_MIDDLE+BUTTON_MASK_RIGHT):
|
||||||
camrot += event.relative.x * 0.005
|
camrot += event.relative.x * 0.005
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends RigidBody
|
extends RigidBody
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Area
|
extends Area
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends RigidBody
|
extends RigidBody
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
@@ -22,15 +21,15 @@ func _integrate_forces(state):
|
|||||||
|
|
||||||
lv += g * delta # Apply gravity
|
lv += g * delta # Apply gravity
|
||||||
var up = -g.normalized()
|
var up = -g.normalized()
|
||||||
|
|
||||||
if dying:
|
if dying:
|
||||||
state.set_linear_velocity(lv)
|
state.set_linear_velocity(lv)
|
||||||
return
|
return
|
||||||
|
|
||||||
for i in range(state.get_contact_count()):
|
for i in range(state.get_contact_count()):
|
||||||
var cc = state.get_contact_collider_object(i)
|
var cc = state.get_contact_collider_object(i)
|
||||||
var dp = state.get_contact_local_normal(i)
|
var dp = state.get_contact_local_normal(i)
|
||||||
|
|
||||||
if cc:
|
if cc:
|
||||||
if cc is preload("res://bullet.gd") and not cc.disabled:
|
if cc is preload("res://bullet.gd") and not cc.disabled:
|
||||||
set_mode(MODE_RIGID)
|
set_mode(MODE_RIGID)
|
||||||
@@ -43,15 +42,15 @@ func _integrate_forces(state):
|
|||||||
cc.disabled = true
|
cc.disabled = true
|
||||||
get_node("sound_hit").play()
|
get_node("sound_hit").play()
|
||||||
return
|
return
|
||||||
|
|
||||||
var col_floor = get_node("Armature/ray_floor").is_colliding()
|
var col_floor = get_node("Armature/ray_floor").is_colliding()
|
||||||
var col_wall = get_node("Armature/ray_wall").is_colliding()
|
var col_wall = get_node("Armature/ray_wall").is_colliding()
|
||||||
|
|
||||||
var advance = not col_wall and col_floor
|
var advance = not col_wall and col_floor
|
||||||
|
|
||||||
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 +58,17 @@ func _integrate_forces(state):
|
|||||||
else:
|
else:
|
||||||
if prev_advance:
|
if prev_advance:
|
||||||
rot_dir = 1 # randf()*2.0 - 1.0
|
rot_dir = 1 # randf()*2.0 - 1.0
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Camera
|
extends Camera
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends KinematicBody
|
extends KinematicBody
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
@@ -34,15 +33,15 @@ var shoot_blend = 0
|
|||||||
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
|
||||||
@@ -52,12 +51,12 @@ 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()
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
|
|
||||||
var lv = linear_velocity
|
var lv = linear_velocity
|
||||||
var g = Vector3(0, -9.8, 0)
|
var g = Vector3(0, -9.8, 0)
|
||||||
|
|
||||||
@@ -65,19 +64,19 @@ func _physics_process(delta):
|
|||||||
# if (d < 0):
|
# if (d < 0):
|
||||||
# d = 0
|
# d = 0
|
||||||
lv += g * delta # Apply gravity
|
lv += g * delta # Apply gravity
|
||||||
|
|
||||||
var anim = ANIM_FLOOR
|
var anim = ANIM_FLOOR
|
||||||
|
|
||||||
var up = -g.normalized() # (up is against gravity)
|
var up = -g.normalized() # (up is against gravity)
|
||||||
var vv = up.dot(lv) # Vertical velocity
|
var vv = up.dot(lv) # Vertical velocity
|
||||||
var hv = lv - up * vv # Horizontal velocity
|
var hv = lv - up * vv # 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
|
||||||
|
|
||||||
var dir = Vector3() # Where does the player intend to walk to
|
var dir = Vector3() # Where does the player intend to walk to
|
||||||
var cam_xform = get_node("target/camera").get_global_transform()
|
var cam_xform = get_node("target/camera").get_global_transform()
|
||||||
|
|
||||||
if Input.is_action_pressed("move_forward"):
|
if Input.is_action_pressed("move_forward"):
|
||||||
dir += -cam_xform.basis[2]
|
dir += -cam_xform.basis[2]
|
||||||
if Input.is_action_pressed("move_backwards"):
|
if Input.is_action_pressed("move_backwards"):
|
||||||
@@ -86,15 +85,15 @@ func _physics_process(delta):
|
|||||||
dir += -cam_xform.basis[0]
|
dir += -cam_xform.basis[0]
|
||||||
if Input.is_action_pressed("move_right"):
|
if Input.is_action_pressed("move_right"):
|
||||||
dir += cam_xform.basis[0]
|
dir += cam_xform.basis[0]
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
var target_dir = (dir - up * dir.dot(up)).normalized()
|
var target_dir = (dir - up * dir.dot(up)).normalized()
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
var sharp_turn = hspeed > 0.1 and rad2deg(acos(target_dir.dot(hdir))) > sharp_turn_threshold
|
var sharp_turn = hspeed > 0.1 and rad2deg(acos(target_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:
|
||||||
#linear_dir = linear_h_velocity/linear_vel
|
#linear_dir = linear_h_velocity/linear_vel
|
||||||
@@ -105,26 +104,26 @@ func _physics_process(delta):
|
|||||||
facing_dir = hdir
|
facing_dir = hdir
|
||||||
else:
|
else:
|
||||||
hdir = target_dir
|
hdir = target_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 - up * facing_mesh.dot(up)).normalized()
|
facing_mesh = (facing_mesh - up * facing_mesh.dot(up)).normalized()
|
||||||
|
|
||||||
if hspeed>0:
|
if hspeed>0:
|
||||||
facing_mesh = adjust_facing(facing_mesh, target_dir, delta, 1.0/hspeed*turn_speed, up)
|
facing_mesh = adjust_facing(facing_mesh, target_dir, delta, 1.0/hspeed*turn_speed, up)
|
||||||
var m3 = Basis(-facing_mesh, up, -facing_mesh.cross(up).normalized()).scaled(CHAR_SCALE)
|
var m3 = Basis(-facing_mesh, up, -facing_mesh.cross(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
|
||||||
@@ -134,7 +133,7 @@ func _physics_process(delta):
|
|||||||
anim = ANIM_AIR_UP
|
anim = ANIM_AIR_UP
|
||||||
else:
|
else:
|
||||||
anim = ANIM_AIR_DOWN
|
anim = ANIM_AIR_DOWN
|
||||||
|
|
||||||
var hs
|
var hs
|
||||||
if dir.length() > 0.1:
|
if dir.length() > 0.1:
|
||||||
hv += target_dir * (accel * 0.2) * delta
|
hv += target_dir * (accel * 0.2) * delta
|
||||||
@@ -146,22 +145,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
|
||||||
|
|
||||||
lv = hv + up*vv
|
lv = hv + up*vv
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
movement_dir = lv
|
movement_dir = lv
|
||||||
|
|
||||||
linear_velocity = move_and_slide(lv,-g.normalized())
|
linear_velocity = move_and_slide(lv,-g.normalized())
|
||||||
|
|
||||||
if shoot_blend > 0:
|
if shoot_blend > 0:
|
||||||
shoot_blend -= delta * SHOOT_SCALE
|
shoot_blend -= delta * SHOOT_SCALE
|
||||||
if (shoot_blend < 0):
|
if (shoot_blend < 0):
|
||||||
shoot_blend = 0
|
shoot_blend = 0
|
||||||
|
|
||||||
if shoot_attempt and not prev_shoot:
|
if shoot_attempt and not prev_shoot:
|
||||||
shoot_blend = SHOOT_TIME
|
shoot_blend = SHOOT_TIME
|
||||||
var bullet = preload("res://bullet.scn").instance()
|
var bullet = preload("res://bullet.scn").instance()
|
||||||
@@ -170,12 +169,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("sound_shoot").play()
|
get_node("sound_shoot").play()
|
||||||
|
|
||||||
prev_shoot = shoot_attempt
|
prev_shoot = shoot_attempt
|
||||||
|
|
||||||
if is_on_floor():
|
if is_on_floor():
|
||||||
get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
|
get_node("AnimationTreePlayer").blend2_node_set_amount("walk", hspeed / max_speed)
|
||||||
|
|
||||||
get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
|
get_node("AnimationTreePlayer").transition_node_set_current("state", anim)
|
||||||
get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
|
get_node("AnimationTreePlayer").blend2_node_set_amount("gun", min(shoot_blend, 1.0))
|
||||||
# state.set_angular_velocity(Vector3())
|
# state.set_angular_velocity(Vector3())
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Camera
|
extends Camera
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
@@ -16,27 +15,27 @@ func _physics_process(dt):
|
|||||||
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 up = Vector3(0, 1, 0)
|
var up = Vector3(0, 1, 0)
|
||||||
|
|
||||||
var delta = pos - target
|
var delta = pos - target
|
||||||
|
|
||||||
# Regular delta follow
|
# Regular delta follow
|
||||||
|
|
||||||
# Check ranges
|
# Check ranges
|
||||||
if (delta.length() < min_distance):
|
if (delta.length() < min_distance):
|
||||||
delta = delta.normalized()*min_distance
|
delta = delta.normalized()*min_distance
|
||||||
elif (delta.length() > max_distance):
|
elif (delta.length() > max_distance):
|
||||||
delta = delta.normalized()*max_distance
|
delta = delta.normalized()*max_distance
|
||||||
|
|
||||||
# Check upper and lower height
|
# Check upper and lower height
|
||||||
if ( delta.y > max_height):
|
if ( delta.y > max_height):
|
||||||
delta.y = max_height
|
delta.y = max_height
|
||||||
if ( delta.y < min_height):
|
if ( delta.y < min_height):
|
||||||
delta.y = min_height
|
delta.y = min_height
|
||||||
|
|
||||||
pos = target + delta
|
pos = target + delta
|
||||||
|
|
||||||
look_at_from_position(pos, target, up)
|
look_at_from_position(pos, target, 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
|
||||||
@@ -52,6 +51,6 @@ 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)
|
||||||
|
|||||||
@@ -16,17 +16,17 @@ func _physics_process(delta):
|
|||||||
steer_target = -STEER_LIMIT
|
steer_target = -STEER_LIMIT
|
||||||
else:
|
else:
|
||||||
steer_target = 0
|
steer_target = 0
|
||||||
|
|
||||||
if Input.is_action_pressed("ui_up"):
|
if Input.is_action_pressed("ui_up"):
|
||||||
engine_force = engine_force_value
|
engine_force = engine_force_value
|
||||||
else:
|
else:
|
||||||
engine_force = 0
|
engine_force = 0
|
||||||
|
|
||||||
if Input.is_action_pressed("ui_down"):
|
if Input.is_action_pressed("ui_down"):
|
||||||
brake = 1
|
brake = 1
|
||||||
else:
|
else:
|
||||||
brake = 0.0
|
brake = 0.0
|
||||||
|
|
||||||
if steer_target < steer_angle:
|
if steer_target < steer_angle:
|
||||||
steer_angle -= STEER_SPEED * delta
|
steer_angle -= STEER_SPEED * delta
|
||||||
if steer_target > steer_angle:
|
if steer_target > steer_angle:
|
||||||
@@ -35,5 +35,5 @@ func _physics_process(delta):
|
|||||||
steer_angle += STEER_SPEED * delta
|
steer_angle += STEER_SPEED * delta
|
||||||
if steer_target < steer_angle:
|
if steer_target < steer_angle:
|
||||||
steer_angle = steer_target
|
steer_angle = steer_target
|
||||||
|
|
||||||
steering = steer_angle
|
steering = steer_angle
|
||||||
|
|||||||
21
README.md
21
README.md
@@ -8,23 +8,10 @@ be used with [Godot Engine](https://godotengine.org), the open source
|
|||||||
|
|
||||||
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with Godot's `master` development branch (next 4.x release).
|
- The [`master`](https://github.com/godotengine/godot-demo-projects) branch is compatible with Godot's `master` development branch (next 4.x release).
|
||||||
- The [`3.x`](https://github.com/godotengine/godot-demo-projects/tree/3.x) branch is compatible with Godot's `3.x` development branch (next 3.x release).
|
- The [`3.x`](https://github.com/godotengine/godot-demo-projects/tree/3.x) branch is compatible with Godot's `3.x` development branch (next 3.x release).
|
||||||
- The other branches are compatible with the matching stable versions of Godot:
|
- The other branches are compatible with the matching stable versions of Godot.
|
||||||
- [`4.0`](https://github.com/godotengine/godot-demo-projects/tree/4.0)
|
- [Click here](https://github.com/godotengine/godot-demo-projects/branches) to see all branches.
|
||||||
branch for Godot 4.0.x.
|
- For example, the [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1)
|
||||||
- [`3.5`](https://github.com/godotengine/godot-demo-projects/tree/3.5)
|
branch is for demos compatible with Godot 2.1.x.
|
||||||
branch for Godot 3.5.x.
|
|
||||||
- [`3.4`](https://github.com/godotengine/godot-demo-projects/tree/3.4)
|
|
||||||
branch for Godot 3.4.x.
|
|
||||||
- [`3.3`](https://github.com/godotengine/godot-demo-projects/tree/3.3)
|
|
||||||
branch for Godot 3.3.x.
|
|
||||||
- [`3.2`](https://github.com/godotengine/godot-demo-projects/tree/3.2)
|
|
||||||
branch for Godot 3.2.x.
|
|
||||||
- [`3.1`](https://github.com/godotengine/godot-demo-projects/tree/3.1)
|
|
||||||
branch for Godot 3.1.x.
|
|
||||||
- [***`3.0`***](https://github.com/godotengine/godot-demo-projects/tree/3.0)
|
|
||||||
branch for Godot 3.0.x.
|
|
||||||
- [`2.1`](https://github.com/godotengine/godot-demo-projects/tree/2.1)
|
|
||||||
branch for Godot 2.1.x.
|
|
||||||
|
|
||||||
## Importing all demos
|
## Importing all demos
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=4
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
55
file_format.sh
Executable file
55
file_format.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This script ensures proper POSIX text file formatting and a few other things.
|
||||||
|
|
||||||
|
set -uo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
# Loops through all text files tracked by Git.
|
||||||
|
git grep -zIl '' |
|
||||||
|
while IFS= read -rd '' f; do
|
||||||
|
# Exclude some types of files.
|
||||||
|
if [[ "$f" == *"csproj" ]]; then
|
||||||
|
continue
|
||||||
|
elif [[ "$f" == *"hdr" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Ensure that files are UTF-8 formatted.
|
||||||
|
recode UTF-8 "$f" 2> /dev/null
|
||||||
|
# Ensure that files have LF line endings and do not contain a BOM.
|
||||||
|
dos2unix "$f" 2> /dev/null
|
||||||
|
# Remove trailing space characters and ensures that files end
|
||||||
|
# with newline characters. -l option handles newlines conveniently.
|
||||||
|
perl -i -ple 's/\s*$//g' "$f"
|
||||||
|
# Remove the character sequence "== true" if it has a leading space.
|
||||||
|
perl -i -pe 's/\x20== true//g' "$f"
|
||||||
|
# We don't want to change lines around braces in godot/tscn files.
|
||||||
|
if [[ "$f" == *"godot" ]]; then
|
||||||
|
continue
|
||||||
|
elif [[ "$f" == *"tscn" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
# Disallow empty lines after the opening brace.
|
||||||
|
sed -z -i 's/\x7B\x0A\x0A/\x7B\x0A/g' "$f"
|
||||||
|
# Disallow some empty lines before the closing brace.
|
||||||
|
sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
git diff > patch.patch
|
||||||
|
FILESIZE="$(stat -c%s patch.patch)"
|
||||||
|
MAXSIZE=5
|
||||||
|
|
||||||
|
# If no patch has been generated all is OK, clean up, and exit.
|
||||||
|
if (( FILESIZE < MAXSIZE )); then
|
||||||
|
printf "Files in this commit comply with the formatting rules.\n"
|
||||||
|
rm -f patch.patch
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# A patch has been created, notify the user, clean up, and exit.
|
||||||
|
printf "\n*** The following differences were found between the code "
|
||||||
|
printf "and the formatting rules:\n\n"
|
||||||
|
cat patch.patch
|
||||||
|
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||||
|
rm -f patch.patch
|
||||||
|
exit 1
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends ColorPickerButton
|
extends ColorPickerButton
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -99,6 +99,6 @@ func _ready():
|
|||||||
var button = get_node("bindings").get_node(action).get_node("Button")
|
var button = get_node("bindings").get_node(action).get_node("Button")
|
||||||
button.text = OS.get_scancode_string(input_event.scancode)
|
button.text = OS.get_scancode_string(input_event.scancode)
|
||||||
button.connect("pressed", self, "wait_for_input", [action])
|
button.connect("pressed", self, "wait_for_input", [action])
|
||||||
|
|
||||||
# Do not start processing input until a button is pressed
|
# Do not start processing input until a button is pressed
|
||||||
set_process_input(false)
|
set_process_input(false)
|
||||||
|
|||||||
@@ -152,4 +152,4 @@ TERMINATION
|
|||||||
This license becomes null and void if any of the above conditions are not met.
|
This license becomes null and void if any of the above conditions are not met.
|
||||||
|
|
||||||
DISCLAIMER
|
DISCLAIMER
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Panel
|
extends Panel
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ Copyright (C) 2008 The Android Open Source Project
|
|||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Panel
|
extends Panel
|
||||||
|
|
||||||
func _on_back_pressed():
|
func _on_back_pressed():
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Panel
|
extends Panel
|
||||||
|
|
||||||
func _on_english_pressed():
|
func _on_english_pressed():
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
,en,es,ja
|
,en,es,ja
|
||||||
KEY_HELLO,Hello!,Hola!,こんにちは
|
KEY_HELLO,Hello!,Hola!,こんにちは
|
||||||
KEY_PUSH,Push Me!,Aprétame!,押す
|
KEY_PUSH,Push Me!,Aprétame!,押す
|
||||||
|
|||||||
|
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
signal purchase_success(item_name)
|
signal purchase_success(item_name)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
onready var alert = get_node("alert")
|
onready var alert = get_node("alert")
|
||||||
@@ -13,7 +12,7 @@ func _ready():
|
|||||||
iap.connect("consume_success", self, "on_consume_success")
|
iap.connect("consume_success", self, "on_consume_success")
|
||||||
iap.connect("consume_fail", self, "on_consume_fail")
|
iap.connect("consume_fail", self, "on_consume_fail")
|
||||||
iap.connect("sku_details_complete", self, "on_sku_details_complete")
|
iap.connect("sku_details_complete", self, "on_sku_details_complete")
|
||||||
|
|
||||||
get_node("purchase").connect("pressed", self, "button_purchase")
|
get_node("purchase").connect("pressed", self, "button_purchase")
|
||||||
get_node("consume").connect("pressed", self, "button_consume")
|
get_node("consume").connect("pressed", self, "button_consume")
|
||||||
get_node("request").connect("pressed", self, "button_request")
|
get_node("request").connect("pressed", self, "button_request")
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
# Below are a number of helper functions that show how you can use the raw sensor data to determine the orientation
|
# Below are a number of helper functions that show how you can use the raw sensor data to determine the orientation
|
||||||
# of your phone/device. The cheapest phones only have an accelerometer only the most expensive phones have all three.
|
# of your phone/device. The cheapest phones only have an accelerometer only the most expensive phones have all three.
|
||||||
# Note that none of this logic filters data. Filters introduce lag but also provide stability. There are plenty
|
# Note that none of this logic filters data. Filters introduce lag but also provide stability. There are plenty
|
||||||
# of examples on the internet on how to implement these. I wanted to keep this straight forward.
|
# of examples on the internet on how to implement these. I wanted to keep this straight forward.
|
||||||
|
|
||||||
# We draw a few arrow objects to visualize the vectors and two cubes to show two implementation for orientating
|
# We draw a few arrow objects to visualize the vectors and two cubes to show two implementation for orientating
|
||||||
# these cubes to our phones orientation.
|
# these cubes to our phones orientation.
|
||||||
# This is a 3D example however reading the phones orientation is also invaluable for 2D
|
# This is a 3D example however reading the phones orientation is also invaluable for 2D
|
||||||
|
|
||||||
@@ -13,52 +13,52 @@ extends Node
|
|||||||
# care about the rotation around this axis.
|
# care about the rotation around this axis.
|
||||||
func get_basis_for_arrow(p_vector):
|
func get_basis_for_arrow(p_vector):
|
||||||
var rotate = Basis()
|
var rotate = Basis()
|
||||||
|
|
||||||
# as our arrow points up, Y = our direction vector
|
# as our arrow points up, Y = our direction vector
|
||||||
rotate.y = p_vector.normalized()
|
rotate.y = p_vector.normalized()
|
||||||
|
|
||||||
# get an arbitrary vector we can use to calculate our other two vectors
|
# get an arbitrary vector we can use to calculate our other two vectors
|
||||||
var v = Vector3(1.0, 0.0, 0.0)
|
var v = Vector3(1.0, 0.0, 0.0)
|
||||||
if abs(v.dot(rotate.y)) > 0.9:
|
if abs(v.dot(rotate.y)) > 0.9:
|
||||||
v = Vector3(0.0, 1.0, 0.0)
|
v = Vector3(0.0, 1.0, 0.0)
|
||||||
|
|
||||||
# use our vector to get a vector perpendicular to our two vectors
|
# use our vector to get a vector perpendicular to our two vectors
|
||||||
rotate.x = rotate.y.cross(v).normalized()
|
rotate.x = rotate.y.cross(v).normalized()
|
||||||
|
|
||||||
# and the cross product again gives us our final vector perpendicular to our previous two vectors
|
# and the cross product again gives us our final vector perpendicular to our previous two vectors
|
||||||
rotate.z = rotate.x.cross(rotate.y).normalized()
|
rotate.z = rotate.x.cross(rotate.y).normalized()
|
||||||
|
|
||||||
return rotate
|
return rotate
|
||||||
|
|
||||||
# This function combines the magnetometer reading with the gravity vector to get a vector that points due north
|
# This function combines the magnetometer reading with the gravity vector to get a vector that points due north
|
||||||
func calc_north(p_grav, p_mag):
|
func calc_north(p_grav, p_mag):
|
||||||
# Always use normalized vectors!
|
# Always use normalized vectors!
|
||||||
p_grav = p_grav.normalized()
|
p_grav = p_grav.normalized()
|
||||||
|
|
||||||
# Calculate east (or is it west) by getting our cross product.
|
# Calculate east (or is it west) by getting our cross product.
|
||||||
# The cross product of two normalized vectors returns a vector that
|
# The cross product of two normalized vectors returns a vector that
|
||||||
# is perpendicular to our two vectors
|
# is perpendicular to our two vectors
|
||||||
var east = p_grav.cross(p_mag.normalized()).normalized()
|
var east = p_grav.cross(p_mag.normalized()).normalized()
|
||||||
|
|
||||||
# Cross again to get our horizon aligned north
|
# Cross again to get our horizon aligned north
|
||||||
return east.cross(p_grav).normalized()
|
return east.cross(p_grav).normalized()
|
||||||
|
|
||||||
# This function creates an orientation matrix using the magnetometer and gravity vector as inputs.
|
# This function creates an orientation matrix using the magnetometer and gravity vector as inputs.
|
||||||
func orientate_by_mag_and_grav(p_mag, p_grav):
|
func orientate_by_mag_and_grav(p_mag, p_grav):
|
||||||
var rotate = Basis()
|
var rotate = Basis()
|
||||||
|
|
||||||
# as always, normalize!
|
# as always, normalize!
|
||||||
p_mag = p_mag.normalized()
|
p_mag = p_mag.normalized()
|
||||||
|
|
||||||
# gravity points down, so - gravity points up!
|
# gravity points down, so - gravity points up!
|
||||||
rotate.y = -p_grav.normalized()
|
rotate.y = -p_grav.normalized()
|
||||||
|
|
||||||
# Cross products with our magnetic north gives an aligned east (or west, I always forget)
|
# Cross products with our magnetic north gives an aligned east (or west, I always forget)
|
||||||
rotate.x = rotate.y.cross(p_mag)
|
rotate.x = rotate.y.cross(p_mag)
|
||||||
|
|
||||||
# And cross product again and we get our aligned north completing our matrix
|
# And cross product again and we get our aligned north completing our matrix
|
||||||
rotate.z = rotate.x.cross(rotate.y)
|
rotate.z = rotate.x.cross(rotate.y)
|
||||||
|
|
||||||
return rotate
|
return rotate
|
||||||
|
|
||||||
# This function takes our gyro input and update an orientation matrix accordingly
|
# This function takes our gyro input and update an orientation matrix accordingly
|
||||||
@@ -66,28 +66,28 @@ func orientate_by_mag_and_grav(p_mag, p_grav):
|
|||||||
# rotational velocity. This is why we multiply our values with delta.
|
# rotational velocity. This is why we multiply our values with delta.
|
||||||
func rotate_by_gyro(p_gyro, p_basis, p_delta):
|
func rotate_by_gyro(p_gyro, p_basis, p_delta):
|
||||||
var rotate = Basis()
|
var rotate = Basis()
|
||||||
|
|
||||||
rotate = rotate.rotated(p_basis.x, -p_gyro.x * p_delta)
|
rotate = rotate.rotated(p_basis.x, -p_gyro.x * p_delta)
|
||||||
rotate = rotate.rotated(p_basis.y, -p_gyro.y * p_delta)
|
rotate = rotate.rotated(p_basis.y, -p_gyro.y * p_delta)
|
||||||
rotate = rotate.rotated(p_basis.z, -p_gyro.z * p_delta)
|
rotate = rotate.rotated(p_basis.z, -p_gyro.z * p_delta)
|
||||||
|
|
||||||
return rotate * p_basis
|
return rotate * p_basis
|
||||||
|
|
||||||
# This function corrects the drift in our matrix by our gravity vector
|
# This function corrects the drift in our matrix by our gravity vector
|
||||||
func drift_correction(p_basis, p_grav):
|
func drift_correction(p_basis, p_grav):
|
||||||
# as always, make sure our vector is normalized but also invert as our gravity points down
|
# as always, make sure our vector is normalized but also invert as our gravity points down
|
||||||
var real_up = -p_grav.normalized()
|
var real_up = -p_grav.normalized()
|
||||||
|
|
||||||
# start by calculating the dot product, this gives us the cosine angle between our two vectors
|
# start by calculating the dot product, this gives us the cosine angle between our two vectors
|
||||||
var dot = p_basis.y.dot(real_up)
|
var dot = p_basis.y.dot(real_up)
|
||||||
|
|
||||||
# if our dot is 1.0 we're good
|
# if our dot is 1.0 we're good
|
||||||
if dot < 1.0:
|
if dot < 1.0:
|
||||||
# the cross between our two vectors gives us a vector perpendicular to our two vectors
|
# the cross between our two vectors gives us a vector perpendicular to our two vectors
|
||||||
var axis = p_basis.y.cross(real_up).normalized()
|
var axis = p_basis.y.cross(real_up).normalized()
|
||||||
var correction = Basis(axis, acos(dot))
|
var correction = Basis(axis, acos(dot))
|
||||||
p_basis = correction * p_basis
|
p_basis = correction * p_basis
|
||||||
|
|
||||||
return p_basis
|
return p_basis
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
@@ -96,12 +96,12 @@ func _process(delta):
|
|||||||
var grav = Input.get_gravity()
|
var grav = Input.get_gravity()
|
||||||
var mag = Input.get_magnetometer()
|
var mag = Input.get_magnetometer()
|
||||||
var gyro = Input.get_gyroscope()
|
var gyro = Input.get_gyroscope()
|
||||||
|
|
||||||
# Show our base values
|
# Show our base values
|
||||||
get_node("Control/Accelerometer").text = 'Accelerometer: ' + str(acc) + ', gravity: ' + str(grav)
|
get_node("Control/Accelerometer").text = 'Accelerometer: ' + str(acc) + ', gravity: ' + str(grav)
|
||||||
get_node("Control/Magnetometer").text = 'Magnetometer: ' + str(mag)
|
get_node("Control/Magnetometer").text = 'Magnetometer: ' + str(mag)
|
||||||
get_node("Control/Gyroscope").text = 'Gyroscope: ' + str(gyro)
|
get_node("Control/Gyroscope").text = 'Gyroscope: ' + str(gyro)
|
||||||
|
|
||||||
# Check if we have all needed data
|
# Check if we have all needed data
|
||||||
if grav.length() < 0.1:
|
if grav.length() < 0.1:
|
||||||
if acc.length() < 0.1:
|
if acc.length() < 0.1:
|
||||||
@@ -110,31 +110,31 @@ func _process(delta):
|
|||||||
else:
|
else:
|
||||||
# The gravity vector is calculated by the OS by combining the other sensor inputs.
|
# The gravity vector is calculated by the OS by combining the other sensor inputs.
|
||||||
# If we don't have a gravity vector, from now on, use accelerometer...
|
# If we don't have a gravity vector, from now on, use accelerometer...
|
||||||
grav = acc
|
grav = acc
|
||||||
|
|
||||||
if mag.length() < 0.1:
|
if mag.length() < 0.1:
|
||||||
mag = Vector3(1.0, 0.0, 0.0)
|
mag = Vector3(1.0, 0.0, 0.0)
|
||||||
|
|
||||||
# Update our arrow showing gravity
|
# Update our arrow showing gravity
|
||||||
get_node("Arrows/AccelerometerArrow").transform.basis = get_basis_for_arrow(grav)
|
get_node("Arrows/AccelerometerArrow").transform.basis = get_basis_for_arrow(grav)
|
||||||
|
|
||||||
# Update our arrow showing our magnetometer
|
# Update our arrow showing our magnetometer
|
||||||
# Note that in absense of other strong magnetic forces this will point to magnetic north, which is not horizontal thanks to the earth being, uhm, round
|
# Note that in absense of other strong magnetic forces this will point to magnetic north, which is not horizontal thanks to the earth being, uhm, round
|
||||||
get_node("Arrows/MagnetoArrow").transform.basis = get_basis_for_arrow(mag)
|
get_node("Arrows/MagnetoArrow").transform.basis = get_basis_for_arrow(mag)
|
||||||
|
|
||||||
# Calculate our north vector and show that
|
# Calculate our north vector and show that
|
||||||
var north = calc_north(grav,mag)
|
var north = calc_north(grav,mag)
|
||||||
get_node("Arrows/NorthArrow").transform.basis = get_basis_for_arrow(north)
|
get_node("Arrows/NorthArrow").transform.basis = get_basis_for_arrow(north)
|
||||||
|
|
||||||
# Combine our magnetometer and gravity vector to position our box. This will be fairly accurate
|
# Combine our magnetometer and gravity vector to position our box. This will be fairly accurate
|
||||||
# but our magnetometer can be easily influenced by magnets. Cheaper phones often don't have gyros
|
# but our magnetometer can be easily influenced by magnets. Cheaper phones often don't have gyros
|
||||||
# so it is a good backup.
|
# so it is a good backup.
|
||||||
var mag_and_grav = get_node("Boxes/MagAndGrav")
|
var mag_and_grav = get_node("Boxes/MagAndGrav")
|
||||||
mag_and_grav.transform.basis = orientate_by_mag_and_grav(mag, grav).orthonormalized()
|
mag_and_grav.transform.basis = orientate_by_mag_and_grav(mag, grav).orthonormalized()
|
||||||
|
|
||||||
# Using our gyro and do a drift correction using our gravity vector gives the best result
|
# Using our gyro and do a drift correction using our gravity vector gives the best result
|
||||||
var gyro_and_grav = get_node("Boxes/GyroAndGrav")
|
var gyro_and_grav = get_node("Boxes/GyroAndGrav")
|
||||||
var new_basis = rotate_by_gyro(gyro, gyro_and_grav.transform.basis, delta).orthonormalized()
|
var new_basis = rotate_by_gyro(gyro, gyro_and_grav.transform.basis, delta).orthonormalized()
|
||||||
gyro_and_grav.transform.basis = drift_correction(new_basis, grav)
|
gyro_and_grav.transform.basis = drift_correction(new_basis, grav)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
|
|||||||
@@ -44,4 +44,4 @@ public class HUD : CanvasLayer
|
|||||||
{
|
{
|
||||||
GetNode<Label>("MessageLabel").Hide();
|
GetNode<Label>("MessageLabel").Hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,4 @@ public class Mob : RigidBody2D
|
|||||||
{
|
{
|
||||||
QueueFree();
|
QueueFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class Player : Area2D
|
|||||||
animatedSprite.FlipH = velocity.x < 0;
|
animatedSprite.FlipH = velocity.x < 0;
|
||||||
animatedSprite.FlipV = false;
|
animatedSprite.FlipV = false;
|
||||||
}
|
}
|
||||||
else if(velocity.y != 0)
|
else if(velocity.y != 0)
|
||||||
{
|
{
|
||||||
animatedSprite.Animation = "up";
|
animatedSprite.Animation = "up";
|
||||||
animatedSprite.FlipV = velocity.y > 0;
|
animatedSprite.FlipV = velocity.y > 0;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ config_version=3
|
|||||||
|
|
||||||
_global_script_classes=[ ]
|
_global_script_classes=[ ]
|
||||||
_global_script_class_icons={
|
_global_script_class_icons={
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|||||||
@@ -24,25 +24,25 @@ sync func stop():
|
|||||||
stopped = true
|
stopped = true
|
||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
# ball will move normally for both players
|
# ball will move normally for both players
|
||||||
# even if it's sightly out of sync between them
|
# even if it's sightly out of sync between them
|
||||||
# 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( direction * ball_speed * delta )
|
translate( direction * ball_speed * delta )
|
||||||
|
|
||||||
# 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
|
||||||
# otherwise ball might be out in the other player's screen but not this one
|
# otherwise ball might be out in the other player's screen but not this one
|
||||||
|
|
||||||
if ball_pos.x < 0:
|
if ball_pos.x < 0:
|
||||||
get_parent().rpc("update_score", false)
|
get_parent().rpc("update_score", false)
|
||||||
rpc("_reset_ball", false)
|
rpc("_reset_ball", false)
|
||||||
@@ -50,19 +50,19 @@ func _process(delta):
|
|||||||
# only the slave will decide when the ball is out in the right side (it's own side)
|
# only the slave will decide when the ball is out in the right 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
|
||||||
# otherwise ball might be out in the other player's screen but not this one
|
# otherwise ball might be out in the other player's screen but not this one
|
||||||
|
|
||||||
if ball_pos.x > screen_size.x:
|
if ball_pos.x > screen_size.x:
|
||||||
get_parent().rpc("update_score", true)
|
get_parent().rpc("update_score", true)
|
||||||
rpc("_reset_ball", true)
|
rpc("_reset_ball", true)
|
||||||
|
|
||||||
|
|
||||||
sync func bounce(left, random):
|
sync func bounce(left, random):
|
||||||
#using sync because both players can make it bounce
|
#using sync because both players can make it bounce
|
||||||
if left:
|
if left:
|
||||||
direction.x = abs(direction.x)
|
direction.x = abs(direction.x)
|
||||||
else:
|
else:
|
||||||
direction.x = -abs(direction.x)
|
direction.x = -abs(direction.x)
|
||||||
|
|
||||||
ball_speed *= 1.1
|
ball_speed *= 1.1
|
||||||
direction.y = random * 2.0 - 1
|
direction.y = random * 2.0 - 1
|
||||||
direction = direction.normalized()
|
direction = direction.normalized()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ func _player_connected(id):
|
|||||||
#someone connected, start the game!
|
#someone connected, start the game!
|
||||||
var pong = load("res://pong.tscn").instance()
|
var pong = load("res://pong.tscn").instance()
|
||||||
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED) # connect deferred so we can safely erase it from the callback
|
pong.connect("game_finished", self, "_end_game", [], CONNECT_DEFERRED) # connect deferred so we can safely erase it from the callback
|
||||||
|
|
||||||
get_tree().get_root().add_child(pong)
|
get_tree().get_root().add_child(pong)
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
@@ -24,20 +24,20 @@ func _player_disconnected(id):
|
|||||||
func _connected_ok():
|
func _connected_ok():
|
||||||
# will not use this one
|
# will not use this one
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
get_node("panel/join").set_disabled(false)
|
get_node("panel/join").set_disabled(false)
|
||||||
get_node("panel/host").set_disabled(false)
|
get_node("panel/host").set_disabled(false)
|
||||||
|
|
||||||
func _server_disconnected():
|
func _server_disconnected():
|
||||||
_end_game("Server disconnected")
|
_end_game("Server disconnected")
|
||||||
|
|
||||||
##### Game creation functions ######
|
##### Game creation functions ######
|
||||||
|
|
||||||
func _end_game(with_error=""):
|
func _end_game(with_error=""):
|
||||||
@@ -45,16 +45,16 @@ func _end_game(with_error=""):
|
|||||||
#erase pong scene
|
#erase pong scene
|
||||||
get_node("/root/pong").free() # erase immediately, otherwise network might show errors (this is why we connected deferred above)
|
get_node("/root/pong").free() # erase immediately, otherwise network might show errors (this is why we connected deferred above)
|
||||||
show()
|
show()
|
||||||
|
|
||||||
get_tree().set_network_peer(null) #remove peer
|
get_tree().set_network_peer(null) #remove peer
|
||||||
|
|
||||||
get_node("panel/join").set_disabled(false)
|
get_node("panel/join").set_disabled(false)
|
||||||
get_node("panel/host").set_disabled(false)
|
get_node("panel/host").set_disabled(false)
|
||||||
|
|
||||||
_set_status(with_error, false)
|
_set_status(with_error, false)
|
||||||
|
|
||||||
func _set_status(text, isok):
|
func _set_status(text, isok):
|
||||||
#simple way to show status
|
#simple way to show status
|
||||||
if isok:
|
if isok:
|
||||||
get_node("panel/status_ok").set_text(text)
|
get_node("panel/status_ok").set_text(text)
|
||||||
get_node("panel/status_fail").set_text("")
|
get_node("panel/status_fail").set_text("")
|
||||||
@@ -70,7 +70,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(host)
|
get_tree().set_network_peer(host)
|
||||||
get_node("panel/join").set_disabled(true)
|
get_node("panel/join").set_disabled(true)
|
||||||
get_node("panel/host").set_disabled(true)
|
get_node("panel/host").set_disabled(true)
|
||||||
@@ -81,17 +81,17 @@ 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
|
||||||
|
|
||||||
var host = NetworkedMultiplayerENet.new()
|
var host = NetworkedMultiplayerENet.new()
|
||||||
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
host.set_compression_mode(NetworkedMultiplayerENet.COMPRESS_RANGE_CODER)
|
||||||
host.create_client(ip, DEFAULT_PORT)
|
host.create_client(ip, DEFAULT_PORT)
|
||||||
get_tree().set_network_peer(host)
|
get_tree().set_network_peer(host)
|
||||||
|
|
||||||
_set_status("Connecting..", true)
|
_set_status("Connecting..", true)
|
||||||
|
|
||||||
|
|
||||||
### INITIALIZER ####
|
### INITIALIZER ####
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# connect all the callbacks related to networking
|
# connect all the callbacks related to networking
|
||||||
get_tree().connect("network_peer_connected", self, "_player_connected")
|
get_tree().connect("network_peer_connected", self, "_player_connected")
|
||||||
@@ -99,4 +99,4 @@ func _ready():
|
|||||||
get_tree().connect("connected_to_server", self, "_connected_ok")
|
get_tree().connect("connected_to_server", self, "_connected_ok")
|
||||||
get_tree().connect("connection_failed", self, "_connected_fail")
|
get_tree().connect("connection_failed", self, "_connected_fail")
|
||||||
get_tree().connect("server_disconnected", self, "_server_disconnected")
|
get_tree().connect("server_disconnected", self, "_server_disconnected")
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ func _hide_you_label():
|
|||||||
get_node("you").hide()
|
get_node("you").hide()
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
#is the master of the paddle
|
#is the master of the paddle
|
||||||
if is_network_master():
|
if is_network_master():
|
||||||
motion = 0
|
motion = 0
|
||||||
if Input.is_action_pressed("move_up"):
|
if Input.is_action_pressed("move_up"):
|
||||||
motion -= 1
|
motion -= 1
|
||||||
@@ -29,27 +29,27 @@ func _process(delta):
|
|||||||
|
|
||||||
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 as possible, even if one of the calls is dropped
|
#using unreliable to make sure position is updated as fast 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
|
||||||
var pos = position
|
var pos = position
|
||||||
|
|
||||||
if pos.y < 0:
|
if pos.y < 0:
|
||||||
position = Vector2(pos.x, 0)
|
position = Vector2(pos.x, 0)
|
||||||
elif pos.y > screen_size.y:
|
elif pos.y > screen_size.y:
|
||||||
position = Vector2(pos.x, screen_size.y)
|
position = Vector2(pos.x, screen_size.y)
|
||||||
|
|
||||||
|
|
||||||
func _on_paddle_area_enter( area ):
|
func _on_paddle_area_enter( area ):
|
||||||
if is_network_master():
|
if is_network_master():
|
||||||
area.rpc("bounce", left, randf()) #random for new direction generated on each peer
|
area.rpc("bounce", left, randf()) #random for new direction generated on each peer
|
||||||
|
|||||||
@@ -12,36 +12,36 @@ sync func update_score(add_to_left):
|
|||||||
score_left += 1
|
score_left += 1
|
||||||
get_node("score_left").set_text(str(score_left))
|
get_node("score_left").set_text(str(score_left))
|
||||||
else:
|
else:
|
||||||
|
|
||||||
score_right += 1
|
score_right += 1
|
||||||
get_node("score_right").set_text(str(score_right))
|
get_node("score_right").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:
|
||||||
get_node("winner_left").show()
|
get_node("winner_left").show()
|
||||||
game_ended = true
|
game_ended = true
|
||||||
elif score_right == SCORE_TO_WIN:
|
elif score_right == SCORE_TO_WIN:
|
||||||
get_node("winner_right").show()
|
get_node("winner_right").show()
|
||||||
game_ended = true
|
game_ended = true
|
||||||
|
|
||||||
if game_ended:
|
if game_ended:
|
||||||
get_node("exit_game").show()
|
get_node("exit_game").show()
|
||||||
get_node("ball").rpc("stop")
|
get_node("ball").rpc("stop")
|
||||||
|
|
||||||
func _on_exit_game_pressed():
|
func _on_exit_game_pressed():
|
||||||
emit_signal("game_finished")
|
emit_signal("game_finished")
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# by default, all nodes in server inherit from master
|
# by default, all nodes in server inherit from master
|
||||||
# while all nodes in clients inherit from slave
|
# while all nodes in clients inherit from slave
|
||||||
if get_tree().is_network_server():
|
if get_tree().is_network_server():
|
||||||
#if in the server, get control of player 2 to the other peeer, this function is tree recursive by default
|
#if in the server, get control of player 2 to the other peeer, this function is tree recursive by default
|
||||||
get_node("player2").set_network_master(get_tree().get_network_connected_peers()[0])
|
get_node("player2").set_network_master(get_tree().get_network_connected_peers()[0])
|
||||||
else:
|
else:
|
||||||
#if in the client, give control of player 2 to itself, this function is tree recursive by default
|
#if in the client, give control of player 2 to itself, this function is tree recursive by default
|
||||||
get_node("player2").set_network_master(get_tree().get_network_unique_id())
|
get_node("player2").set_network_master(get_tree().get_network_unique_id())
|
||||||
|
|
||||||
#let each paddle know which one is left, too
|
#let each paddle know which one is left, too
|
||||||
get_node("player1").left = true
|
get_node("player1").left = true
|
||||||
get_node("player2").left = false
|
get_node("player2").left = false
|
||||||
|
|||||||
@@ -20,4 +20,3 @@ func _exit_tree():
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -24,23 +24,23 @@ func save_file_selected(path):
|
|||||||
var color = get_node("ColorPicker_albedo").color
|
var color = get_node("ColorPicker_albedo").color
|
||||||
var metallic = get_node("HSlider_metallic").value
|
var metallic = get_node("HSlider_metallic").value
|
||||||
var roughness = get_node("HSlider_roughness").value
|
var roughness = get_node("HSlider_roughness").value
|
||||||
|
|
||||||
# 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()
|
||||||
|
|
||||||
# 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
|
||||||
|
|
||||||
# Make a file, store the silly material as a json string, then close the file.
|
# Make a file, store the silly material as a json string, then close the file.
|
||||||
var file = File.new()
|
var file = File.new()
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
@@ -48,19 +48,19 @@ func load_file_selected(path):
|
|||||||
# Using the passed in editor interface, get the selected nodes in the editor
|
# Using the passed in editor interface, get the selected nodes in the editor
|
||||||
var editor_selection = editor_interface.get_selection()
|
var editor_selection = editor_interface.get_selection()
|
||||||
var selected_nodes = editor_selection.get_selected_nodes()
|
var selected_nodes = editor_selection.get_selected_nodes()
|
||||||
|
|
||||||
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:
|
||||||
@@ -68,24 +68,24 @@ func load_file_selected(path):
|
|||||||
else:
|
else:
|
||||||
file.close()
|
file.close()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# Tell the silly resource (actually a node) to make a material
|
# Tell the silly resource (actually a node) to make a material
|
||||||
SpatialMaterial_Silly = silly_resource.make_material()
|
SpatialMaterial_Silly = silly_resource.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
|
||||||
# to the silly material.
|
# to the silly material.
|
||||||
for node in selected_nodes:
|
for node in selected_nodes:
|
||||||
if node.has_method("set_surface_material"):
|
if node.has_method("set_surface_material"):
|
||||||
node.set_surface_material(0, SpatialMaterial_Silly)
|
node.set_surface_material(0, SpatialMaterial_Silly)
|
||||||
|
|
||||||
# Close the file and return true (success!)
|
# Close the file and return true (success!)
|
||||||
file.close()
|
file.close()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# If the file does not exist, then return false (failure)
|
# If the file does not exist, then return false (failure)
|
||||||
else:
|
else:
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# If we somehow get here, then return false (failure)
|
# If we somehow get here, then return false (failure)
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -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,23 +37,23 @@ 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"]
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ extends EditorPlugin
|
|||||||
var io_material_dialog;
|
var io_material_dialog;
|
||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
|
|
||||||
io_material_dialog = preload("res://addons/custom_import_plugin/Custom_material_dock.tscn").instance()
|
io_material_dialog = preload("res://addons/custom_import_plugin/Custom_material_dock.tscn").instance()
|
||||||
io_material_dialog.editor_interface = get_editor_interface();
|
io_material_dialog.editor_interface = get_editor_interface();
|
||||||
|
|
||||||
add_control_to_dock(DOCK_SLOT_LEFT_UL, io_material_dialog)
|
add_control_to_dock(DOCK_SLOT_LEFT_UL, io_material_dialog)
|
||||||
|
|
||||||
func _exit_tree():
|
func _exit_tree():
|
||||||
|
|||||||
@@ -15,4 +15,3 @@ func _exit_tree():
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -10,4 +10,4 @@ addons/custom_node
|
|||||||
To distribute and install from UI, make a zip that contains the folder,
|
To distribute and install from UI, make a zip that contains the folder,
|
||||||
example:
|
example:
|
||||||
|
|
||||||
zip -r custom_node.zip custom_node/*
|
zip -r custom_node.zip custom_node/*
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
# Member variables
|
# Member variables
|
||||||
@@ -16,46 +15,46 @@ func _process(delta):
|
|||||||
var ball_pos = get_node("ball").get_position()
|
var ball_pos = get_node("ball").get_position()
|
||||||
var left_rect = Rect2(get_node("left").get_position() - pad_size * 0.5, pad_size)
|
var left_rect = Rect2(get_node("left").get_position() - pad_size * 0.5, pad_size)
|
||||||
var right_rect = Rect2(get_node("right").get_position() - pad_size * 0.5, pad_size)
|
var right_rect = Rect2(get_node("right").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)
|
||||||
|
|
||||||
get_node("ball").set_position(ball_pos)
|
get_node("ball").set_position(ball_pos)
|
||||||
|
|
||||||
# Move left pad
|
# Move left pad
|
||||||
var left_pos = get_node("left").get_position()
|
var left_pos = get_node("left").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
|
||||||
|
|
||||||
get_node("left").set_position(left_pos)
|
get_node("left").set_position(left_pos)
|
||||||
|
|
||||||
# Move right pad
|
# Move right pad
|
||||||
var right_pos = get_node("right").get_position()
|
var right_pos = get_node("right").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
|
||||||
|
|
||||||
get_node("right").set_position(right_pos)
|
get_node("right").set_position(right_pos)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ func _ready():
|
|||||||
|
|
||||||
# Assign the sprite's texture to the viewport texture
|
# Assign the sprite's texture to the viewport texture
|
||||||
viewport.set_clear_mode(Viewport.CLEAR_MODE_ONLY_NEXT_FRAME)
|
viewport.set_clear_mode(Viewport.CLEAR_MODE_ONLY_NEXT_FRAME)
|
||||||
|
|
||||||
# Let two frames pass to make sure the screen was captured
|
# Let two frames pass to make sure the screen was captured
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
yield(get_tree(), "idle_frame")
|
yield(get_tree(), "idle_frame")
|
||||||
viewport_sprite.texture = viewport.get_texture()
|
viewport_sprite.texture = viewport.get_texture()
|
||||||
|
|
||||||
set_process(true)
|
set_process(true)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ func _ready():
|
|||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
model.rotation_degrees.y += delta * SPEED
|
model.rotation_degrees.y += delta * SPEED
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func _input(event):
|
|||||||
if event is mouse_event:
|
if event is mouse_event:
|
||||||
is_mouse_event = true
|
is_mouse_event = true
|
||||||
break
|
break
|
||||||
|
|
||||||
# If it is, then pass the event to the viewport
|
# If it is, then pass the event to the viewport
|
||||||
if is_mouse_event == false:
|
if is_mouse_event == false:
|
||||||
viewport.input(event)
|
viewport.input(event)
|
||||||
@@ -37,20 +37,20 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
|
|||||||
pos.x += event.relative.x / viewport.size.x
|
pos.x += event.relative.x / viewport.size.x
|
||||||
pos.y += event.relative.y / viewport.size.y
|
pos.y += event.relative.y / viewport.size.y
|
||||||
last_click_pos = pos
|
last_click_pos = pos
|
||||||
|
|
||||||
# Convert to 2D
|
# Convert to 2D
|
||||||
pos = Vector2(pos.x, pos.y)
|
pos = Vector2(pos.x, pos.y)
|
||||||
|
|
||||||
# Convert to viewport coordinate system
|
# Convert to viewport coordinate system
|
||||||
# Convert pos to a range from (0 - 1)
|
# Convert pos to a range from (0 - 1)
|
||||||
pos.y *= -1
|
pos.y *= -1
|
||||||
pos += Vector2(1, 1)
|
pos += Vector2(1, 1)
|
||||||
pos = pos / 2
|
pos = pos / 2
|
||||||
|
|
||||||
# Convert pos to be in range of the viewport
|
# Convert pos to be in range of the viewport
|
||||||
pos.x *= viewport.size.x
|
pos.x *= viewport.size.x
|
||||||
pos.y *= viewport.size.y
|
pos.y *= viewport.size.y
|
||||||
|
|
||||||
# Set the position in event
|
# Set the position in event
|
||||||
event.position = pos
|
event.position = pos
|
||||||
event.global_position = pos
|
event.global_position = pos
|
||||||
@@ -59,7 +59,7 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
|
|||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
event.relative = pos - prev_pos
|
event.relative = pos - prev_pos
|
||||||
prev_pos = pos
|
prev_pos = pos
|
||||||
|
|
||||||
# Send the event to the viewport
|
# Send the event to the viewport
|
||||||
viewport.input(event)
|
viewport.input(event)
|
||||||
|
|
||||||
@@ -67,4 +67,4 @@ func _on_area_input_event(camera, event, click_pos, click_normal, shape_idx):
|
|||||||
func _ready():
|
func _ready():
|
||||||
viewport = get_node("Viewport")
|
viewport = get_node("Viewport")
|
||||||
get_node("Area").connect("input_event", self, "_on_area_input_event")
|
get_node("Area").connect("input_event", self, "_on_area_input_event")
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +13,7 @@ func _on_button_pressed():
|
|||||||
|
|
||||||
# Retrieve the captured image
|
# Retrieve the captured image
|
||||||
var img = get_viewport().get_texture().get_data()
|
var img = get_viewport().get_texture().get_data()
|
||||||
|
|
||||||
# Flip it on the y-axis (because it's flipped)
|
# Flip it on the y-axis (because it's flipped)
|
||||||
img.flip_y()
|
img.flip_y()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user