In the game I'm making you can throw units at enemies. Units are much smaller than enemies, so when an unit impacts, it can latch on to the enemy and continue attacking it. Thus, if the enemy moves around, the unit will move with it. You can throw a number of units to an enemy, the theoretical limit being 100, but the most frequent case it will be something lower than 15.
I have though of these ways to implement this:
SOLUTION A: Dynamic RemoteTransform3D
When the unit impacts with the enemy, a RemoteTransform3D node is created at the collision point and added as a child to the enemy, with the RemotePath property pointing to the attacking unit. This way the RemoteTransform3D node will inherit all movement from its parent (the enemy) and pass it on to the unit. When the enemy dies or the unit unlatches, the RemoteTransform3D node is deleted.
- PRO: Very simple system.
- CON: Needs to add and delete nodes dynamically, though it will never have to create more than 2 or 3 nodes at the same time (as you can't throw more than 1 unit at a time).
SOLUTION B: Static RemoteTransform3D
At creation, the enemy will create a list of RemoteTransform3D nodes and add them all as childs. When an unit impacts with the enemy, it will get assigned to an available RemoteTransform3D node and the RemoteTransform3D will be marked as unavailable. When an unit unlatches, the corresponding RemoteTransform3D node will be made available again.
- PRO: Everything is set up at start-up.
- CON: Every enemy will require a lot of RemoteTransform3D nodes (around 30-40) while only 15 or so will really be used most of the times (or even less!). We'll be preemptively reserving memory and moving these nodes around for nothing. We're also complicating the solution, as now we have a list of nodes we also have to keep track of.
SOLUTION C: Mixed RemoTransform3d
Mix the static and dynamic solutions: Have a list of 15 RemoteTransform3D nodes created at start-up, but create more if a unit requests one and there are none available.
- PRO: Best of both solutions.
- CON: It has the same problems of both solutions as well and increases complexity even more by making the list of nodes dynamic.
SOLUTION D: Manual transform calculation
Once latched, the unit will save the position of the collision point and use it to calculate the offset (enemy.global_position - collision_point.global_position) from the enemy's center position. Then, in a _process() call the unit will just update it's position by adding the offset to the enemy's new position.
- PRO: Very simple solution, no additional nodes required.
- CON: I haven't been able to properly translate the offset into the local space of the enemy so that rotations are considered correctly 🙁
What would be the best solution, considering that there will be at most 4-5 enemies active at the same time?