• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

[SOLVED] object following parent only

J

jr carey

Guest
I'm trying to get child object to follow a parent object, for example I have 2 objects 1st will be object 1 and 2nd will be object 2 (just random names)
1st is the parent, and 2nd is the child, in the step event of 2nd I put (move_towards_point(1st.x,1st.y,5))
but it only follows itself because its a child even when I'm asking it to follow that object...it does the same thing if you add another object that isn't parented or chided by any objects, it will still follow 2nd, and occasionally 1st...to make it clearer, I will add a 3rd object named 3rd, if I try to make third follow 1st, it will follow 2nd
so how can I make one object follow a parent object and not the childs? any ideas?
 
I

ItchyPancake

Guest
Are there multiple of each object 1, object 2, object 3? If there is, read this:
create event for object 1:

repeat(how ever many there are){
child = instance_create(x,y,obj_2)
child.follow = id}

create event for child:
follow = 0
step event for child:
move_towards_point(follow.x,follow.y,1)

Basically, you are telling each created child to get the id of the parent that way they follow that specific object and not themselves.
same exact concept for object 2 to make an object 3

If there's only 1 of each
create event for obj 1
globalvar follow1;
follow1 = id
-------------------------------------------------------------------
create event for obj 2
globalvar follow2;
follow2 = id

step event for obj 2
move_towards_point(follow1.x,follow1.y,1)

-------------------------------------------------------------------
repeat per object

Those are just some ways of dealing with this. you basically want a way to single out the ID of the object to follow

EDIT: Please let me know if this helped guide you. If you have any specific questions for your game, please ask :) And if possible, provide more background on what is happening if you have further questions on how to implement this to your project
 
J

jr carey

Guest
Are there multiple of each object 1, object 2, object 3? If there is, read this:
create event for object 1:

repeat(how ever many there are){
child = instance_create(x,y,obj_2)
child.follow = id}

create event for child:
follow = 0
step event for child:
move_towards_point(follow.x,follow.y,1)

Basically, you are telling each created child to get the id of the parent that way they follow that specific object and not themselves.
same exact concept for object 2 to make an object 3

If there's only 1 of each
create event for obj 1
globalvar follow1;
follow1 = id
-------------------------------------------------------------------
create event for obj 2
globalvar follow2;
follow2 = id

step event for obj 2
move_towards_point(follow1.x,follow1.y,1)

-------------------------------------------------------------------
repeat per object

Those are just some ways of dealing with this. you basically want a way to single out the ID of the object to follow

EDIT: Please let me know if this helped guide you. If you have any specific questions for your game, please ask :) And if possible, provide more background on what is happening if you have further questions on how to implement this to your project
I still cant get it to work lol it still following the child, the reason I need to follow the parent is so I can judge which parent is closer and follow the closer parent rather than flying around
the screen, maybe if I made a parent for the parent, and made the old parent a child, that way id have 2 childs, so I can pick which one out of 50 to follow....so much thinking lol
 
I

ItchyPancake

Guest
Hehe, quick cheat for that ;)

Code:
x += 100000;
InstanceNearest = instance_nearest(x-100000, y, *object*);
x -= 100000;
move the x by 1000000,
check the old spot you used to be at for the nearest object,
then move right back to where you were!

ITS THE PERFECT SOLUTIONNNN

Lemme know if that works (I feel it will)
 
C

CROmartin

Guest
I'm trying to get child object to follow a parent object, for example I have 2 objects 1st will be object 1 and 2nd will be object 2 (just random names)
1st is the parent, and 2nd is the child, in the step event of 2nd I put (move_towards_point(1st.x,1st.y,5))
but it only follows itself because its a child even when I'm asking it to follow that object...it does the same thing if you add another object that isn't parented or chided by any objects, it will still follow 2nd, and occasionally 1st...to make it clearer, I will add a 3rd object named 3rd, if I try to make third follow 1st, it will follow 2nd
so how can I make one object follow a parent object and not the childs? any ideas?
Code:
///in child step event
follow = object_get_parent(name_of_child_object);
move_towards_point(follow.x,follow.y,1)
Follow will store just id of parent , so use it on places where would you use obj_parent .Try this,let me know if it work or dont.Why not use scripts? Sry on bad English.
 

Roderick

Member
When you say "parent" and "child", do you mean that you set one as a parent to the other in the object properties?

