Hi All,

My second question. In my 3d rpg game, I am creating a prototype where you have two knights and a bunch of randomly placed hounds in a room.

I have created an Area node in the main scene that will be the area where the randomly created hounds will appear.

In a script attached to the main scene, loop 6 times and create hound instances off of my hound scene and add then as CHILDs to the Area node. I do this because it is, at least in my opinion, cleaner to generate random x and z positions for grounded enemies by simply using the range -1,1 for the x and z coordinates. These are taken as local coordinates within the area so works nicely. Each hounds spawn function is nicely contained within an enemy.gd script attached to each Hound scene.

Because the hounds are children of this area that I created and this is scalled, I reset all of the hounds scale by mutliplying it with 1/Area.scale.x, 1/Area.scale.y and 1/Area.scale.z (found this useful trick out in another Godot forum)

In order to detect whether a hound has landed on another hound while being randomly placed, I have each hound have an Area node of its own that is roughly the same size as its collision shape. In the physicsprocess(delta)() function of the hound, I have this check to see if it is spawned on another area:

``````extends KinematicBody
var spawned = false
signal spawn_collision

func _physics_process(delta):
var bodies = \$Area.get_overlapping_areas()
if(bodies.size()):# and !spawned):
if(!spawned):
spawn()
else:
spawned = true

func spawn():
randomize()
var x_pos = rand_range(-1,1)
var z_pos = rand_range(-1,1)
set_translation(Vector3(x_pos,0,z_pos))
``````

This means, if the hounds did land on each other, for a split second when the level loads up, I see a hound or two quickly change positions before settling down.

The main level scene script takes care of spawning all hounds and when all hounds have their spawned flag set to true, it will stop spawning and move on to other processing and not call the spawning process again.

It does appear to be quite a round about way of accomplishing something trivial. Is there a more effecient way of detecting collisions straight away of a spawned object? (without calculating the bounds of each spawned enemy already and comparing it with this list)

in Engine

After spending some time on this, I have a better way than what I explained in my question.

1. I create a new scene called EnemySpawner.
2. The Scene simply contains a MeshInstance Node as its root node.
3. I rename this root node to EnemySpawner.
4. I attach a script to this root node called "EnemySpawner.gd.
5. I choose a BoxShape for the Meshinstance.
6. I can change the size and position of this if I want - practically this will be done more when I place this in my main level scene.
7. In the EnemySpawner.gd script ready function, I calculate the minimum and maximum x and z positions (dealing only with grounded units for the time being so y is 0).
This is done using the code:

var minx = 0
var max
x = 0
var miny = 0
var max
y = 0
var minz = 0
var max
z = 0

# Called when the node is added to the scene for the first time.
# Initialization here
min
x = translation.x - ((mesh.size.x * scale.x)/2)
maxx = translation.x + ((mesh.size.x * scale.x)/2)
min
z = translation.z - ((mesh.size.z * scale.z)/2)
max_z = translation.z + ((mesh.size.z * scale.z)/2)
pass

8. I have a function called spawn() in the EnemySpawner.gd script that takes the enemy object to spawn as an argument and sets its translation (currently I am not using random atm, but that can easily be added soon):

func spawn(enemy):
var enemyxoffset = enemy.getnode("EnemyCollider").shape.getextents().x/2
var enemyzoffset = enemy.getnode("EnemyCollider").shape.getextents().z/2

``````enemy.translation = Vector3(translation.x,0,max_z - enemy_z_offset)
``````

The important thing to note is that I also have to subtract or add the enemy collider offset to the position I am inserting the object in otherwise, when placed on an edge, the enemy will be sticking out of the spawn area.

Finally, in my main level script, I can create random enemies using the spawn area. I do not add them as childs to the EnemySpawner but instead add them as child nodes to the main level to avoid child node transform headaches: