GameMaker Help with a grid path.

D

DNJ

Guest
I was browsing around to find an answer to this, and while I could find allusions to methods, I never found an example.

How do you reference a specific instance?

So far, the only way I've been able to figure out how to do it is with "id" in the Object's internal code, and the instance_nearest command in other Objects.

Example: I wanted an enemy sprite to create an identical sprite on a higher layer, and to become opaque whenever the player sprite was above it. I could get them to attach to each enemy fine, but whenever one did something weird, like enter a dying animation, the others would desync, and then the over sprite would attach to one of the still-existing enemies.

I couldn't figure out how to get the over sprite to destroy itself when the instance it had originally attached itself to stopped existing, so instead I set up the code for the enemy to produce an over sprite every step, and for the over sprite to destroy itself after one frame of existence.

It works, fine now, but I feel like I'm gonna run into more problems if I can't figure this out. What are some of the methods you can use to reference specific instances?
 
Last edited by a moderator:

FrostyCat

Redemption Seeker
I cover handling of subsidiary instances in the "Finding the Right Instance" section of this article: What's the Difference: Objects and Instances
Created or copied instance. instance_create() (GMS 1.x and legacy) / instance_create_layer() and instance_create_depth() (GMS 2.x) and instance_copy() return the ID of the created or copied instance. NEVER use instance_nearest() to establish this relationship --- something else could be closer by.

Subsidiary instance(s). Same as created or copied instance. If the subsidiary instance needs to reference its creator, the creator should assign its instance ID to an instance variable in the subsidiary instance. Conversely, if the creator needs to reference its subsidiary (or subsidiaries), it must store the return value of instance_create() (GMS 1.x and legacy) / instance_create_layer() or instance_create_depth() (GMS 2.x) immediately. NEVER use instance_nearest() to establish or maintain this relationship --- being the closest does NOT imply being the most relevant, especially in close quarters.
When you create the subsidiary instance, you make it remember its exact originator like this (NOT with instance_nearest() for reasons that should be obvious to you by now):
Code:
with (instance_create_layer(x, y, "higherlayer", obj_subsidiary)) {
  owner = other.id;
}
Then in the subsidiary's Step event:
Code:
if (instance_exists(owner)) {
  x = owner.x;
  y = owner.y;
} else {
  instance_destroy();
}
You need to stop believing that id and instance_nearest() are the only sources of instance IDs. If you keep working with the assumption that these are the only sources, you'll suck at GML forever. At the very least, you should know that these return or contain instance IDs when applicable:
  • Basic collision functions: instance_place() and instance_position()
  • Extended collision functions: collision_point(), collision_circle(), collision_ellipse(), collision_line(), collision_rectangle()
  • All built-in functions that generate new instances: instance_create_layer(), instance_create_depth() and instance_copy()
  • other.id in a Collision event (the one from the event selector, NOT collision checks in the step event) or a with block (which refers back to the calling instance)
More finer points on collision functions are available on this article, most importantly the difference between instance_place() and instance_position().

You should also go over everything you currently believe must take object IDs, and check in the Manual whether they take instance IDs. Way too many rookies synthetically limit themselves to object IDs, and needlessly struggle in multi-instance environments. In particular, the variable reference dot (subject.variable) also accepts instance IDs on its left side. As a general rule, the only place in GML that accepts object IDs but not instance IDs is the obj parameter in built-in functions starting with instance_create_*() or object_*().
 
  • Like
Reactions: Rob
D

DNJ

Guest
Thanks a lot. That's exactly what I was looking for.
I actually tried to convert the instance ID into a variable and copy it over like that in some of my earlier experiments, but it never took.
Didn't realize you could do it in the braces after creating the instance.
 

FrostyCat

Redemption Seeker
I actually tried to convert the instance ID into a variable and copy it over like that in some of my earlier experiments, but it never took.
That should have worked had you done this:
Code:
var spawn = instance_create_layer(x, y, "higherlayer", obj_subsidiary);
spawn.owner = id;
This is for when you don't need to refer to spawn from the creator in future events. If you do, just get rid of the var.
 
D

DNJ

Guest
I'm having trouble with coding path-finding for enemies.
cell_width = 16;
cell_height = 16;

hcells = room_width div cell_width;
vcells = room_height div cell_height;

global.grid = mp_grid_create(0, 0, hcells, vcells, cell_width, cell_height+8);

mp_grid_add_instances(global.grid, oWall, false);
if(vile_mode = mode_attack){
if (mp_grid_path(global.grid, path, x, y, oPlayer.x, oPlayer.y, 1)){
path_start(path, 1.5, path_action_stop, false);}
}
In the tutorial I watched, the object seemingly collided with things with pixel accuracy, but my enemies are colliding based on their origin point, and it doesn't look very good when they overlap with certain environmental objects.

What might the problem be?
 
Last edited by a moderator:
Top