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://mouse_look.gd" type="Script" id=2]
|
||||
|
@ -15,56 +15,64 @@ height = 0.85
|
|||
|
||||
flags_transparent = false
|
||||
flags_unshaded = false
|
||||
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 = 2.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 )
|
||||
specular_mode = 0
|
||||
specular_color = Color( 0.1, 0.1, 0.1, 1 )
|
||||
specular_metalness = 0.1
|
||||
specular_roughness = 0.0
|
||||
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
|
||||
height_enabled = false
|
||||
depth_enabled = false
|
||||
subsurf_scatter_enabled = false
|
||||
refraction_enabled = false
|
||||
detail_enabled = false
|
||||
uv1_scale = Vector2( 1, 1 )
|
||||
uv1_offset = Vector2( 0, 0 )
|
||||
uv2_scale = Vector2( 1, 1 )
|
||||
uv2_offset = Vector2( 0, 0 )
|
||||
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
|
||||
|
||||
[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"]
|
||||
|
||||
input_ray_pickable = true
|
||||
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_mask = 1
|
||||
collide_with/static = true
|
||||
collide_with/kinematic = true
|
||||
collide_with/rigid = true
|
||||
collide_with/character = true
|
||||
collision/margin = 0.001
|
||||
collision/safe_margin = 0.001
|
||||
script = ExtResource( 1 )
|
||||
speed = 5.0
|
||||
gravity = 9.8
|
||||
gravity = 40.0
|
||||
jump_force = 8.0
|
||||
head = NodePath("Camera")
|
||||
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 )
|
||||
shape = SubResource( 1 )
|
||||
trigger = false
|
||||
_update_shape_index = 0
|
||||
disabled = false
|
||||
|
||||
[node name="Camera" type="Camera" parent="."]
|
||||
|
||||
|
@ -89,11 +96,14 @@ cull_mask = 1048575
|
|||
environment = null
|
||||
h_offset = 0.0
|
||||
v_offset = 0.0
|
||||
doppler/tracking = 0
|
||||
script = ExtResource( 2 )
|
||||
_sections_unfolded = [ "Transform" ]
|
||||
sensitivity = 0.3
|
||||
min_angle = -90
|
||||
max_angle = 90
|
||||
capture_mouse = true
|
||||
distance = 4.0
|
||||
|
||||
[node name="interaction" type="Node" parent="."]
|
||||
|
||||
|
@ -103,10 +113,16 @@ cursor_material = SubResource( 2 )
|
|||
|
||||
[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_bottom = 325.0
|
||||
rect_pivot_offset = Vector2( 0, 0 )
|
||||
rect_clip_content = false
|
||||
mouse_filter = 2
|
||||
size_flags_horizontal = 1
|
||||
size_flags_vertical = 0
|
||||
percent_visible = 1.0
|
||||
lines_skipped = 0
|
||||
|
@ -131,10 +147,26 @@ shadow_color = Color( 0, 0, 0, 1 )
|
|||
shadow_bias = 0.1
|
||||
shadow_contact = 0.0
|
||||
shadow_max_distance = 0.0
|
||||
shadow_reverse_cull_face = false
|
||||
editor_only = false
|
||||
omni_range = 10.0
|
||||
omni_attenuation = 2.54912
|
||||
omni_shadow_mode = 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
|
||||
|
||||
const BoxPhysics = preload("res://box_physics.gd")
|
||||
|
||||
export var speed = 5.0
|
||||
export var gravity = 9.8
|
||||
export var jump_force = 5.0
|
||||
|
@ -43,13 +45,19 @@ func _fixed_process(delta):
|
|||
_velocity.z = motor.z
|
||||
_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
|
||||
_grounded = false
|
||||
#_grounded = false
|
||||
|
||||
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
|
||||
# if is_colliding():
|
||||
|
@ -64,3 +72,60 @@ func _fixed_process(delta):
|
|||
# else:
|
||||
# _grounded = false
|
||||
#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_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://axes.tscn" type="PackedScene" id=6]
|
||||
[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]
|
||||
|
||||
|
@ -195,6 +196,52 @@ subdivide_width = 0
|
|||
subdivide_height = 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="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
|
@ -205,7 +252,7 @@ environment = SubResource( 2 )
|
|||
|
||||
provider = SubResource( 3 )
|
||||
voxel_library = SubResource( 6 )
|
||||
view_distance = 64
|
||||
view_distance = 32
|
||||
viewer_path = NodePath("")
|
||||
generate_collisions = true
|
||||
material/0 = ExtResource( 1 )
|
||||
|
@ -221,11 +268,11 @@ _sections_unfolded = [ "material" ]
|
|||
|
||||
[node name="Grid" type="MeshInstance" parent="."]
|
||||
|
||||
visible = false
|
||||
layers = 1
|
||||
material_override = SubResource( 7 )
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
visible_in_all_rooms = false
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
|
@ -251,6 +298,7 @@ shadow_color = Color( 0, 0, 0, 1 )
|
|||
shadow_bias = 0.1
|
||||
shadow_contact = 0.0
|
||||
shadow_max_distance = 100.0
|
||||
shadow_reverse_cull_face = false
|
||||
editor_only = false
|
||||
directional_shadow_mode = 2
|
||||
directional_shadow_split_1 = 0.1
|
||||
|
@ -262,17 +310,17 @@ _sections_unfolded = [ "Directional Shadow", "Light", "Shadow" ]
|
|||
|
||||
[node name="CharacterAvatar" parent="." instance=ExtResource( 5 )]
|
||||
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -75.9996, 22.9488, 0 )
|
||||
collision/safe_margin = 0.001
|
||||
speed = 4.0
|
||||
gravity = 0.0
|
||||
jump_force = 9.0
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 25, 17 )
|
||||
terrain = NodePath("../VoxelTerrain")
|
||||
|
||||
[node name="axes" parent="." instance=ExtResource( 6 )]
|
||||
|
||||
[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_right = 104.0
|
||||
margin_bottom = 34.0
|
||||
|
@ -293,7 +341,6 @@ layers = 1
|
|||
material_override = null
|
||||
cast_shadow = 1
|
||||
extra_cull_margin = 0.0
|
||||
visible_in_all_rooms = false
|
||||
use_in_baked_light = false
|
||||
lod_min_distance = 0.0
|
||||
lod_min_hysteresis = 0.0
|
||||
|
@ -304,4 +351,20 @@ skeleton = NodePath("..")
|
|||
material/0 = ExtResource( 1 )
|
||||
_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 max_angle = 90
|
||||
export var capture_mouse = true
|
||||
export var distance = 5.0
|
||||
|
||||
var _yaw = 0
|
||||
var _pitch = 0
|
||||
var _offset = Vector3()
|
||||
|
||||
|
||||
func _ready():
|
||||
_offset = get_translation()
|
||||
if capture_mouse:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
|
@ -21,6 +24,14 @@ func _input(event):
|
|||
if capture_mouse:
|
||||
# Capture the mouse
|
||||
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:
|
||||
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED || not capture_mouse:
|
||||
|
@ -39,8 +50,7 @@ func _input(event):
|
|||
_pitch = min_angle+e
|
||||
|
||||
# Apply rotations
|
||||
set_rotation(Vector3(0, deg2rad(_yaw), 0))
|
||||
rotate(get_transform().basis.x.normalized(), -deg2rad(_pitch))
|
||||
update_rotations()
|
||||
|
||||
elif event is InputEventKey:
|
||||
if event.pressed:
|
||||
|
@ -54,5 +64,10 @@ func _input(event):
|
|||
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
|
||||
|
||||
[application]
|
||||
|
||||
run/main_scene="res://main.tscn"
|
||||
name="Voxel Game"
|
||||
main_scene="res://main.tscn"
|
||||
icon="res://icon.png"
|
||||
|
||||
[input]
|
||||
|
||||
action1=[ InputEvent(MBUTTON,1) ]
|
||||
action2=[ InputEvent(MBUTTON,2) ]
|
||||
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=[ 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]
|
||||
|
||||
|
|
Loading…
Reference in New Issue