homing projectiles
This commit is contained in:
@@ -12,14 +12,24 @@ public class SpawnProjectileBehavior(PackedScene projectileScene) : IAbilityBeha
|
|||||||
{
|
{
|
||||||
public void OnStarted(AbilityBehaviorContext context)
|
public void OnStarted(AbilityBehaviorContext context)
|
||||||
{
|
{
|
||||||
if (context.Target is not Node3D target || context.Source is not Node3D source) return;
|
if (context.Target is not Node3D target || context.Source is not Node3D source)
|
||||||
|
{
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var sourceLocation = source.GlobalPosition;
|
var sourceLocation = source.GlobalPosition;
|
||||||
|
|
||||||
if (projectileScene.Instantiate() is not Projectile projectile) return;
|
if (projectileScene.Instantiate() is not Projectile projectile)
|
||||||
|
{
|
||||||
|
context.InstanceHandle.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
source.GetTree().GetCurrentScene().AddChild(projectile);
|
source.GetTree().GetCurrentScene().AddChild(projectile);
|
||||||
|
|
||||||
projectile.GlobalPosition = source is ITargetable targetable ? targetable.GetTargetGlobalPosition() : sourceLocation;
|
var startPos = source is ITargetable targetable ? targetable.GetTargetGlobalPosition() : sourceLocation;
|
||||||
|
projectile.GlobalPosition = startPos + Vector3.Up;
|
||||||
projectile.Target = target;
|
projectile.Target = target;
|
||||||
if (projectile is ISpawnable spawnable) spawnable.Init();
|
if (projectile is ISpawnable spawnable) spawnable.Init();
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ InitialStack = SubResource("Resource_hgi6f")
|
|||||||
Cues = []
|
Cues = []
|
||||||
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
metadata/_custom_type_script = "uid://b83hf13nj37k3"
|
||||||
|
|
||||||
[sub_resource type="ViewportTexture" id="ViewportTexture_f6vvi"]
|
[sub_resource type="ViewportTexture" id="ViewportTexture_xabdf"]
|
||||||
viewport_path = NodePath("SubViewport")
|
viewport_path = NodePath("SubViewport")
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_6d4gl"]
|
[sub_resource type="Resource" id="Resource_6d4gl"]
|
||||||
@@ -240,7 +240,7 @@ metadata/_custom_type_script = "uid://dps0oef50noil"
|
|||||||
|
|
||||||
[node name="CHealthBar" parent="." unique_id=1278247727 instance=ExtResource("9_6ew2r")]
|
[node name="CHealthBar" parent="." unique_id=1278247727 instance=ExtResource("9_6ew2r")]
|
||||||
transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
|
transform = Transform3D(0.4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0)
|
||||||
texture = SubResource("ViewportTexture_f6vvi")
|
texture = SubResource("ViewportTexture_xabdf")
|
||||||
|
|
||||||
[node name="CMovement" parent="." unique_id=1080640834 node_paths=PackedStringArray("WallInFrontRayCast") instance=ExtResource("10_d3cra")]
|
[node name="CMovement" parent="." unique_id=1080640834 node_paths=PackedStringArray("WallInFrontRayCast") instance=ExtResource("10_d3cra")]
|
||||||
RMovement = SubResource("Resource_6d4gl")
|
RMovement = SubResource("Resource_6d4gl")
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public record struct EmpoweredActionPayload;
|
|||||||
|
|
||||||
|
|
||||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
|
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_character.png"), Meta(typeof(IAutoNode))]
|
||||||
public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandler, IDisposable
|
public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandler, IDisposable, ITargetable
|
||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
@@ -2708,4 +2708,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
public void OnUpdate(IForgeEntity? target, CueParameters? parameters)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3 GetTargetGlobalPosition()
|
||||||
|
{
|
||||||
|
return HeadSystem.GlobalPosition;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,18 +68,44 @@ public partial class Projectile : RigidBody3D, IForgeEntity, ITargetable, IKilla
|
|||||||
[Node("ForgeEntityNode")] public required ForgeEntityNode ForgeEntity { get; set;}
|
[Node("ForgeEntityNode")] public required ForgeEntityNode ForgeEntity { get; set;}
|
||||||
|
|
||||||
[Export] public float Damage = 10f;
|
[Export] public float Damage = 10f;
|
||||||
|
[Export] public float Speed = 10f;
|
||||||
|
[Export] public float HomingFactor = 0.2f;
|
||||||
|
|
||||||
public Node3D Target { get; set; }
|
public Node3D? Target { get; set; }
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
ApplyCentralImpulse(Vector3.Up * 10);
|
ApplyCentralImpulse(ComputeImpulseToTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3 ComputeImpulseToTarget()
|
||||||
|
{
|
||||||
|
if (Target == null) return Vector3.Zero;
|
||||||
|
return Vector3.Up * Speed;
|
||||||
|
|
||||||
|
var targetDir = GlobalPosition.DirectionTo(Target.GlobalPosition);
|
||||||
|
var hDir = new Vector3(targetDir.X, 0, targetDir.Z).Normalized();
|
||||||
|
var throwDir = (hDir + 3*Vector3.Up).Normalized();
|
||||||
|
var distanceTo = GlobalPosition.DistanceTo(Target.GlobalPosition);
|
||||||
|
|
||||||
|
return throwDir * distanceTo*0.8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
|
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
|
||||||
{
|
{
|
||||||
var direction = GlobalPosition.DirectionTo(Target.GlobalPosition);
|
if (Target == null) return;
|
||||||
state.LinearVelocity += direction / 10.0f;
|
var targetPos = Target is ITargetable targetable ? targetable.GetTargetGlobalPosition() : Target.GlobalPosition;
|
||||||
|
var targetVel = state.LinearVelocity + GlobalPosition.DirectionTo(targetPos) * HomingFactor;
|
||||||
|
if (targetVel.Length() > Speed) targetVel = targetVel.Normalized() * Speed;
|
||||||
|
state.LinearVelocity = targetVel;
|
||||||
|
// var targetDir = GlobalPosition.DirectionTo(targetPos);
|
||||||
|
// var hDir = new Vector3(targetDir.X, 0, targetDir.Z).Normalized();
|
||||||
|
// var currentVelocityHDir = new Vector3(state.LinearVelocity.X, 0, state.LinearVelocity.Z);
|
||||||
|
// var finalHDir = hDir*HomingFactor + currentVelocityHDir;
|
||||||
|
// var combinedVelocity = new Vector3(finalHDir.X, state.LinearVelocity.Y, finalHDir.Z);
|
||||||
|
// if (combinedVelocity.Length() > Speed) combinedVelocity = combinedVelocity.Normalized() * Speed;
|
||||||
|
// state.LinearVelocity = combinedVelocity;
|
||||||
|
// state.LinearVelocity += targetDir/5.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnResolved()
|
public void OnResolved()
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ script = ExtResource("12_6slh1")
|
|||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_uh7hr"]
|
[sub_resource type="Resource" id="Resource_uh7hr"]
|
||||||
script = ExtResource("12_6slh1")
|
script = ExtResource("12_6slh1")
|
||||||
BaseValue = 10.0
|
BaseValue = 1.0
|
||||||
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ckp55"]
|
[sub_resource type="Resource" id="Resource_ckp55"]
|
||||||
@@ -201,6 +201,8 @@ continuous_cd = true
|
|||||||
contact_monitor = true
|
contact_monitor = true
|
||||||
max_contacts_reported = 1
|
max_contacts_reported = 1
|
||||||
script = ExtResource("1_bwggc")
|
script = ExtResource("1_bwggc")
|
||||||
|
Speed = 20.0
|
||||||
|
HomingFactor = 0.8
|
||||||
|
|
||||||
[node name="ForgeEntityNode" type="Node3D" parent="." unique_id=1961065393]
|
[node name="ForgeEntityNode" type="Node3D" parent="." unique_id=1961065393]
|
||||||
script = ExtResource("3_0m0gv")
|
script = ExtResource("3_0m0gv")
|
||||||
|
|||||||
Reference in New Issue
Block a user