Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ProjectileEffect base class and basic functionality #2

Merged
merged 7 commits into from
Aug 20, 2024

Conversation

Checkroth
Copy link
Collaborator

Adds a new Node type and class called ProjectileEffect. Includes the usage of this class in the player and projectile scenes.

Will also include the following projectile effects:

  • Double laser
  • Big Laser
  • Fast Laser

units/player.gd Outdated Show resolved Hide resolved
Copy link
Owner

@campenr campenr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢 but with some random questions that occured to me while reading the PR

units/player.gd Outdated
# utility functions will get called regardless of its presense in the scene
# tree, as long as thy're in the top-level projectile_effects Array.
add_child(double_laser.instantiate())
projectile_effects.append(double_laser)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note:

This is not actually appending anything to the top-level projectile_effects array. Later instances where this is accessed see an empty array for some reason 🤷

@Checkroth Checkroth force-pushed the feature/projectile-effects branch 3 times, most recently from 4398d3a to 066cad0 Compare August 18, 2024 06:12
@Checkroth Checkroth requested a review from campenr August 18, 2024 10:04
@Checkroth
Copy link
Collaborator Author

Re-requesting review because the PR has evolved significantly and now is now officially "done"


# Modify the logic that adds the projectile as a child to the scene.
# This can be used to change spawn locations, quantities, etc.
func modify_creation(owner: Node, projectile_effects: Array, transform: Transform2D):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍷 🧀

I'm pretty sure the resulting type here is "Packed Scene", which currently cannot be typed better

I flip-flopped between the actual node type (ProjectileEffect) and PackedScenes and some other ideas so many times that changing every type annotation was incredibly cumbersome, so I've opted to leave this as just Array until we flesh things out and settle on something that works and won't be changed.

There's also no support for Type Variables -- I figured having a Globals script that contains this type so we can just say var EffectType = Array[PackedScene] and use that so that making a change would be trivial, but can't find a way to do it with the current gdscript version.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Some interesting thoughts in this forum post on accessing more info about types when using PackedScene. A custom resource type is an interesting approach. Nothing for now though, just food for collective thought.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Classic me. No link, and now I can't find it again 🤦

units/player.gd Outdated

_add_test_effects()

func _add_test_effects():
Copy link
Collaborator Author

@Checkroth Checkroth Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍷 🧀

This, an the top-level projectile_effects array is not used (and therefore this function effectively does nothing)

This is for two reasons:

  1. The core node type ProjectileEffect is not used now, see the comment about using PackedScene instead.
  2. Passing just the type ProjectileEffect (or a subclass -- HugeLaser, DoubleLaser, etc.) results in an empty array for a reason I truly have no idea about. Otherwise I would keep the array, use a non-instantiated variable, and then use that instead of the PackedScene

I think ultimately, a combination of ideas might be the best path forward: A Globals script that keeps a list of all our "officially supported" effects as an enum & dictionary of that Enum to a resource path (e.g. res://projectiles/fast_laser.tscn), and then maintain the top level list of just the enum, and offload the loading/instansiating to the projectile scene.

@@ -0,0 +1,2 @@
class_name HugeLaser
extends ProjectileEffect
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍷 🧀

This is not actually needed with the current implementation.

It WILL be needed if we want to use the Node class type instead of a PackedScene for effects management. I.e. you can't do HugeLaser.new() unless you define the class_name in a script.
But if you load a PackedScene from the scene path, this is totally superfluous boilerplate.

scale = new_scale

func _ready():
if scale != Vector2.ONE:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍷 🧀

This is a hack to allow the "scale" you set on the Projectile node itself to impact the actual scale of the base projectile.
Without this, setting "Transform -> Scale" on the base projectile node will change the size of the projectile in the 2D visual UI, but at runtime it will be completely ignored. See this godot pr, also linked in the commit message directly.

Projectile = load("res://units/projectile.tscn")
# Called when the node enters the scene tree for the first time.

# Called every frame. 'delta' is the elapsed time since the previous frame.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗑️

Copy link
Owner

@campenr campenr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I like that adding multiple of the same effect works as expected (i..e super super fast, super super big) 👍 👍 👍

Not going to block. But do we want to consider embracing a clean commit style approach here to make it easier to see how a thing was done start -> (a) finish?.

projectiles/double_laser.gd Show resolved Hide resolved
return not effect.is_double_laser

# TODO:: Hacky? but const on the node does not work for packed scenes
return effect.resource_path != "res://projectiles/double_laser.tscn"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ Non-blocking: can we type check the effect? I guess we're loading the scene, but we could probably type check the parent node of the scene to be able to check against a custom class_name? 🤔

projectiles/projectile_effect.gd Show resolved Hide resolved

# Modify the logic that adds the projectile as a child to the scene.
# This can be used to change spawn locations, quantities, etc.
func modify_creation(owner: Node, projectile_effects: Array, transform: Transform2D):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Some interesting thoughts in this forum post on accessing more info about types when using PackedScene. A custom resource type is an interesting approach. Nothing for now though, just food for collective thought.

units/player.gd Outdated
func _add_test_effects():
# Debugging -- these should be added to the list via some user interaction instead.
var double_laser = load("res://projectiles/double_laser.tscn")
# TODO:: Not even sure if adding to the scene tree here is necessary.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 It's necessary for lifecycle things. If we want to listen to signals etc. 👍

units/player.gd Show resolved Hide resolved
@Checkroth
Copy link
Collaborator Author

consider embracing a clean commit style approach here

I thought that's what I was doing 😆 maybe my commits aren't pristine, but I did intend to do it atomically.

There's some refactoring in here that could be squashed in to earlier commits, but it was also a lot of discovery and small changes that were rebase conflict magnets, which I opted to just not deal with

Adds a new Node type and class called ProjectileEffect.
Includes the usage of this class in the player and projectile scenes.

Does not include any actual projectile effects yet.
This effect adds an identical lazer ouput offset from the original
laser.
It also makes some modifications to how the firing mechanism and
effects dispatch is handled, to make it easier to offload effect
mechanism management to each effect.
This adds a projectile effect that makes lasers huge.
It includes refactoring to the projectile effect engine to allow
effects to directly influence the parent node's size
Adds a workaround that manually scales the children of the Projectile
scene.
This is due to a problem where the projectile root node scale does not
propagate down to the sprite or collision shape within it.

godotengine/godot#5734
This refactors the projectile effect system to use packed scenes
instead of the base class node type ProjectileEffect.

This is due to the requirement for these scenes to be instantiated for
each projectile, not a shared resource. Without this change, effects
that modify the scene tree (such as HUGE LASER) do not work.
Adds a new effect that hooks in to the physics system to make lasers
go pewpew faser
This moves projectiles to a new collision layer, and adds that layer
to the mask for enemies.

This is to do two things: (1) Prevent lasers from colliding with
themselves ("Huge" and "Double" lasers can overlap), (2) allow enemies
to queue_free themselves, instead of leaving that burden on the projectile
@@ -8,6 +8,7 @@ radius = 4.0

[node name="Projectile" type="Area2D"]
position = Vector2(68, 1)
collision_layer = 2
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 I kinda like the idea that projectiles can hit themselves / the player... but that'll take some thinking. For now 👍 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a terrible idea, though the huge double lasers overlapped hitboxes, so they would just immediately disappear

Copy link
Owner

@campenr campenr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!!! 🚢 🚢 🚢 🚢

@campenr campenr merged commit f2cd26f into main Aug 20, 2024
@campenr campenr deleted the feature/projectile-effects branch August 20, 2024 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants