Răsfoiți Sursa

Convert 3D navmesh demo to use NavigationAgents (#806)

Co-authored-by: smix8 <[email protected]>
David Briscoe 2 ani în urmă
părinte
comite
ccc4354331

+ 44 - 0
3d/navmesh/character.gd

@@ -0,0 +1,44 @@
+extends Spatial
+
+const Line3D = preload("res://line3d.gd")
+
+
+export(float) var character_speed = 10.0
+export var show_path = true
+
+onready var _nav_agent = $NavigationAgent
+onready var _nav_path_line = $Line3D
+
+
+func _ready():
+	_nav_path_line.set_as_toplevel(true)
+
+
+func _physics_process(delta):
+	if _nav_agent.is_navigation_finished():
+		return
+	var next_position = _nav_agent.get_next_location()
+	var offset = next_position - global_translation
+	global_translation = global_translation.move_toward(next_position, delta * character_speed)
+
+	# Make the robot look at the direction we're traveling.
+	# Clamp y to 0 so the robot only looks left and right, not up/down.
+	offset.y = 0
+	look_at(global_translation + offset, Vector3.UP)
+
+
+func set_target_location(target_location: Vector3):
+	_nav_agent.set_target_location(target_location)
+	# get a full navigation path with the NavigationServer API
+	if show_path:
+		var start_position = global_transform.origin
+		var target_position = target_location
+		var optimize = true
+		var navigation_map = get_world().get_navigation_map()
+		var path = NavigationServer.map_get_path(
+				navigation_map,
+				start_position,
+				target_position,
+				optimize)
+		_nav_path_line.draw_path(path)
+

+ 23 - 0
3d/navmesh/line3d.gd

@@ -0,0 +1,23 @@
+extends ImmediateGeometry
+
+
+var _material := SpatialMaterial.new()
+
+
+func _ready():
+	_material.flags_unshaded = true
+	_material.flags_use_point_size = true
+	_material.albedo_color = Color.white
+
+
+func draw_path(path):
+	set_material_override(_material)
+	clear()
+	begin(Mesh.PRIMITIVE_POINTS, null)
+	add_vertex(path[0])
+	add_vertex(path[path.size() - 1])
+	end()
+	begin(Mesh.PRIMITIVE_LINE_STRIP, null)
+	for x in path:
+		add_vertex(x)
+	end()

+ 31 - 0
3d/navmesh/navigation.gd

@@ -0,0 +1,31 @@
+extends Spatial
+
+
+var _cam_rotation = 0.0
+
+onready var _camera = $CameraBase/Camera as Camera
+onready var _robot = $RobotBase as Spatial
+
+
+func _unhandled_input(event: InputEvent):
+	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
+		# get closest point on navmesh for the current mouse cursor position
+		var mouse_cursor_position = event.position
+		var camera_ray_length = 1000.0
+		var camera_ray_start = _camera.project_ray_origin(mouse_cursor_position)
+		var camera_ray_end = camera_ray_start + _camera.project_ray_normal(mouse_cursor_position) * camera_ray_length
+		var navigation_map = get_world().get_navigation_map()
+
+		var closest_point_on_navmesh = NavigationServer.map_get_closest_point_to_segment(
+			navigation_map,
+			camera_ray_start,
+			camera_ray_end
+			)
+		_robot.set_target_location(closest_point_on_navmesh)
+
+	if event is InputEventMouseMotion:
+		if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT):
+			_cam_rotation += event.relative.x * 0.005
+			$CameraBase.set_rotation(Vector3.UP * _cam_rotation)
+			print("Camera Rotation: ", _cam_rotation)
+

+ 0 - 117
3d/navmesh/navmesh.gd

