GDScript physics :p
parent
1f58edfe9b
commit
3892d546e0
|
@ -0,0 +1,121 @@
|
||||||
|
|
||||||
|
const EPSILON = 0.001
|
||||||
|
|
||||||
|
# Gets the transformed vector for moving a box and slide.
|
||||||
|
# This algorithm is free from tunnelling for axis-aligned movement,
|
||||||
|
# except in some high-speed diagonal cases or huge size differences:
|
||||||
|
# For example, if a box is fast enough to have a diagonal motion jumping from A to B,
|
||||||
|
# it will pass through C if that other box is the only other one:
|
||||||
|
#
|
||||||
|
# o---o
|
||||||
|
# | A |
|
||||||
|
# o---o
|
||||||
|
# o---o
|
||||||
|
# | C |
|
||||||
|
# o---o
|
||||||
|
# o---o
|
||||||
|
# | B |
|
||||||
|
# o---o
|
||||||
|
#
|
||||||
|
# TODO one way to fix this would be to try a "hot side" projection instead
|
||||||
|
#
|
||||||
|
static func get_motion(box, motion, other_boxes):
|
||||||
|
# The bounding box is expanded to include it's estimated version at next update.
|
||||||
|
# This also makes the algorithm tunnelling-free
|
||||||
|
var expanded_box = expand_with_vector(box, motion)
|
||||||
|
|
||||||
|
var colliding_boxes = []
|
||||||
|
for other in other_boxes:
|
||||||
|
if expanded_box.intersects(other):
|
||||||
|
colliding_boxes.append(other)
|
||||||
|
|
||||||
|
if colliding_boxes.size() == 0:
|
||||||
|
return motion
|
||||||
|
#print("Colliding: ", colliding_boxes.size())
|
||||||
|
|
||||||
|
var new_motion = motion
|
||||||
|
|
||||||
|
for other in colliding_boxes:
|
||||||
|
new_motion.y = calculate_y_offset(other, box, new_motion.y)
|
||||||
|
box.position.y += new_motion.y
|
||||||
|
|
||||||
|
for other in colliding_boxes:
|
||||||
|
new_motion.x = calculate_x_offset(other, box, new_motion.x)
|
||||||
|
box.position.x += new_motion.x
|
||||||
|
|
||||||
|
for other in colliding_boxes:
|
||||||
|
new_motion.z = calculate_z_offset(other, box, new_motion.z)
|
||||||
|
box.position.z += new_motion.z
|
||||||
|
|
||||||
|
return new_motion
|
||||||
|
|
||||||
|
|
||||||
|
static func expand_with_vector(box, v):
|
||||||
|
if v.x > 0:
|
||||||
|
box.size.x += v.x
|
||||||
|
elif v.x < 0:
|
||||||
|
box.position.x += v.x
|
||||||
|
box.size.x -= v.x
|
||||||
|
if v.y > 0:
|
||||||
|
box.size.y += v.y
|
||||||
|
elif v.y < 0:
|
||||||
|
box.position.y += v.y
|
||||||
|
box.size.y -= v.y
|
||||||
|
if v.z > 0:
|
||||||
|
box.size.z += v.z
|
||||||
|
elif v.z < 0:
|
||||||
|
box.position.z += v.z
|
||||||
|
box.size.z -= v.z
|
||||||
|
return box
|
||||||
|
|
||||||
|
|
||||||
|
static func calculate_z_offset(box, other, motion_z):
|
||||||
|
if other.end.y <= box.position.y || other.position.y >= box.end.y:
|
||||||
|
return motion_z
|
||||||
|
if other.end.x <= box.position.x || other.position.x >= box.end.x:
|
||||||
|
return motion_z
|
||||||
|
if motion_z > 0.0 and other.end.z <= box.position.z:
|
||||||
|
var off = box.position.z - other.end.z - EPSILON
|
||||||
|
if off < motion_z:
|
||||||
|
motion_z = off
|
||||||
|
if motion_z < 0.0 and other.position.z >= box.end.z:
|
||||||
|
var off = box.end.z - other.position.z + EPSILON
|
||||||
|
if off > motion_z:
|
||||||
|
motion_z = off
|
||||||
|
return motion_z
|
||||||
|
|
||||||
|
|
||||||
|
static func calculate_x_offset(box, other, motion_x):
|
||||||
|
if other.end.z <= box.position.z || other.position.z >= box.end.z:
|
||||||
|
return motion_x
|
||||||
|
if other.end.y <= box.position.y || other.position.y >= box.end.y:
|
||||||
|
return motion_x
|
||||||
|
if motion_x > 0.0 and other.end.x <= box.position.x:
|
||||||
|
var off = box.position.x - other.end.x - EPSILON
|
||||||
|
if off < motion_x:
|
||||||
|
motion_x = off
|
||||||
|
if motion_x < 0.0 and other.position.x >= box.end.x:
|
||||||
|
var off = box.end.x - other.position.x + EPSILON
|
||||||
|
if off > motion_x:
|
||||||
|
motion_x = off
|
||||||
|
return motion_x
|
||||||
|
|
||||||
|
|
||||||
|
static func calculate_y_offset(box, other, motion_y):
|
||||||
|
if other.end.z <= box.position.z || other.position.z >= box.end.z:
|
||||||
|
return motion_y
|
||||||
|
if other.end.x <= box.position.x || other.position.x >= box.end.x:
|
||||||
|
return motion_y
|
||||||
|
if motion_y > 0.0 and other.end.y <= box.position.y:
|
||||||
|
var off = box.position.y - other.end.y - EPSILON
|
||||||
|
if off < motion_y:
|
||||||
|
motion_y = off
|
||||||
|
if motion_y < 0.0 and other.position.y >= box.end.y:
|
||||||
|
var off = box.end.y - other.position.y + EPSILON
|
||||||
|
if off > motion_y:
|
||||||
|
motion_y = off
|
||||||
|
return motion_y
|
||||||
|
|
||||||
|
|
||||||
|
static func box_from_center_extents(center, extents):
|
||||||
|
return Rect3(center - extents, 2.0*extents)
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=8 format=2]
|
[gd_scene load_steps=9 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://character_controller.gd" type="Script" id=1]
|
[ext_resource path="res://character_controller.gd" type="Script" id=1]
|
||||||
[ext_resource path="res://mouse_look.gd" type="Script" id=2]
|
[ext_resource path="res://mouse_look.gd" type="Script" id=2]
|
||||||
|
@ -15,56 +15,64 @@ height = 0.85
|
||||||
|
|
||||||
flags_transparent = false
|
flags_transparent = false
|
||||||
flags_unshaded = false
|
flags_unshaded = false
|
||||||
|
flags_vertex_lighting = false
|
||||||
flags_on_top = false
|
flags_on_top = false
|
||||||
flags_use_point_size = false
|
flags_use_point_size = false
|
||||||
flags_fixed_size = false
|
flags_fixed_size = false
|
||||||
vertex_color_use_as_albedo = true
|
vertex_color_use_as_albedo = true
|
||||||
vertex_color_is_srgb = false
|
vertex_color_is_srgb = false
|
||||||
params_diffuse_mode = 0
|
params_diffuse_mode = 0
|
||||||
|
params_specular_mode = 0
|
||||||
params_blend_mode = 0
|
params_blend_mode = 0
|
||||||
params_cull_mode = 0
|
params_cull_mode = 0
|
||||||
params_depth_draw_mode = 0
|
params_depth_draw_mode = 0
|
||||||
params_line_width = 2.0
|
params_line_width = 2.0
|
||||||
params_point_size = 1.0
|
params_point_size = 1.0
|
||||||
params_billboard_mode = 0
|
params_billboard_mode = 0
|
||||||
|
params_grow = false
|
||||||
|
params_use_alpha_scissor = false
|
||||||
albedo_color = Color( 1, 1, 1, 1 )
|
albedo_color = Color( 1, 1, 1, 1 )
|
||||||
specular_mode = 0
|
metallic = 0.0
|
||||||
specular_color = Color( 0.1, 0.1, 0.1, 1 )
|
metallic_specular = 0.5
|
||||||
specular_metalness = 0.1
|
metallic_texture_channel = 0
|
||||||
specular_roughness = 0.0
|
roughness = 0.0
|
||||||
|
roughness_texture_channel = 0
|
||||||
emission_enabled = false
|
emission_enabled = false
|
||||||
normal_enabled = false
|
normal_enabled = false
|
||||||
rim_enabled = false
|
rim_enabled = false
|
||||||
clearcoat_enabled = false
|
clearcoat_enabled = false
|
||||||
anisotropy_enabled = false
|
anisotropy_enabled = false
|
||||||
ao_enabled = false
|
ao_enabled = false
|
||||||
height_enabled = false
|
depth_enabled = false
|
||||||
subsurf_scatter_enabled = false
|
subsurf_scatter_enabled = false
|
||||||
refraction_enabled = false
|
refraction_enabled = false
|
||||||
detail_enabled = false
|
detail_enabled = false
|
||||||
uv1_scale = Vector2( 1, 1 )
|
uv1_scale = Vector3( 1, 1, 1 )
|
||||||
uv1_offset = Vector2( 0, 0 )
|
uv1_offset = Vector3( 0, 0, 0 )
|
||||||
uv2_scale = Vector2( 1, 1 )
|
uv1_triplanar = false
|
||||||
uv2_offset = Vector2( 0, 0 )
|
uv1_triplanar_sharpness = 1.0
|
||||||
|
uv2_scale = Vector3( 1, 1, 1 )
|
||||||
|
uv2_offset = Vector3( 0, 0, 0 )
|
||||||
|
uv2_triplanar = false
|
||||||
|
uv2_triplanar_sharpness = 1.0
|
||||||
|
|
||||||
|
[sub_resource type="CubeMesh" id=3]
|
||||||
|
|
||||||
|
size = Vector3( 0.8, 1.8, 0.8 )
|
||||||
|
subdivide_width = 0
|
||||||
|
subdivide_height = 0
|
||||||
|
subdivide_depth = 0
|
||||||
|
|
||||||
[node name="CharacterAvatar" type="KinematicBody"]
|
[node name="CharacterAvatar" type="KinematicBody"]
|
||||||
|
|
||||||
input_ray_pickable = true
|
input_ray_pickable = true
|
||||||
input_capture_on_drag = false
|
input_capture_on_drag = false
|
||||||
shape_count = 1
|
|
||||||
shapes/0/shape = SubResource( 1 )
|
|
||||||
shapes/0/transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )
|
|
||||||
shapes/0/trigger = false
|
|
||||||
collision_layer = 3
|
collision_layer = 3
|
||||||
collision_mask = 1
|
collision_mask = 1
|
||||||
collide_with/static = true
|
collision/safe_margin = 0.001
|
||||||
collide_with/kinematic = true
|
|
||||||
collide_with/rigid = true
|
|
||||||
collide_with/character = true
|
|
||||||
collision/margin = 0.001
|
|
||||||
script = ExtResource( 1 )
|
script = ExtResource( 1 )
|
||||||
speed = 5.0
|
speed = 5.0
|
||||||
gravity = 9.8
|
gravity = 40.0
|
||||||
jump_force = 8.0
|
jump_force = 8.0
|
||||||
head = NodePath("Camera")
|
head = NodePath("Camera")
|
||||||
terrain = null
|
terrain = null
|
||||||
|
@ -73,8 +81,7 @@ terrain = null
|
||||||
|
|
||||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
transform = Transform( 1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0 )
|
||||||
shape = SubResource( 1 )
|
shape = SubResource( 1 )
|
||||||
trigger = false
|
disabled = false
|
||||||
_update_shape_index = 0
|
|
||||||
|
|
||||||
[node name="Camera" type="Camera" parent="."]
|
[node name="Camera" type="Camera" parent="."]
|
||||||
|
|
||||||
|
@ -89,11 +96,14 @@ cull_mask = 1048575
|
||||||
environment = null
|
environment = null
|
||||||
h_offset = 0.0
|
h_offset = 0.0
|
||||||
v_offset = 0.0
|
v_offset = 0.0
|
||||||
|
doppler/tracking = 0
|
||||||
script = ExtResource( 2 )
|
script = ExtResource( 2 )
|
||||||
|
_sections_unfolded = [ "Transform" ]
|
||||||
sensitivity = 0.3
|
sensitivity = 0.3
|
||||||
min_angle = -90
|
min_angle = -90
|
||||||
max_angle = 90
|
max_angle = 90
|
||||||
capture_mouse = true
|
capture_mouse = true
|
||||||
|
distance = 4.0
|
||||||
|
|
||||||
[node name="interaction" type="Node" parent="."]
|
[node name="interaction" type="Node" parent="."]
|
||||||
|
|
||||||
|
@ -103,10 +113,16 @@ cursor_material = SubResource( 2 )
|
||||||
|
|
||||||
[node name="debug_label" type="Label" parent="."]
|
[node name="debug_label" type="Label" parent="."]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
margin_right = 379.0
|
margin_right = 379.0
|
||||||
margin_bottom = 325.0
|
margin_bottom = 325.0
|
||||||
|
rect_pivot_offset = Vector2( 0, 0 )
|
||||||
rect_clip_content = false
|
rect_clip_content = false
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
size_flags_horizontal = 1
|
||||||
size_flags_vertical = 0
|
size_flags_vertical = 0
|
||||||
percent_visible = 1.0
|
percent_visible = 1.0
|
||||||
lines_skipped = 0
|
lines_skipped = 0
|
||||||
|
@ -131,10 +147,26 @@ shadow_color = Color( 0, 0, 0, 1 )
|
||||||
shadow_bias = 0.1
|
shadow_bias = 0.1
|
||||||
shadow_contact = 0.0
|
shadow_contact = 0.0
|
||||||
shadow_max_distance = 0.0
|
shadow_max_distance = 0.0
|
||||||
|
shadow_reverse_cull_face = false
|
||||||
editor_only = false
|
editor_only = false
|
||||||
omni_range = 10.0
|
omni_range = 10.0
|
||||||
omni_attenuation = 2.54912
|
omni_attenuation = 2.54912
|
||||||
omni_shadow_mode = 1
|
omni_shadow_mode = 1
|
||||||
omni_shadow_detail = 1
|
omni_shadow_detail = 1
|
||||||
|
|
||||||
|
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||||
|
|
||||||
|
layers = 1
|
||||||
|
material_override = null
|
||||||
|
cast_shadow = 1
|
||||||
|
extra_cull_margin = 0.0
|
||||||
|
use_in_baked_light = false
|
||||||
|
lod_min_distance = 0.0
|
||||||
|
lod_min_hysteresis = 0.0
|
||||||
|
lod_max_distance = 0.0
|
||||||
|
lod_max_hysteresis = 0.0
|
||||||
|
mesh = SubResource( 3 )
|
||||||
|
skeleton = NodePath("..")
|
||||||
|
material/0 = null
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
extends KinematicBody
|
extends KinematicBody
|
||||||
|
|
||||||
|
const BoxPhysics = preload("res://box_physics.gd")
|
||||||
|
|
||||||
export var speed = 5.0
|
export var speed = 5.0
|
||||||
export var gravity = 9.8
|
export var gravity = 9.8
|
||||||
export var jump_force = 5.0
|
export var jump_force = 5.0
|
||||||
|
@ -43,13 +45,19 @@ func _fixed_process(delta):
|
||||||
_velocity.z = motor.z
|
_velocity.z = motor.z
|
||||||
_velocity.y -= gravity * delta
|
_velocity.y -= gravity * delta
|
||||||
|
|
||||||
if _grounded and Input.is_key_pressed(KEY_SPACE):
|
#if _grounded and Input.is_key_pressed(KEY_SPACE):
|
||||||
|
if Input.is_key_pressed(KEY_SPACE):
|
||||||
_velocity.y = jump_force
|
_velocity.y = jump_force
|
||||||
_grounded = false
|
#_grounded = false
|
||||||
|
|
||||||
var motion = _velocity * delta
|
var motion = _velocity * delta
|
||||||
|
|
||||||
var rem = move(motion)
|
motion = move_with_box_physics(motion)
|
||||||
|
|
||||||
|
assert(delta > 0)
|
||||||
|
_velocity = motion / delta
|
||||||
|
|
||||||
|
#var rem = move(motion)
|
||||||
|
|
||||||
# TODO Fix it, obsolete code
|
# TODO Fix it, obsolete code
|
||||||
# if is_colliding():
|
# if is_colliding():
|
||||||
|
@ -64,3 +72,60 @@ func _fixed_process(delta):
|
||||||
# else:
|
# else:
|
||||||
# _grounded = false
|
# _grounded = false
|
||||||
#get_node("debug").set_text("Grounded=" + str(_grounded))
|
#get_node("debug").set_text("Grounded=" + str(_grounded))
|
||||||
|
|
||||||
|
|
||||||
|
# TODO There is room for optimization, but I'll leave it like this for now, it doesn't cause any lag
|
||||||
|
func move_with_box_physics(motion):
|
||||||
|
var debug3d = get_node("../Debug3D")
|
||||||
|
|
||||||
|
var pos = get_translation()
|
||||||
|
var box = BoxPhysics.box_from_center_extents(pos, Vector3(0.4, 0.9, 0.4))
|
||||||
|
|
||||||
|
var expanded_box = BoxPhysics.expand_with_vector(box, motion)
|
||||||
|
debug3d.draw_wire_box(expanded_box, Color(0,1,0,1))
|
||||||
|
|
||||||
|
var potential_boxes = []
|
||||||
|
|
||||||
|
# Collect collisions with the terrain
|
||||||
|
if has_node(terrain):
|
||||||
|
var voxel_terrain = get_node(terrain)
|
||||||
|
var voxels = voxel_terrain.get_storage()
|
||||||
|
|
||||||
|
var min_x = int(floor(expanded_box.position.x))
|
||||||
|
var min_y = int(floor(expanded_box.position.y))
|
||||||
|
var min_z = int(floor(expanded_box.position.z))
|
||||||
|
|
||||||
|
var max_x = int(ceil(expanded_box.end.x))
|
||||||
|
var max_y = int(ceil(expanded_box.end.y))
|
||||||
|
var max_z = int(ceil(expanded_box.end.z))
|
||||||
|
|
||||||
|
var x = min_x
|
||||||
|
var y = min_y
|
||||||
|
var z = min_z
|
||||||
|
|
||||||
|
while z < max_z:
|
||||||
|
while y < max_y:
|
||||||
|
while x < max_x:
|
||||||
|
|
||||||
|
var voxel_type = voxels.get_voxel(x,y,z, 0)
|
||||||
|
if voxel_type != 0:
|
||||||
|
var voxel_box = Rect3(Vector3(x,y,z), Vector3(1,1,1))
|
||||||
|
potential_boxes.append(voxel_box)
|
||||||
|
debug3d.draw_wire_box(voxel_box)
|
||||||
|
|
||||||
|
x += 1
|
||||||
|
x = min_x
|
||||||
|
y += 1
|
||||||
|
y = min_y
|
||||||
|
z += 1
|
||||||
|
|
||||||
|
motion = BoxPhysics.get_motion(box, motion, potential_boxes)
|
||||||
|
move(motion)
|
||||||
|
return motion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
extends MeshInstance
|
||||||
|
|
||||||
|
|
||||||
|
var _boxes = []
|
||||||
|
var _colors = []
|
||||||
|
var _mesh = null
|
||||||
|
|
||||||
|
# Who said "use ImmediateGeometry" node?
|
||||||
|
|
||||||
|
func draw_wire_box(box, color=Color(1,1,1,1)):
|
||||||
|
_boxes.append(box)
|
||||||
|
_colors.append(color)
|
||||||
|
|
||||||
|
|
||||||
|
func _fixed_process(delta):
|
||||||
|
|
||||||
|
if _mesh == null:
|
||||||
|
_mesh = ArrayMesh.new()
|
||||||
|
mesh = _mesh
|
||||||
|
|
||||||
|
if _mesh.get_surface_count() != 0:
|
||||||
|
_mesh.surface_remove(0)
|
||||||
|
|
||||||
|
var positions = PoolVector3Array()
|
||||||
|
var colors = PoolColorArray()
|
||||||
|
var indices = PoolIntArray()
|
||||||
|
|
||||||
|
for i in range(0, _boxes.size()):
|
||||||
|
var box = _boxes[i]
|
||||||
|
var color = _colors[i]
|
||||||
|
|
||||||
|
var vi = positions.size()
|
||||||
|
|
||||||
|
var pos = box.position
|
||||||
|
var end = box.end
|
||||||
|
|
||||||
|
var x0 = pos.x
|
||||||
|
var y0 = pos.y
|
||||||
|
var z0 = pos.z
|
||||||
|
|
||||||
|
var x1 = end.x
|
||||||
|
var y1 = end.y
|
||||||
|
var z1 = end.z
|
||||||
|
|
||||||
|
positions.append_array([
|
||||||
|
Vector3(x0, y0, z0),
|
||||||
|
Vector3(x1, y0, z0),
|
||||||
|
Vector3(x1, y0, z1),
|
||||||
|
Vector3(x0, y0, z1),
|
||||||
|
|
||||||
|
Vector3(x0, y1, z0),
|
||||||
|
Vector3(x1, y1, z0),
|
||||||
|
Vector3(x1, y1, z1),
|
||||||
|
Vector3(x0, y1, z1)
|
||||||
|
])
|
||||||
|
|
||||||
|
colors.append_array([
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color,
|
||||||
|
color
|
||||||
|
])
|
||||||
|
|
||||||
|
indices.append_array([
|
||||||
|
indices.append(vi),
|
||||||
|
indices.append(vi+1),
|
||||||
|
indices.append(vi+1),
|
||||||
|
indices.append(vi+2),
|
||||||
|
indices.append(vi+2),
|
||||||
|
indices.append(vi+3),
|
||||||
|
indices.append(vi+3),
|
||||||
|
indices.append(vi),
|
||||||
|
|
||||||
|
indices.append(vi+4),
|
||||||
|
indices.append(vi+5),
|
||||||
|
indices.append(vi+5),
|
||||||
|
indices.append(vi+6),
|
||||||
|
indices.append(vi+6),
|
||||||
|
indices.append(vi+7),
|
||||||
|
indices.append(vi+7),
|
||||||
|
indices.append(vi+4),
|
||||||
|
|
||||||
|
indices.append(vi),
|
||||||
|
indices.append(vi+4),
|
||||||
|
indices.append(vi+1),
|
||||||
|
indices.append(vi+5),
|
||||||
|
indices.append(vi+2),
|
||||||
|
indices.append(vi+6),
|
||||||
|
indices.append(vi+3),
|
||||||
|
indices.append(vi+7)
|
||||||
|
])
|
||||||
|
|
||||||
|
if positions.size() != 0:
|
||||||
|
var arrays = []
|
||||||
|
# TODO Use ArrayMesh.ARRAY_MAX
|
||||||
|
arrays.resize(9)
|
||||||
|
arrays[ArrayMesh.ARRAY_VERTEX] = positions
|
||||||
|
arrays[ArrayMesh.ARRAY_COLOR] = colors
|
||||||
|
arrays[ArrayMesh.ARRAY_INDEX] = indices
|
||||||
|
|
||||||
|
_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, arrays)
|
||||||
|
|
||||||
|
_boxes.clear()
|
||||||
|
_colors.clear()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=16 format=2]
|
[gd_scene load_steps=18 format=2]
|
||||||
|
|
||||||
[ext_resource path="res://terrain_material.tres" type="Material" id=1]
|
[ext_resource path="res://terrain_material.tres" type="Material" id=1]
|
||||||
[ext_resource path="res://terrain_marerial_transparent.tres" type="Material" id=2]
|
[ext_resource path="res://terrain_marerial_transparent.tres" type="Material" id=2]
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
[ext_resource path="res://character_avatar.tscn" type="PackedScene" id=5]
|
[ext_resource path="res://character_avatar.tscn" type="PackedScene" id=5]
|
||||||
[ext_resource path="res://axes.tscn" type="PackedScene" id=6]
|
[ext_resource path="res://axes.tscn" type="PackedScene" id=6]
|
||||||
[ext_resource path="res://profiling_gui.gd" type="Script" id=7]
|
[ext_resource path="res://profiling_gui.gd" type="Script" id=7]
|
||||||
|
[ext_resource path="res://debug3d.gd" type="Script" id=8]
|
||||||
|
|
||||||
[sub_resource type="ProceduralSky" id=1]
|
[sub_resource type="ProceduralSky" id=1]
|
||||||
|
|
||||||
|
@ -195,6 +196,52 @@ subdivide_width = 0
|
||||||
subdivide_height = 0
|
subdivide_height = 0
|
||||||
subdivide_depth = 0
|
subdivide_depth = 0
|
||||||
|
|
||||||
|
[sub_resource type="SpatialMaterial" id=9]
|
||||||
|
|
||||||
|
flags_transparent = false
|
||||||
|
flags_unshaded = true
|
||||||
|
flags_vertex_lighting = false
|
||||||
|
flags_on_top = false
|
||||||
|
flags_use_point_size = false
|
||||||
|
flags_fixed_size = false
|
||||||
|
vertex_color_use_as_albedo = true
|
||||||
|
vertex_color_is_srgb = false
|
||||||
|
params_diffuse_mode = 0
|
||||||
|
params_specular_mode = 0
|
||||||
|
params_blend_mode = 0
|
||||||
|
params_cull_mode = 0
|
||||||
|
params_depth_draw_mode = 0
|
||||||
|
params_line_width = 1.0
|
||||||
|
params_point_size = 1.0
|
||||||
|
params_billboard_mode = 0
|
||||||
|
params_grow = false
|
||||||
|
params_use_alpha_scissor = false
|
||||||
|
albedo_color = Color( 1, 1, 1, 1 )
|
||||||
|
metallic = 0.0
|
||||||
|
metallic_specular = 0.5
|
||||||
|
metallic_texture_channel = 0
|
||||||
|
roughness = 0.0
|
||||||
|
roughness_texture_channel = 0
|
||||||
|
emission_enabled = false
|
||||||
|
normal_enabled = false
|
||||||
|
rim_enabled = false
|
||||||
|
clearcoat_enabled = false
|
||||||
|
anisotropy_enabled = false
|
||||||
|
ao_enabled = false
|
||||||
|
depth_enabled = false
|
||||||
|
subsurf_scatter_enabled = false
|
||||||
|
refraction_enabled = false
|
||||||
|
detail_enabled = false
|
||||||
|
uv1_scale = Vector3( 1, 1, 1 )
|
||||||
|
uv1_offset = Vector3( 0, 0, 0 )
|
||||||
|
uv1_triplanar = false
|
||||||
|
uv1_triplanar_sharpness = 1.0
|
||||||
|
uv2_scale = Vector3( 1, 1, 1 )
|
||||||
|
uv2_offset = Vector3( 0, 0, 0 )
|
||||||
|
uv2_triplanar = false
|
||||||
|
uv2_triplanar_sharpness = 1.0
|
||||||
|
_sections_unfolded = [ "Emission", "Flags", "Vertex Color" ]
|
||||||
|
|
||||||
[node name="Node" type="Node"]
|
[node name="Node" type="Node"]
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
@ -205,7 +252,7 @@ environment = SubResource( 2 )
|
||||||
|
|
||||||
provider = SubResource( 3 )
|
provider = SubResource( 3 )
|
||||||
voxel_library = SubResource( 6 )
|
voxel_library = SubResource( 6 )
|
||||||
view_distance = 64
|
view_distance = 32
|
||||||
viewer_path = NodePath("")
|
viewer_path = NodePath("")
|
||||||
generate_collisions = true
|
generate_collisions = true
|
||||||
material/0 = ExtResource( 1 )
|
material/0 = ExtResource( 1 )
|
||||||
|
@ -221,11 +268,11 @@ _sections_unfolded = [ "material" ]
|
||||||
|
|
||||||
[node name="Grid" type="MeshInstance" parent="."]
|
[node name="Grid" type="MeshInstance" parent="."]
|
||||||
|
|
||||||
|
visible = false
|
||||||
layers = 1
|
layers = 1
|
||||||
material_override = SubResource( 7 )
|
material_override = SubResource( 7 )
|
||||||
cast_shadow = 1
|
cast_shadow = 1
|
||||||
extra_cull_margin = 0.0
|
extra_cull_margin = 0.0
|
||||||
visible_in_all_rooms = false
|
|
||||||
use_in_baked_light = false
|
use_in_baked_light = false
|
||||||
lod_min_distance = 0.0
|
lod_min_distance = 0.0
|
||||||
lod_min_hysteresis = 0.0
|
lod_min_hysteresis = 0.0
|
||||||
|
@ -251,6 +298,7 @@ shadow_color = Color( 0, 0, 0, 1 )
|
||||||
shadow_bias = 0.1
|
shadow_bias = 0.1
|
||||||
shadow_contact = 0.0
|
shadow_contact = 0.0
|
||||||
shadow_max_distance = 100.0
|
shadow_max_distance = 100.0
|
||||||
|
shadow_reverse_cull_face = false
|
||||||
editor_only = false
|
editor_only = false
|
||||||
directional_shadow_mode = 2
|
directional_shadow_mode = 2
|
||||||
directional_shadow_split_1 = 0.1
|
directional_shadow_split_1 = 0.1
|
||||||
|
@ -262,17 +310,17 @@ _sections_unfolded = [ "Directional Shadow", "Light", "Shadow" ]
|
||||||
|
|
||||||
[node name="CharacterAvatar" parent="." instance=ExtResource( 5 )]
|
[node name="CharacterAvatar" parent="." instance=ExtResource( 5 )]
|
||||||
|
|
||||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -75.9996, 22.9488, 0 )
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 25, 17 )
|
||||||
collision/safe_margin = 0.001
|
|
||||||
speed = 4.0
|
|
||||||
gravity = 0.0
|
|
||||||
jump_force = 9.0
|
|
||||||
terrain = NodePath("../VoxelTerrain")
|
terrain = NodePath("../VoxelTerrain")
|
||||||
|
|
||||||
[node name="axes" parent="." instance=ExtResource( 6 )]
|
[node name="axes" parent="." instance=ExtResource( 6 )]
|
||||||
|
|
||||||
[node name="ProfilingInfo" type="Label" parent="."]
|
[node name="ProfilingInfo" type="Label" parent="."]
|
||||||
|
|
||||||
|
anchor_left = 0.0
|
||||||
|
anchor_top = 0.0
|
||||||
|
anchor_right = 0.0
|
||||||
|
anchor_bottom = 0.0
|
||||||
margin_top = 20.0
|
margin_top = 20.0
|
||||||
margin_right = 104.0
|
margin_right = 104.0
|
||||||
margin_bottom = 34.0
|
margin_bottom = 34.0
|
||||||
|
@ -293,7 +341,6 @@ layers = 1
|
||||||
material_override = null
|
material_override = null
|
||||||
cast_shadow = 1
|
cast_shadow = 1
|
||||||
extra_cull_margin = 0.0
|
extra_cull_margin = 0.0
|
||||||
visible_in_all_rooms = false
|
|
||||||
use_in_baked_light = false
|
use_in_baked_light = false
|
||||||
lod_min_distance = 0.0
|
lod_min_distance = 0.0
|
||||||
lod_min_hysteresis = 0.0
|
lod_min_hysteresis = 0.0
|
||||||
|
@ -304,4 +351,20 @@ skeleton = NodePath("..")
|
||||||
material/0 = ExtResource( 1 )
|
material/0 = ExtResource( 1 )
|
||||||
_sections_unfolded = [ "material" ]
|
_sections_unfolded = [ "material" ]
|
||||||
|
|
||||||
|
[node name="Debug3D" type="MeshInstance" parent="."]
|
||||||
|
|
||||||
|
layers = 1
|
||||||
|
material_override = SubResource( 9 )
|
||||||
|
cast_shadow = 1
|
||||||
|
extra_cull_margin = 0.0
|
||||||
|
use_in_baked_light = false
|
||||||
|
lod_min_distance = 0.0
|
||||||
|
lod_min_hysteresis = 0.0
|
||||||
|
lod_max_distance = 0.0
|
||||||
|
lod_max_hysteresis = 0.0
|
||||||
|
mesh = null
|
||||||
|
skeleton = NodePath("..")
|
||||||
|
script = ExtResource( 8 )
|
||||||
|
_sections_unfolded = [ "Geometry" ]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,15 @@ export var sensitivity = 0.4
|
||||||
export var min_angle = -90
|
export var min_angle = -90
|
||||||
export var max_angle = 90
|
export var max_angle = 90
|
||||||
export var capture_mouse = true
|
export var capture_mouse = true
|
||||||
|
export var distance = 5.0
|
||||||
|
|
||||||
var _yaw = 0
|
var _yaw = 0
|
||||||
var _pitch = 0
|
var _pitch = 0
|
||||||
|
var _offset = Vector3()
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
_offset = get_translation()
|
||||||
if capture_mouse:
|
if capture_mouse:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
|
|
||||||
|
@ -21,6 +24,14 @@ func _input(event):
|
||||||
if capture_mouse:
|
if capture_mouse:
|
||||||
# Capture the mouse
|
# Capture the mouse
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
|
|
||||||
|
if event.button_index == BUTTON_WHEEL_UP:
|
||||||
|
distance = max(distance-1, 0)
|
||||||
|
update_rotations()
|
||||||
|
|
||||||
|
elif event.button_index == BUTTON_WHEEL_DOWN:
|
||||||
|
distance = max(distance+1, 0)
|
||||||
|
update_rotations()
|
||||||
|
|
||||||
elif event is InputEventMouseMotion:
|
elif event is InputEventMouseMotion:
|
||||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED || not capture_mouse:
|
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED || not capture_mouse:
|
||||||
|
@ -39,8 +50,7 @@ func _input(event):
|
||||||
_pitch = min_angle+e
|
_pitch = min_angle+e
|
||||||
|
|
||||||
# Apply rotations
|
# Apply rotations
|
||||||
set_rotation(Vector3(0, deg2rad(_yaw), 0))
|
update_rotations()
|
||||||
rotate(get_transform().basis.x.normalized(), -deg2rad(_pitch))
|
|
||||||
|
|
||||||
elif event is InputEventKey:
|
elif event is InputEventKey:
|
||||||
if event.pressed:
|
if event.pressed:
|
||||||
|
@ -54,5 +64,10 @@ func _input(event):
|
||||||
print("Position: ", pos, ", Forward: ", fw)
|
print("Position: ", pos, ", Forward: ", fw)
|
||||||
|
|
||||||
|
|
||||||
|
func update_rotations():
|
||||||
|
set_translation(Vector3())
|
||||||
|
set_rotation(Vector3(0, deg2rad(_yaw), 0))
|
||||||
|
rotate(get_transform().basis.x.normalized(), -deg2rad(_pitch))
|
||||||
|
set_translation(get_transform().basis.z * distance + _offset)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
|
; Engine configuration file.
|
||||||
|
; It's best edited using the editor UI and not directly,
|
||||||
|
; since the parameters that go here are not all obvious.
|
||||||
|
;
|
||||||
|
; Format:
|
||||||
|
; [section] ; section goes between []
|
||||||
|
; param=value ; assign values to parameters
|
||||||
|
|
||||||
config_version=3
|
config_version=3
|
||||||
|
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
|
run/main_scene="res://main.tscn"
|
||||||
name="Voxel Game"
|
name="Voxel Game"
|
||||||
main_scene="res://main.tscn"
|
main_scene="res://main.tscn"
|
||||||
icon="res://icon.png"
|
icon="res://icon.png"
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
action1=[ InputEvent(MBUTTON,1) ]
|
action1=[ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null)
|
||||||
action2=[ InputEvent(MBUTTON,2) ]
|
]
|
||||||
|
action2=[ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":2,"pressed":false,"doubleclick":false,"script":null)
|
||||||
|
]
|
||||||
|
|
||||||
[layer_names]
|
[layer_names]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue