Sfoglia il codice sorgente

Merge pull request #436 from aaronfranke/astar-kinematic

Some changes to Astar and Kinematic Character 3D
Aaron Franke 5 anni fa
parent
commit
758f38db67

+ 22 - 21
2d/navigation_astar/character.gd

@@ -1,60 +1,61 @@
-extends Position2D
+extends Node2D
 
 enum States { IDLE, FOLLOW }
 
 export(float) var speed = 200.0
 var _state = null
 
-var path = []
-var target_point_world = Vector2()
-var target_position = Vector2()
+var _path = []
+var _target_point_world = Vector2()
+var _target_position = Vector2()
 
-var velocity = Vector2()
+var _velocity = Vector2()
 
 func _ready():
 	_change_state(States.IDLE)
 
 
 func _process(_delta):
-	if not _state == States.FOLLOW:
+	if _state != States.FOLLOW:
 		return
-	var arrived_to_next_point = move_to(target_point_world)
-	if arrived_to_next_point:
-		path.remove(0)
-		if len(path) == 0:
+	var _arrived_to_next_point = _move_to(_target_point_world)
+	if _arrived_to_next_point:
+		_path.remove(0)
+		if len(_path) == 0:
 			_change_state(States.IDLE)
 			return
-		target_point_world = path[0]
+		_target_point_world = _path[0]
 
 
 func _input(event):
 	if event.is_action_pressed("click"):
+		var global_mouse_pos = get_global_mouse_position()
 		if Input.is_key_pressed(KEY_SHIFT):
-			global_position = get_global_mouse_position()
+			global_position = global_mouse_pos
 		else:
-			target_position = get_global_mouse_position()
+			_target_position = global_mouse_pos
 		_change_state(States.FOLLOW)
 
 
-func move_to(world_position):
+func _move_to(world_position):
 	var MASS = 10.0
 	var ARRIVE_DISTANCE = 10.0
 
 	var desired_velocity = (world_position - position).normalized() * speed
-	var steering = desired_velocity - velocity
-	velocity += steering / MASS
-	position += velocity * get_process_delta_time()
-	rotation = velocity.angle()
+	var steering = desired_velocity - _velocity
+	_velocity += steering / MASS
+	position += _velocity * get_process_delta_time()
+	rotation = _velocity.angle()
 	return position.distance_to(world_position) < ARRIVE_DISTANCE
 
 
 func _change_state(new_state):
 	if new_state == States.FOLLOW:
-		path = get_parent().get_node("TileMap")._get_path(position, target_position)
-		if not path or len(path) == 1:
+		_path = get_parent().get_node("TileMap").get_astar_path(position, _target_position)
+		if not _path or len(_path) == 1:
 			_change_state(States.IDLE)
 			return
 		# The index 0 is the starting cell
 		# we don't want the character to move back to it in this example
-		target_point_world = path[1]
+		_target_point_world = _path[1]
 	_state = new_state

+ 7 - 6
2d/navigation_astar/pathfind_astar.gd

@@ -4,7 +4,7 @@ const BASE_LINE_WIDTH = 3.0
 const DRAW_COLOR = Color.white
 
 # The Tilemap node doesn't have clear bounds so we're defining the map's limits here.
-export(Vector2) var map_size = Vector2(16, 16)
+export(Vector2) var map_size = Vector2.ONE * 16
 
 # The path start and end variables use setter methods.
 # You can find them at the bottom of the script.
@@ -85,10 +85,11 @@ func astar_connect_walkable_cells(points_array):
 		# left and bottom of it. If it's in the map and not an obstalce.
 		# We connect the current point with it.
 		var points_relative = PoolVector2Array([
-			Vector2(point.x + 1, point.y),
-			Vector2(point.x - 1, point.y),
-			Vector2(point.x, point.y + 1),
-			Vector2(point.x, point.y - 1)])
+			point + Vector2.RIGHT,
+			point + Vector2.LEFT,
+			point + Vector2.DOWN,
+			point + Vector2.UP,
+		])
 		for point_relative in points_relative:
 			var point_relative_index = calculate_point_index(point_relative)
 			if is_outside_map_bounds(point_relative):
@@ -135,7 +136,7 @@ func is_outside_map_bounds(point):
 	return point.x < 0 or point.y < 0 or point.x >= map_size.x or point.y >= map_size.y
 
 
-func _get_path(world_start, world_end):
+func get_astar_path(world_start, world_end):
 	self.path_start_position = world_to_map(world_start)
 	self.path_end_position = world_to_map(world_end)
 	_recalculate_path()

+ 36 - 33
3d/kinematic_character/cubio.gd

@@ -1,55 +1,58 @@
-
 extends KinematicBody
 
-# Member variables
-var g = -9.8
-var vel: Vector3
 const MAX_SPEED = 5
 const JUMP_SPEED = 7
-const ACCEL= 2
-const DEACCEL= 4
+const ACCELERATION = 2
+const DECELERATION = 4
 const MAX_SLOPE_ANGLE = 30
 
+onready var gravity = -ProjectSettings.get_setting("physics/3d/default_gravity")
+var velocity: Vector3
 
 func _physics_process(delta):
+	if Input.is_action_just_pressed("exit"):
+		get_tree().quit()
 	if Input.is_action_just_pressed("reset_position"):
 		translation = Vector3(-3, 4, 8)
-	var dir = Vector3() # Where does the player intend to walk to
-	var cam_xform = $Target/Camera.get_global_transform()
-
-	if Input.is_action_pressed("move_forward"):
-		dir += -cam_xform.basis[2]
-	if Input.is_action_pressed("move_backwards"):
-		dir += cam_xform.basis[2]
-	if Input.is_action_pressed("move_left"):
-		dir += -cam_xform.basis[0]
-	if Input.is_action_pressed("move_right"):
-		dir += cam_xform.basis[0]
-
-	dir.y = 0
-	dir = dir.normalized()
-
-	vel.y += delta * g
-
-	var hvel = vel
+	
+	var dir = Vector3()
+	dir.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
+	dir.z = Input.get_action_strength("move_back") - Input.get_action_strength("move_forward")
+	
+	# Get the camera's transform basis, but remove the X rotation such
+	# that the Y axis is up and Z is horizontal.
+	var cam_basis = $Target/Camera.global_transform.basis
+	var basis = cam_basis.rotated(cam_basis.x, -cam_basis.get_euler().x)
+	dir = basis.xform(dir)
+	
+	# Limit the input to a length of 1. length_squared is faster to check.
+	if dir.length_squared() > 1:
+		dir /= dir.length()
+
+	# Apply gravity.
+	velocity.y += delta * gravity
+
+	# Using only the horizontal velocity, interpolate towards the input.
+	var hvel = velocity
 	hvel.y = 0
 
 	var target = dir * MAX_SPEED
-	var accel
+	var acceleration
 	if dir.dot(hvel) > 0:
-		accel = ACCEL
+		acceleration = ACCELERATION
 	else:
-		accel = DEACCEL
-
-	hvel = hvel.linear_interpolate(target, accel * delta)
+		acceleration = DECELERATION
 
-	vel.x = hvel.x
-	vel.z = hvel.z
+	hvel = hvel.linear_interpolate(target, acceleration * delta)
 
-	vel = move_and_slide(vel, Vector3.UP)
+	# Assign hvel's values back to velocity, and then move.
+	velocity.x = hvel.x
+	velocity.z = hvel.z
+	velocity = move_and_slide(velocity, Vector3.UP)
 
+	# Jumping code. is_on_floor() must come after move_and_slide().
 	if is_on_floor() and Input.is_action_pressed("jump"):
-		vel.y = JUMP_SPEED
+		velocity.y = JUMP_SPEED
 
 
 func _on_tcube_body_entered(body):

+ 17 - 1
3d/kinematic_character/project.godot

@@ -28,35 +28,51 @@ singletons=[  ]
 jump={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
  ]
 }
-move_backwards={
+move_back={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
  ]
 }
 move_forward={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
  ]
 }
 move_left={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
  ]
 }
 move_right={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
 , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null)
+, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
  ]
 }
 reset_position={
 "deadzone": 0.5,
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
+ ]
+}
+exit={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null)
+, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
  ]
 }