How do I combine two elements on contact and instantiate a third?

Hi game devs,
I can’t seem to wrap my brain around what I need to create here:
Two 2D gems, upon touching, burst, and “combine” into a new, larger gem.
I’m currently using OnCollisionStay2D, but the problem is that both gems register the touch to each other, call GemCombo.Convert (which creates the new gem), then they both destroy themselves.

I can’t figure out how to smartly have them both team up for only one gem creation. They were both Instantiated during gameplay, and the larger scope is that they have a “gemType”, which will look-up what type of new gem is created based on one of 8 or so types.

Any general methodology advice?
Thanks!

If this is some sort of grid-based matching game, I would not recommend using physics for it. Have a game board class that keeps track of what is where, moves things around, and does what needs to be done when they combine.

(That’s the approach I used on Chesster, and it worked great.)

1 Like

No, it’s actually a 2D vertical physics game. I’m having a hard time having two Gems touch without both of them trying to give the call for a new gem. It’s like two cowboys with two guns. They frequently both kill each other, so neither makes the NewGem call, or they both try to make the NewGem call. Having the “first one to call” kill the other works generally, unless I have a pile of 6 identical gems. Then my results are very haphazard. I think I need to implement some sort of list on the GameObject that creates the new Gem, but I’m confused about how to deal with gem precedence when there are multiple touches interacting from a pile of gems.

p.s. How did Chester do? I’m all ears for the best methods for marketing, since this is our first official release (dev on Android)

Simple solution: Each of them has a “combinationHasBeenHandled” bool. In your collision handler, set collisionHasBeenHandled for BOTH objects to true. If it’s true on either, then don’t run the combining function.

If that doesn’t give enough control, you can make a more complex solution where each gem contains a List of other gems it has collided with. On the collision handler for object A, check to see if B is on A’s list; if it’s not, then you run your combining function, then add A to B’s list and B to A’s list.

create a variable on each gem: isCombined (bool) false;

When the gems touch, the first gem to run through the codes says…

if(!isCombined) return; // even if the other gem calls the collision, it will eject from teh code because this variable.

isCombined = true;
otherGem.isCombined = true;


//create the new gem
CreateGem(other.value + this.value, Vector3.Lerp(transform.position, other.transform.position, 0.5f));


DestroyImmediate(otherGem);

Actually, you can use an already-handled flag, or you can use DestroyImmediate. No need to do both. (The difference between Destroy and DestroyImmediate is that the former marks the object for destruction, but it doesn’t actually happen until the end of the frame, after it’s had a chance to run its own code; whereas DestroyImmediate kills it dead right then and there, preventing it from running any further updates.)

As for how Chesster’s doing, I don’t really know. Sean Kiley was the design genius and the business guy; I was just the hired (coding) gun. :slight_smile:

1 Like

Or don’t have the responsibility of the collision’s result on gem and use a third party that manage all collision and resolve them.

1 Like