If so, that's your problem. When you set obj_parent to be the parent of obj_child, each instance of obj_child is ALSO an instance of obj_parent. So when you thee obj_child to follow obj_parent, it finds an instance of obj_parent and follows it. If there's only one obj_parent, that's no problem. But if there's more than one (including children), then it can be difficult to know which one it locks on to.

As @CROmartin said, you need to directly follow the specific instance by referencing its id.
 
J

jr carey

Guest
When you say "parent" and "child", do you mean that you set one as a parent to the other in the object properties?

If so, that's your problem. When you set obj_parent to be the parent of obj_child, each instance of obj_child is ALSO an instance of obj_parent. So when you thee obj_child to follow obj_parent, it finds an instance of obj_parent and follows it. If there's only one obj_parent, that's no problem. But if there's more than one (including children), then it can be difficult to know which one it locks on to.

As @CROmartin said, you need to directly follow the specific instance by referencing its id.
so If I can find a way to make a unique ID just for the parent I should be able to follow it, correct?
 
J

jr carey

Guest
Code:
///in child step event
follow = object_get_parent(name_of_child_object);
move_towards_point(follow.x,follow.y,1)
Follow will store just id of parent , so use it on places where would you use obj_parent .Try this,let me know if it work or dont.Why not use scripts? Sry on bad English.
it still does the same thing lol, and I am coding, not a fan of GML but I cant ever get c++ game libraries to link up to my IDE so I'm stuck with this
 
J

jr carey

Guest
Hehe, quick cheat for that ;)

Code:
x += 100000;
InstanceNearest = instance_nearest(x-100000, y, *object*);
x -= 100000;
move the x by 1000000,
check the old spot you used to be at for the nearest object,
then move right back to where you were!

ITS THE PERFECT SOLUTIONNNN

Lemme know if that works (I feel it will)
this still wont work because the child will inherit this as well and will just follow itself
 
I

ItchyPancake

Guest
this still wont work because the child will inherit this as well and will just follow itself
Actually, if you place an empty step event in the child, it will not follow the parents code. Each object is processed one at a time in the order of creation, so by placing the object back by the end of the code, it'll be as if nothing ever happened
 
Last edited by a moderator:

FrostyCat

Redemption Seeker
so If I can find a way to make a unique ID just for the parent I should be able to follow it, correct?
A lot of novices fail to make a distinction between an object and an instance, that's where confusion like this comes from.

Every instance of an object you place into the room has a unique instance ID. This can be determined from the room editor by mousing over it, or from the return value of functions such as instance_find() or instance_create(). Instead of having an object on the left side of the dot (e.g. 1st.x), put that instance ID there and it will get the right one even if multiple instances of the object exist in the room.

Also, remember that a child-parent relationship in GM is an "A is a B" relationship, not an "A uses B" relationship. obj_red_delicious makes sense as a child of obj_apple, but obj_apple has no business being a child of obj_apple_salad. You should sever that relationship if the child does not count as what its parent stands for.

Hehe, quick cheat for that ;)

Code:
x += 100000;
InstanceNearest = instance_nearest(x-100000, y, *object*);
x -= 100000;
move the x by 1000000,
check the old spot you used to be at for the nearest object,
then move right back to where you were!

ITS THE PERFECT SOLUTIONNNN

Lemme know if that works (I feel it will)
I just hope people would stop recommending defective instance_nearest() crutches like this to mask ignorance for instance IDs they should have kept better track of. Distance is way too flimsy as a determinant for ownership or association.
 
I

ItchyPancake

Guest
I just hope people would stop recommending defective instance_nearest() crutches like this to mask ignorance for instance IDs they should have kept better track of. Distance is way too flimsy as a determinant for ownership or associatio
In my defense I did mention ways to obtain an instance id in my previous post. OP ignored some of the ways to obtain the instance ID.

Every object in the game contains an ID
you just need a way to obtain it and use it to follow an object directly.
Having the issue with parents and trying to find the nearest object is causing this problem it seems.
you can not just simply move towards the closest object because it'll count itself as that object.

I need to follow the parent is so I can judge which parent is closer and follow the closer parent

by the way FrostyCat, he is trying to follow the nearest parent, not just the parent object alone. Thus, I used instance_nearest to find the nearest.
Would you prefer him to create an array for every parent object and store their x and y values and go through each one to make sure the id's are not the same as the object checking then calculate the x and y differences to find each distance then determine which is the closest that doesnt have the same ID as itself then proceed to move towards it? Will that help remove the crutches? I feel that's just adding stones in my opinion, but hey! It still works if you ask me!
 
C

CROmartin

Guest
I just messed around with parents and child for 20 mins and I realised that simply by puting in parents step event move_towards_point(obj_parent.x,obj_parent.y,3) it should perfectly work(it worked fine at me) and then I didnt put in parent but child I did and again worked fine.I dont know what did you mesed in your project but probaly something with id.More information abouth code would help .. do you want to I send you that testing project?
 
J

jr carey

Guest
okay lol to make this clear, this is what I'm basically trying to do, I have a parent object and a child object, the parent object is gonna be named parent_obj and the child is gonna be named child_obj just to make things easier to follow, the child_obj will do as constructed from the parent_obj, the child_obj destroys the closest enemies from the parent_obj POV (point of view), meaning which ever target is closer to the parent_obj, the child_obj will attack it and kill it, I got that system working good, it does its job (but now its being stubborn so I have to work through all of the code and see what the problem is because now its destroying objects closest to itself and not the parent_obj) but when its back up and running I cant get the child_obj to listen to the closest parent_obj only when the parent_obj tells it to seek and kill that object closest to it (instead all the child_obj's only listen to one single parent_obj), its a pretty complex system, and a complex algorithm, it wouldn't be so difficult if GML had like a capping system which allowed you to tell what the child can inherit, because all of the coding is in the parents events, I probably need to rearrange everything, in order to get my positive results, but if you still don't understand, heres a picture of what I'm trying to do.....but do you guys got any ideas on an easier way to get this? like I said its pretty complex, and I heard GML doesn't tend to like complex AI, but I disagree, its all just human error....do wish they'd let us use some c++ though lol....and I know I misspelled attack
 

Attachments

C

CROmartin

Guest
Code:
//// I puted this whole code in parents step event, and I used sprite_index to stop parent doing whole this code(you need adjust to your code),and instance_nearest look who closest to parent
if sprite_index != spr_parent var follow = instance_nearest(obj_parent.x,obj_parent.y,obj_enemy)
/// Here I add to child check are any obj_enemy instances in room
if sprite_index != spr_parent && instance_number(obj_enemy) > 0 move_towards_point(follow.x,follow.y,3)
This work I tested it, if you need something more, let me know.
 
J

jr carey

Guest
Code:
//// I puted this whole code in parents step event, and I used sprite_index to stop parent doing whole this code(you need adjust to your code),and instance_nearest look who closest to parent
if sprite_index != spr_parent var follow = instance_nearest(obj_parent.x,obj_parent.y,obj_enemy)
/// Here I add to child check are any obj_enemy instances in room
if sprite_index != spr_parent && instance_number(obj_enemy) > 0 move_towards_point(follow.x,follow.y,3)
This work I tested it, if you need something more, let me know.
why not use a with() statement? I don't like the with statements, they can sometimes be difficult, but which is better?
 
C

CROmartin

Guest
why not use a with() statement? I don't like the with statements, they can sometimes be difficult, but which is better?
I am kinda confused with your sentence(so you want use with or dont?).Why would I use with in this code(I actually almost never use with)?I am interested how you would do it with "with"(so pleas show me) and ty infront.
 
J

jr carey

Guest
the with statement is used for pointing out certain objects, and making those objects only run that code so for example:
if I have 2 objects parent_obj and child_obj

I can do something like

with(parent_obj)
{
// do something but the parent only runs this code
}
with(child_obj)
{
// do something but the child only runs this code
}

in theory that's what is should do, but because there isn't a program that basically says "child will only adopt this code from the parent"
I believe the child will still run both codes anyways, or inherit the parents with, causing and endless loop which is bad for optimization,
but who knows I could just be over thinking it, and it does what its suppose to do without inheriting all of the code
 

FrostyCat

Redemption Seeker
Let me remind you of this one more time:

A child-parent relationship in GM is an "A is a B" relationship, not an "A uses B" relationship.

Your use case and diagram clearly demonstrate an "A uses B" relationship. Unless A is the same kind of thing as B, A should not be a child of B.

Just so that you stop thinking in terms of parents and children, I will start calling your objects "leaders" and "followers". A leader is not a parent of a follower, they are two distinct objects.

In the follower's Create event, it should identify its closest leader and remember its instance ID:
Code:
my_leader = instance_nearest(obj_leader);
If you want the follower to follow its leader, do it by instance ID, not by object ID. The latter is a defective approach when multiple instances of the object exist.
Code:
move_towards_point(my_leader.x, my_leader.y, 3);
If you want the leader to issue commands to its followers:
Code:
with (obj_follower) {
  if (my_leader == other.id) {
    /* Commands interpreted from the perspective of a follower */
  }
}
 
