diff --git a/scenes/player.tscn b/scenes/player.tscn index ba9aa93..2360b77 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://scripts/player.gd" type="Script" id=1] +[ext_resource path="res://scripts/tp_camera.gd" type="Script" id=2] [sub_resource type="CapsuleShape" id=1] @@ -20,7 +21,7 @@ radial_segments = 64 rings = 8 _sections_unfolded = [ "Resource" ] -[node name="RigidBody" type="RigidBody" groups=[ +[node name="RigidBody" type="RigidBody" index="0" groups=[ "player", ]] @@ -51,6 +52,8 @@ angular_velocity = Vector3( 0, 0, 0 ) angular_damp = -1.0 script = ExtResource( 1 ) _sections_unfolded = [ "Angular", "Axis Lock", "Collision", "Linear", "Transform", "Visibility", "collision" ] +tp_camera = NodePath("TPCamera") +master_only = NodePath("MasterOnly") [node name="Body" type="CollisionShape" parent="." index="0"] @@ -75,30 +78,7 @@ cast_to = Vector3( 0, -0.3, 0 ) collision_mask = 1 _sections_unfolded = [ "Transform", "Visibility" ] -[node name="Yaw" type="Spatial" parent="." index="3"] - -[node name="Pitch" type="Spatial" parent="Yaw" index="0"] - -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, 0 ) -_sections_unfolded = [ "Transform" ] - -[node name="Camera" type="Camera" parent="Yaw/Pitch" index="0"] - -keep_aspect = 0 -cull_mask = 1048575 -environment = null -h_offset = 0.0 -v_offset = 0.0 -doppler_tracking = 0 -projection = 0 -current = false -fov = 70.0 -size = 1.0 -near = 0.05 -far = 100.0 -_sections_unfolded = [ "Transform", "Visibility" ] - -[node name="MeshInstance" type="MeshInstance" parent="." index="4"] +[node name="MeshInstance" type="MeshInstance" parent="." index="3"] transform = Transform( 1, 0, 0, 0, -1.62921e-07, -1, 0, 1, -1.62921e-07, 0, 0.95, 0 ) layers = 1 @@ -115,6 +95,13 @@ skeleton = NodePath("..") material/0 = null _sections_unfolded = [ "Transform" ] +[node name="Yaw" type="Spatial" parent="." index="4"] + +[node name="Pitch" type="Spatial" parent="Yaw" index="0"] + +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, 0 ) +_sections_unfolded = [ "Transform" ] + [node name="MasterOnly" type="Node" parent="." index="5"] [node name="Crosshair" type="Label" parent="MasterOnly" index="0"] @@ -159,4 +146,29 @@ percent_visible = 1.0 lines_skipped = 0 max_lines_visible = -1 +[node name="TPCamera" type="Spatial" parent="." index="6"] + +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, 0 ) +script = ExtResource( 2 ) +_sections_unfolded = [ "Transform" ] +cam = NodePath("Camera") +pivot = NodePath("Pivot") + +[node name="Pivot" type="Spatial" parent="TPCamera" index="0"] + +[node name="Camera" type="Camera" parent="TPCamera" index="1"] + +keep_aspect = 1 +cull_mask = 1048575 +environment = null +h_offset = 0.0 +v_offset = 0.0 +doppler_tracking = 0 +projection = 0 +current = false +fov = 70.0 +size = 1.0 +near = 0.05 +far = 100.0 + diff --git a/scripts/player.gd b/scripts/player.gd index c4e3ecd..570d75c 100644 --- a/scripts/player.gd +++ b/scripts/player.gd @@ -3,8 +3,6 @@ extends RigidBody var view_sensitivity = 0.25 -var yaw = 0 -var pitch = 0 # Walking speed and jumping height are defined later. var walk_speed = 0.8 # Actually acceleration; m/s/s @@ -29,19 +27,21 @@ slave var slave_transform = Basis() slave var slave_lin_v = Vector3() slave var slave_ang_v = Vector3() +export(NodePath) var tp_camera +export(NodePath) var master_only + func _ready(): + + tp_camera = get_node(tp_camera) + master_only = get_node(master_only) + set_process_input(true) - - # Capture mouse once game is started: - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - debug_node = get_node("/root/Level/Debug") - if is_network_master(): - get_node("Yaw/Pitch/Camera").make_current() + tp_camera.set_enabled(true) spawn() else: - remove_child(get_node("MasterOnly")) + remove_child(master_only) func spawn(): var placement = Vector3() @@ -60,17 +60,6 @@ func spawn(): set_linear_velocity(Vector3()) func _input(event): - if is_network_master(): - - if event is InputEventMouseMotion: - yaw = fmod(yaw - event.relative.x * view_sensitivity, 360) - pitch = max(min(pitch - event.relative.y * view_sensitivity, 85), -85) - set_rotation() - - # Toggle mouse capture: - if Input.is_action_pressed("toggle_mouse_capture"): - toggle_mouse_capture() - if Input.is_action_just_pressed("switch_hero"): switch_hero_interface() # Quit the game: @@ -85,30 +74,31 @@ func toggle_mouse_capture(): Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) view_sensitivity = 0.25 +# Update visual yaw + pitch components to match camera func set_rotation(): - get_node("Yaw").set_rotation(Vector3(0, deg2rad(yaw), 0)) - get_node("Yaw/Pitch").set_rotation(Vector3(deg2rad(pitch), 0, 0)) + get_node("Yaw").set_rotation(Vector3(0, deg2rad(tp_camera.cam_yaw), 0)) + get_node("Yaw/Pitch").set_rotation(Vector3(deg2rad(tp_camera.cam_pitch), 0, 0)) func _integrate_forces(state): if is_network_master(): control_player(state) rpc_unreliable("set_status", get_status()) + set_rotation() slave func set_status(s): set_transform(s[0]) set_linear_velocity(s[1]) set_angular_velocity(s[2]) - yaw = s[3] - pitch = s[4] - set_rotation() # Confirm yaw + pitch changes + tp_camera.cam_yaw = s[3] + tp_camera.cam_pitch = s[4] func get_status(): return [ get_transform(), get_linear_velocity(), get_angular_velocity(), - yaw, - pitch, + tp_camera.cam_yaw, + tp_camera.cam_pitch, ] func control_player(state): diff --git a/scripts/tp_camera.gd b/scripts/tp_camera.gd new file mode 100644 index 0000000..1212f2b --- /dev/null +++ b/scripts/tp_camera.gd @@ -0,0 +1,121 @@ +# From khairul169: https://github.com/khairul169/3rdperson-godot/blob/master/assets/scripts/tpscam.gd + +extends Spatial + +var cam_pitch = 0.0; +var cam_yaw = 0.0; +var cam_cpitch = 0.0; +var cam_cyaw = 0.0; +var cam_currentradius = 2.0; +var cam_radius = 2.0; +var cam_pos = Vector3(); +var cam_ray_result = {}; +var cam_smooth_movement = true; +var cam_fov = 60.0; +var cam_view_sensitivity = 0.3; +var cam_smooth_lerp = 10; +var cam_pitch_minmax = Vector2(90, -90); + +var is_enabled = false; +var collision_exception = []; + +export(NodePath) var cam; +export(NodePath) var pivot; + +func _ready(): + cam = get_node(cam); + pivot = get_node(pivot); + + cam_fov = cam.get_fov(); + +func set_enabled(enabled): + if enabled: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED); + set_process(true); + cam.make_current() + is_enabled = true; + else: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE); + set_process(false); + is_enabled = false; + +func clear_exception(): + collision_exception.clear(); + +func add_collision_exception(node): + collision_exception.push_back(node); + +func _input(ie): + if !is_enabled: + return; + + if ie is InputEventMouseMotion: + cam_pitch = max(min(cam_pitch+(ie.relative.y*cam_view_sensitivity),cam_pitch_minmax.x),cam_pitch_minmax.y); + if cam_smooth_movement: + cam_yaw = cam_yaw-(ie.relative.x*cam_view_sensitivity); + else: + cam_yaw = fmod(cam_yaw-(ie.relative.x*cam_view_sensitivity),360); + cam_currentradius = cam_radius; + cam_update(); + + if ie is InputEventMouseButton: + if ie.pressed: + if ie.button_index == BUTTON_WHEEL_UP: + cam_radius = max(min(cam_radius-0.2,4.0),1.0); + elif ie.button_index == BUTTON_WHEEL_DOWN: + cam_radius = max(min(cam_radius+0.2,4.0),1.0); + + # Toggle mouse capture: + if Input.is_action_just_pressed("toggle_mouse_capture"): + set_enabled(!is_enabled) + +func _process(delta): + if !is_enabled: + return; + + if !cam.is_current(): + cam.make_current(); + + if cam.get_projection() == Camera.PROJECTION_PERSPECTIVE: + cam.set_perspective(lerp(cam.get_fov(), cam_fov, cam_smooth_lerp*delta), cam.get_znear(), cam.get_zfar()); + + if cam_smooth_movement: + cam_cpitch = lerp(cam_cpitch, cam_pitch, 10*delta); + cam_cyaw = lerp(cam_cyaw, cam_yaw, 10*delta); + cam_currentradius = lerp(cam_currentradius, cam_radius, 5*delta); + + cam_update(); + +func cam_update(): + cam_pos = pivot.get_global_transform().origin; + + if cam_smooth_movement: + cam_pos.x += cam_currentradius * sin(deg2rad(cam_cyaw)) * cos(deg2rad(cam_cpitch)); + cam_pos.y += cam_currentradius * sin(deg2rad(cam_cpitch)); + cam_pos.z += cam_currentradius * cos(deg2rad(cam_cyaw)) * cos(deg2rad(cam_cpitch)); + else: + cam_pos.x += cam_currentradius * sin(deg2rad(cam_yaw)) * cos(deg2rad(cam_pitch)); + cam_pos.y += cam_currentradius * sin(deg2rad(cam_pitch)); + cam_pos.z += cam_currentradius * cos(deg2rad(cam_yaw)) * cos(deg2rad(cam_pitch)); + + var pos = Vector3(); + + if cam_ray_result.size() != 0: + print("re-pos, ray found") + var a = (cam_ray_result.position-pivot.get_global_transform().origin).normalized(); + var b = pivot.get_global_transform().origin.distance_to(cam_ray_result.position); + #pos = cam_ray_result.position; + pos = pivot.get_global_transform().origin+a*max(b-0.1, 0); + else: + pos = cam_pos; + + cam.look_at_from_position(pos, pivot.get_global_transform().origin, Vector3(0,1,0)); + +func _physics_process(delta): + if !is_enabled: + return; + + var ds = get_world().get_direct_space_state(); + if ds != null: + cam_ray_result = ds.intersect_ray(pivot.get_global_transform().origin, cam_pos, collision_exception); + #print(cam_ray_result)