@@ -1,117 +0,0 @@
-extends Spatial
-
-
-const SPEED = 10.0
-
-var camrot = 0.0
-var m = SpatialMaterial.new()
-
-var map
-
-var path = []
-var show_path = true
-
-onready var robot  = get_node("RobotBase")
-onready var camera = get_node("CameraBase/Camera")
-
-
-func _ready():
-	set_process_input(true)
-	m.flags_unshaded = true
-	m.flags_use_point_size = true
-	m.albedo_color = Color.white
-
-	# use call deferred to make sure the entire SceneTree Nodes are setup
-	# else yield on 'physics_frame' in a _ready() might get stuck
-	call_deferred("setup_navserver")
-
-
-func _physics_process(delta):
-	var direction = Vector3()
-
-	# We need to scale the movement speed by how much delta has passed,
-	# otherwise the motion won't be smooth.
-	var step_size = delta * SPEED
-
-	if path.size() > 0:
-		# Direction is the difference between where we are now
-		# and where we want to go.
-		var destination = path[0]
-		direction = destination - robot.translation
-
-		# If the next node is closer than we intend to 'step', then
-		# take a smaller step. Otherwise we would go past it and
-		# potentially go through a wall or over a cliff edge!
-		if step_size > direction.length():
-			step_size = direction.length()
-			# We should also remove this node since we're about to reach it.
-			path.remove(0)
-
-		# Move the robot towards the path node, by how far we want to travel.
-		# Note: For a KinematicBody, we would instead use move_and_slide
-		# so collisions work properly.
-		robot.translation += direction.normalized() * step_size
-
-		# Lastly let's make sure we're looking in the direction we're traveling.
-		# Clamp y to 0 so the robot only looks left and right, not up/down.
-		direction.y = 0
-		if direction:
-			# Direction is relative, so apply it to the robot's location to
-			# get a point we can actually look at.
-			var look_at_point = robot.translation + direction.normalized()
-			# Make the robot look at the point.
-			robot.look_at(look_at_point, Vector3.UP)
-
-
-func setup_navserver():
-	# create a new navigation map
-	map = NavigationServer.map_create()
-	NavigationServer.map_set_up(map, Vector3.UP)
-	NavigationServer.map_set_active(map, true)
-
-	# create a new navigation region and add it to the map
-	var region = NavigationServer.region_create()
-	NavigationServer.region_set_transform(region, Transform())
-	NavigationServer.region_set_map(region, map)
-
-	# sets navigation mesh for the region
-	var navigation_mesh = NavigationMesh.new()
-	navigation_mesh = $NavigationMeshInstance_Level.navmesh
-	NavigationServer.region_set_navmesh(region, navigation_mesh)
-
-	# wait for NavigationServer sync to adapt to made changes
-	yield(get_tree(), "physics_frame")
-
-
-func _unhandled_input(event):
-	if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
-		var from = camera.project_ray_origin(event.position)
-		var to = from + camera.project_ray_normal(event.position) * 1000
-		var target_point = NavigationServer.map_get_closest_point_to_segment(map, from, to)
-		var optimize_path = true
-
-		# Set the path between the robots current location and our target.
-		path = NavigationServer.map_get_path(map,robot.translation, target_point, optimize_path)
-
-		if show_path:
-			draw_path(path)
-
-	if event is InputEventMouseMotion:
-		if event.button_mask & (BUTTON_MASK_MIDDLE + BUTTON_MASK_RIGHT):
-			camrot += event.relative.x * 0.005
-			get_node("CameraBase").set_rotation(Vector3(0, camrot, 0))
-			print("Camera Rotation: ", camrot)
-
-
-func draw_path(path_array):
-	var im = get_node("Draw")
-	im.set_material_override(m)
-	im.clear()
-	im.begin(Mesh.PRIMITIVE_POINTS, null)
-	im.add_vertex(path_array[0])
-	im.add_vertex(path_array[path_array.size() - 1])
-	im.end()
-	im.begin(Mesh.PRIMITIVE_LINE_STRIP, null)
-	for x in path:
-		im.add_vertex(x)
-	im.end()

Fișier diff suprimat deoarece este prea mare
+ 4 - 2
3d/navmesh/navmesh.tscn


BIN
3d/navmesh/particle.png


+ 0 - 37
3d/navmesh/particle.png.import

@@ -1,37 +0,0 @@
-[remap]
-
-importer="texture"
-type="StreamTexture"
-path.s3tc="res://.import/particle.png-c2ba3d91e96c62035d672392a1197218.s3tc.stex"
-path.etc="res://.import/particle.png-c2ba3d91e96c62035d672392a1197218.etc.stex"
-metadata={
-"imported_formats": [ "s3tc", "etc" ],
-"vram_texture": true
-}
-
-[deps]
-
-source_file="res://particle.png"
-dest_files=[ "res://.import/particle.png-c2ba3d91e96c62035d672392a1197218.s3tc.stex", "res://.import/particle.png-c2ba3d91e96c62035d672392a1197218.etc.stex" ]
-
-[params]
-
-compress/mode=2
-compress/lossy_quality=0.7
-compress/hdr_mode=0
-compress/bptc_ldr=0
-compress/normal_map=0
-flags/repeat=true
-flags/filter=true
-flags/mipmaps=true
-flags/anisotropic=false
-flags/srgb=1
-process/fix_alpha_border=true
-process/premult_alpha=false
-process/HDR_as_SRGB=false
-process/invert_color=false
-process/normal_map_invert_y=false
-stream=false
-size_limit=0
-detect_3d=false
-svg/scale=1.0

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff