Make ShootyEnemy cycle between targets by velocity
This commit is contained in:
parent
3bb4ed31e6
commit
7a96f549ff
@ -1,5 +1,8 @@
|
|||||||
extends KinematicBody
|
extends KinematicBody
|
||||||
|
|
||||||
|
# An enemy which shoots at the future player position and moves between two targets within a given
|
||||||
|
# amount of time.
|
||||||
|
|
||||||
|
|
||||||
export(NodePath) var player_node
|
export(NodePath) var player_node
|
||||||
onready var player = get_node(player_node)
|
onready var player = get_node(player_node)
|
||||||
@ -7,46 +10,83 @@ onready var player = get_node(player_node)
|
|||||||
export(NodePath) var solar_system_node
|
export(NodePath) var solar_system_node
|
||||||
onready var solar_system = get_node(solar_system_node)
|
onready var solar_system = get_node(solar_system_node)
|
||||||
|
|
||||||
|
export(Array, NodePath) var target_paths
|
||||||
|
|
||||||
|
export var target_fly_time := 5.0
|
||||||
|
var time_passed_since_fly_start := 0.0
|
||||||
|
var current_target_index = 0
|
||||||
|
|
||||||
var bullet_scene = preload("res://Bullet.tscn")
|
var bullet_scene = preload("res://Bullet.tscn")
|
||||||
var bullet_velocity = 40.0
|
var bullet_velocity = 40.0
|
||||||
|
|
||||||
var target
|
var shoot_target
|
||||||
var velocity := Vector3(0.0, 1.0, 1.0)
|
var velocity := Vector3.ZERO
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# Shoot everytime the timer times out
|
||||||
$ShotTimer.connect("timeout", self, "shoot_bullet")
|
$ShotTimer.connect("timeout", self, "shoot_bullet")
|
||||||
|
|
||||||
|
# Set up pathing: Start at the first target
|
||||||
|
global_transform.origin = get_node(target_paths[0]).global_transform.origin
|
||||||
|
_set_velocity_to_fly_towards_next_target()
|
||||||
|
|
||||||
|
|
||||||
|
# Picks the next target position from the `target_paths` list and set the `velocity` appropriately
|
||||||
|
# so that the target will be reached after `target_fly_time`.
|
||||||
|
func _set_velocity_to_fly_towards_next_target():
|
||||||
|
current_target_index = (current_target_index + 1) % target_paths.size()
|
||||||
|
|
||||||
|
# Vector from here to the new target
|
||||||
|
var vector_to_next = (get_node(target_paths[current_target_index]).global_transform.origin
|
||||||
|
- global_transform.origin)
|
||||||
|
|
||||||
|
# s = v * t --> v = s / t
|
||||||
|
velocity = vector_to_next / target_fly_time
|
||||||
|
time_passed_since_fly_start = 0.0
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
# Project the player's position into the future
|
# Project the player's position into the future
|
||||||
target = _get_future_position(
|
shoot_target = _get_future_position(
|
||||||
player.get_center(),
|
player.get_center(),
|
||||||
player.velocity - velocity
|
player.velocity - velocity
|
||||||
)
|
)
|
||||||
|
|
||||||
if target:
|
# Look at the target that will be shot at, with the gravity as the down vector
|
||||||
|
if shoot_target:
|
||||||
var gravity = solar_system.get_gravity_acceleration(global_transform.origin)
|
var gravity = solar_system.get_gravity_acceleration(global_transform.origin)
|
||||||
look_at(target, gravity)
|
look_at(shoot_target, gravity)
|
||||||
|
|
||||||
|
# Have we rearched the target?
|
||||||
|
time_passed_since_fly_start += delta
|
||||||
|
if time_passed_since_fly_start >= target_fly_time:
|
||||||
|
# If so, fly towards the next target
|
||||||
|
_set_velocity_to_fly_towards_next_target()
|
||||||
|
|
||||||
|
# Apply velocity
|
||||||
global_transform.origin += velocity * delta
|
global_transform.origin += velocity * delta
|
||||||
|
|
||||||
|
|
||||||
func shoot_bullet():
|
func shoot_bullet():
|
||||||
if not target:
|
if not shoot_target:
|
||||||
# Player can't be hit right now, abort
|
# Player can't be hit right now, abort
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Add a bullet
|
||||||
var instance = bullet_scene.instance()
|
var instance = bullet_scene.instance()
|
||||||
get_tree().get_root().add_child(instance)
|
get_tree().get_root().add_child(instance)
|
||||||
|
|
||||||
|
# Make the bullet start at the current position of this object and fly towards the target.
|
||||||
|
# The own velocity is added because of galilean relativity.
|
||||||
instance.global_transform.origin = global_transform.origin - global_transform.basis.z
|
instance.global_transform.origin = global_transform.origin - global_transform.basis.z
|
||||||
instance.velocity = velocity + (target - global_transform.origin).normalized() * bullet_velocity
|
instance.velocity = velocity + (shoot_target - global_transform.origin).normalized() * bullet_velocity
|
||||||
|
|
||||||
|
|
||||||
|
# Return the position at which a bullet fired forwards and with the velocity `bullet_velocity` would
|
||||||
|
# intersect with the object that is at `position` and moving with the given `velocity`
|
||||||
func _get_future_position(position, velocity):
|
func _get_future_position(position, velocity):
|
||||||
# Solution to the quadratic formula gives us the time at which the player would be hit
|
# Solution to the quadratic formula gives us the time at which the player would be hit
|
||||||
# TODO: Take acceleration into account as well!
|
|
||||||
var a = pow(velocity.x, 2) + pow(velocity.y, 2) + pow(velocity.z, 2) - pow(bullet_velocity, 2)
|
var a = pow(velocity.x, 2) + pow(velocity.y, 2) + pow(velocity.z, 2) - pow(bullet_velocity, 2)
|
||||||
var b = 2 * (velocity.x * (position.x - global_transform.origin.x)
|
var b = 2 * (velocity.x * (position.x - global_transform.origin.x)
|
||||||
+ velocity.y * (position.y - global_transform.origin.y)
|
+ velocity.y * (position.y - global_transform.origin.y)
|
||||||
@ -67,4 +107,5 @@ func _get_future_position(position, velocity):
|
|||||||
var t = min(t1, t2)
|
var t = min(t1, t2)
|
||||||
if t < 0: t = max(t1, t2)
|
if t < 0: t = max(t1, t2)
|
||||||
|
|
||||||
|
# Return the position given by the time we calculated
|
||||||
return position + t * velocity
|
return position + t * velocity
|
||||||
|
@ -190,10 +190,17 @@ environment = SubResource( 11 )
|
|||||||
transform = Transform( 0.866025, -0.353553, 0.353553, 0, 0.707107, 0.707107, -0.5, -0.612372, 0.612372, 0, 10, 0 )
|
transform = Transform( 0.866025, -0.353553, 0.353553, 0, 0.707107, 0.707107, -0.5, -0.612372, 0.612372, 0, 10, 0 )
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
|
|
||||||
|
[node name="EnemyPos1" type="Position3D" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8, 20 )
|
||||||
|
|
||||||
|
[node name="EnemyPos2" type="Position3D" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -46.5073, 54.1815, 76.6368 )
|
||||||
|
|
||||||
[node name="ShootyEnemy" parent="." instance=ExtResource( 6 )]
|
[node name="ShootyEnemy" parent="." instance=ExtResource( 6 )]
|
||||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8, 20 )
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8, 20 )
|
||||||
player_node = NodePath("../Player")
|
player_node = NodePath("../Player")
|
||||||
solar_system_node = NodePath("../Planets")
|
solar_system_node = NodePath("../Planets")
|
||||||
|
target_paths = [ NodePath("../EnemyPos1"), NodePath("../EnemyPos2") ]
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource( 1 )]
|
[node name="Player" parent="." instance=ExtResource( 1 )]
|
||||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 0 )
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 0 )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user