M

Me Myself and I

Guest
To reiterate @Frosty's advice -- you should ONLY use the parent/child field on objects when you want different objects to have the same code. For example, I use it for damage....the weapons in my game all the do the same damage to all enemies, so I have one object with the collisions and damages/hit points and then I make all enemies a child of it.

What you're trying to accomplish is NOT a "parent-child" relationship in GameMaker. As @Frosty said, it's a "leader-follower" relationship.
 
  • Like
Reactions: Yal
J

jr carey

Guest
then how are you suppose to share local variables? I'm not gonna have them save the vars in a file, open and close them every step, that's just bad lol, and global variables are useless in this case
 
D

Docker

Guest
So.... if the parent is telling the child then could you not achieve what you're after by using:
closest_parent = instance_nearest(x, y, parent_obj);

Then with the parent object you can do:
closest_enemy = instance_nearest(x, y, enemy_obj);

Then you can find the closest_enemy in the parent_obj by using something like closest_enemy_to_parent = closest_parent.closest_enemy;

I have no idea of the complexity of your code to determine if this will work as intended and there may be better ways to do this using data structures etc that I have no idea about as I've only been programming GMS for a few weeks however I can't see a problem with you getting what you want by playing around with what I've written above.
 

Roderick

Member
then how are you suppose to share local variables? I'm not gonna have them save the vars in a file, open and close them every step, that's just bad lol, and global variables are useless in this case
By referencing the owner of the variable.

If an instance named follower wants to get the x and y coords of an instance called target, then in follower's events, you just reference target.x and target.y

And you can put target's id in a variable stored in follower, so that it can just use that variable. When you need to change targets, just pick a new target, and store it in the same variable.
 
J

jr carey

Guest
that's the easy part though, I'm trying to have it so the "leader" sends out the information to any "followers" close to itself, and from the information the "followers" respond, they go where the leader tells or kills what the leader says to kill, kind of like an online network, and if i do remove the parenting, the other half of the code works, while the other one still fails, so a good solution would be for me to for every instance created (that needs a code) would create its own special ID not the object or instance_id, so the leader can easily connect by changing its own special ID to match the followers special ID so they can exchange information, but the only way ive found possible would be global variables, which like i said are really worthless in this current code, you guys have all great ideas, but i still cant get what I'm looking for, I'm not gonna stop this is my first real challenge lol, but exchanging information between objects, without parenting, files and globals seems to be difficult for me, or I'm probably just overcomplicating this, but instead of moving towards objects, do you guys have any ideas on a solution for a system to exchange information between other objects?
 
J

jr carey

Guest
okay! believe I figured out how to share local variables, i create a for loop, that checks the instances your looking for, and assigns each of those certain objects a key, the only way to access the key is by setting the value of the other object so they can transmit, if you want the basics of this code, lemme know and ill stick it in a file for you to copy and paste
 

Roderick

Member
that's the easy part though, I'm trying to have it so the "leader" sends out the information to any "followers" close to itself, and from the information the "followers" respond, they go where the leader tells or kills what the leader says to kill, kind of like an online network
Store the commands in the leader object as variables. For example:
Code:
target = instance_nearest(x, y, obj_target)
if (target.type == enemy) {action = action.attack;} else {action = action.heal;} // type is a variable stored in all obj_target instances, action.attack and action.heal are enums set at the beginning of the game
Then, you have the units find the nearest leader and read its orders:
Code:
leader = instance_nearest(x, y, obj_leader);
switch (leader.action)
{case action.attack: scr_attack(leader.target); break;
case action.heal: scr_heal(leader.target); break;
// other possible actions here
}
 
J

jr carey

Guest
Store the commands in the leader object as variables. For example:
Code:
target = instance_nearest(x, y, obj_target)
if (target.type == enemy) {action = action.attack;} else {action = action.heal;} // type is a variable stored in all obj_target instances, action.attack and action.heal are enums set at the beginning of the game
Then, you have the units find the nearest leader and read its orders:
Code:
leader = instance_nearest(x, y, obj_leader);
switch (leader.action)
{case action.attack: scr_attack(leader.target); break;
case action.heal: scr_heal(leader.target); break;
// other possible actions here
}

ahh okay, i understand now lol, thanks! i figured it out!
 
Top