Add shooting enemy which shoots at future player pos
Works fairly well, although it doesn't account for changing acceleration which happens due to the changing gravity. I guess this is good enough, since it does hit if the player isn't careful
This commit is contained in:
parent
9401fc9c97
commit
219c8731f5
28
Bullet.gd
Normal file
28
Bullet.gd
Normal file
@ -0,0 +1,28 @@
|
||||
extends Spatial
|
||||
|
||||
|
||||
var target := Vector3.ZERO
|
||||
|
||||
var acceleration := Vector3.ZERO
|
||||
var velocity := Vector3.ZERO
|
||||
|
||||
export var acceleration_factor = 5.0
|
||||
export var accelerating := false
|
||||
|
||||
|
||||
func _ready():
|
||||
$HitArea.connect("body_entered", self, "_on_hit_body")
|
||||
|
||||
|
||||
func _on_hit_body(body):
|
||||
if body.name == "Player":
|
||||
print("Player hit!")
|
||||
|
||||
|
||||
func _process(delta):
|
||||
if accelerating:
|
||||
var direction = (target - global_transform.origin).normalized()
|
||||
acceleration += direction * acceleration_factor * delta
|
||||
velocity += acceleration
|
||||
|
||||
global_transform.origin += velocity * delta
|
23
Bullet.tscn
Normal file
23
Bullet.tscn
Normal file
File diff suppressed because one or more lines are too long
@ -33,5 +33,3 @@ func _process(delta):
|
||||
# Limit at length 1
|
||||
if input.length() > 1.0:
|
||||
input /= input.length()
|
||||
|
||||
print(input)
|
||||
|
@ -30,8 +30,6 @@ func _process(delta):
|
||||
|
||||
velocity = (translation - translation_before) / delta
|
||||
|
||||
print(velocity)
|
||||
|
||||
# Rotate according to gravity
|
||||
var gravity_acceleration = get_node(solar_system).get_gravitation_acceleration(global_transform.origin)
|
||||
|
||||
|
@ -10,7 +10,7 @@ const distance_multiplier = 318550 # thus, a radius of 20 results in an earth-
|
||||
|
||||
# If the gravity doesn't feel like it should, this scales it. A higher value means that the pull is
|
||||
# stronger.
|
||||
const gravity_multiplier = 5.0
|
||||
const gravity_multiplier = 10.0
|
||||
|
||||
|
||||
func get_gravitation_acceleration(position: Vector3) -> Vector3:
|
||||
|
@ -32,6 +32,10 @@ func _input(event):
|
||||
jumping = false
|
||||
|
||||
|
||||
func get_center():
|
||||
return global_transform.origin + global_transform.basis.y
|
||||
|
||||
|
||||
func apply_acceleration(acceleration):
|
||||
# First drag, then add the new acceleration
|
||||
# For drag: Lerp towards the target velocity
|
||||
|
66
ShootyEnemy.gd
Normal file
66
ShootyEnemy.gd
Normal file
@ -0,0 +1,66 @@
|
||||
extends KinematicBody
|
||||
|
||||
|
||||
export(NodePath) var player_node
|
||||
onready var player = get_node(player_node)
|
||||
|
||||
export(NodePath) var solar_system_node
|
||||
onready var solar_system = get_node(solar_system_node)
|
||||
|
||||
var bullet_scene = preload("res://Bullet.tscn")
|
||||
var bullet_velocity = 40.0
|
||||
|
||||
var target
|
||||
|
||||
|
||||
func _ready():
|
||||
$ShotTimer.connect("timeout", self, "shoot_bullet")
|
||||
|
||||
|
||||
func _process(delta):
|
||||
# Project the player's position into the future
|
||||
target = _get_future_position(
|
||||
player.get_center(),
|
||||
player.velocity
|
||||
)
|
||||
|
||||
if target:
|
||||
var gravity = solar_system.get_gravitation_acceleration(global_transform.origin)
|
||||
look_at(target, gravity)
|
||||
|
||||
|
||||
func shoot_bullet():
|
||||
if not target:
|
||||
# Player can't be hit right now, abort
|
||||
return
|
||||
|
||||
var instance = bullet_scene.instance()
|
||||
get_tree().get_root().add_child(instance)
|
||||
|
||||
instance.global_transform.origin = global_transform.origin
|
||||
instance.velocity = (target - global_transform.origin).normalized() * bullet_velocity
|
||||
|
||||
|
||||
func _get_future_position(position, velocity):
|
||||
# Solution to the quadratic formula gives us the time at which the player would be hit
|
||||
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)
|
||||
+ velocity.y * (position.y - global_transform.origin.y)
|
||||
+ velocity.z * (position.z - global_transform.origin.z))
|
||||
|
||||
var c = pow(position.x - global_transform.origin.x, 2.0) \
|
||||
+ pow(position.y - global_transform.origin.y, 2.0) \
|
||||
+ pow(position.z - global_transform.origin.z, 2.0)
|
||||
|
||||
var discriminant = pow(b, 2) - 4 * a * c
|
||||
|
||||
if (discriminant < 0): return null # Can't hit the target :(
|
||||
|
||||
var t1 = (-b + sqrt(discriminant)) / (2 * a)
|
||||
var t2 = (-b - sqrt(discriminant)) / (2 * a)
|
||||
|
||||
# Choose the smallest positive t value
|
||||
var t = min(t1, t2)
|
||||
if t < 0: t = max(t1, t2)
|
||||
|
||||
return position + t * velocity
|
24
ShootyEnemy.tscn
Normal file
24
ShootyEnemy.tscn
Normal file
@ -0,0 +1,24 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://ShootyEnemy.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="PrismMesh" id=1]
|
||||
|
||||
[sub_resource type="ConcavePolygonShape" id=2]
|
||||
data = PoolVector3Array( 0, 1, 1, 1, -1, 1, -1, -1, 1, 0, 1, -1, -1, -1, -1, 1, -1, -1, 0, 1, 1, 0, 1, -1, 1, -1, 1, 0, 1, -1, 1, -1, -1, 1, -1, 1, 0, 1, -1, 0, 1, 1, -1, -1, -1, 0, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1 )
|
||||
|
||||
[node name="ShootyEnemy" type="KinematicBody"]
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0 )
|
||||
mesh = SubResource( 1 )
|
||||
material/0 = null
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0 )
|
||||
shape = SubResource( 2 )
|
||||
|
||||
[node name="ShotTimer" type="Timer" parent="."]
|
||||
process_mode = 0
|
||||
autostart = true
|
31
World.tscn
31
World.tscn
@ -1,10 +1,11 @@
|
||||
[gd_scene load_steps=18 format=2]
|
||||
[gd_scene load_steps=19 format=2]
|
||||
|
||||
[ext_resource path="res://Player.gd" type="Script" id=1]
|
||||
[ext_resource path="res://Planets.gd" type="Script" id=2]
|
||||
[ext_resource path="res://Planet.gd" type="Script" id=3]
|
||||
[ext_resource path="res://PlanetMaterial.tres" type="Material" id=4]
|
||||
[ext_resource path="res://MovingPlatform.gd" type="Script" id=5]
|
||||
[ext_resource path="res://ShootyEnemy.tscn" type="PackedScene" id=6]
|
||||
|
||||
[sub_resource type="CubeMesh" id=1]
|
||||
size = Vector3( 4, 0.5, 4 )
|
||||
@ -106,13 +107,14 @@ glow_bloom = 0.1
|
||||
[node name="World" type="Spatial"]
|
||||
|
||||
[node name="MovingPlatformPivot" type="Position3D" parent="."]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -20, 0 )
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -125, 37, 60 )
|
||||
|
||||
[node name="MovingPlatform" type="KinematicBody" parent="MovingPlatformPivot" groups=[
|
||||
"MovingPlatform",
|
||||
]]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 30, 0 )
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 60, 0 )
|
||||
script = ExtResource( 5 )
|
||||
move_speed = 5.0
|
||||
solar_system = NodePath("../../Planets")
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="MovingPlatformPivot/MovingPlatform"]
|
||||
@ -139,16 +141,28 @@ material/0 = null
|
||||
[node name="CollisionShape" type="CollisionShape" parent="Planets/Earth"]
|
||||
shape = SubResource( 7 )
|
||||
|
||||
[node name="StaticBody" type="StaticBody" parent="Planets"]
|
||||
[node name="Mars" type="StaticBody" parent="Planets"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -20, 37, 30 )
|
||||
script = ExtResource( 3 )
|
||||
mass = 5.0
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="Planets/StaticBody"]
|
||||
[node name="MeshInstance" type="MeshInstance" parent="Planets/Mars"]
|
||||
mesh = SubResource( 8 )
|
||||
material/0 = ExtResource( 4 )
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="Planets/StaticBody"]
|
||||
[node name="CollisionShape" type="CollisionShape" parent="Planets/Mars"]
|
||||
shape = SubResource( 9 )
|
||||
|
||||
[node name="Jupiter" type="StaticBody" parent="Planets"]
|
||||
transform = Transform( 3, 0, 0, 0, 3, 0, 0, 0, 3, -125, 37, 60 )
|
||||
script = ExtResource( 3 )
|
||||
mass = 40.0
|
||||
|
||||
[node name="MeshInstance" type="MeshInstance" parent="Planets/Jupiter"]
|
||||
mesh = SubResource( 8 )
|
||||
material/0 = ExtResource( 4 )
|
||||
|
||||
[node name="CollisionShape" type="CollisionShape" parent="Planets/Jupiter"]
|
||||
shape = SubResource( 9 )
|
||||
|
||||
[node name="Player" type="KinematicBody" parent="."]
|
||||
@ -176,3 +190,8 @@ environment = SubResource( 12 )
|
||||
[node name="DirectionalLight" type="DirectionalLight" parent="WorldEnvironment"]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 10, 0 )
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="ShootyEnemy" parent="." instance=ExtResource( 6 )]
|
||||
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8, 20 )
|
||||
player_node = NodePath("../Player")
|
||||
solar_system_node = NodePath("../Planets")
|
||||
|
Loading…
x
Reference in New Issue
Block a user