0 votes

In the tutorials Thousands of Fish, how would you program a shark eating one of these fish?

e.g. Finding the location of a fish, (for the shark animation), then have that fish disappear without affecting the other fish.

Godot version v3.2.3.stable.official
in Engine by (23 points)

1 Answer

+1 vote

I've never worked with MultiMeshInstance but I think next approach can be used:
I will review only 2D case but it can be easily updated to work in 3D.
1) Start with initialization of fish in predictable order. It can be simple square arrangement, where position of each fish is calculated as (x * fish_size_x), (y * fish_size_y), where x is row and y is column.
2) Define point position in shark that will "eat" fish. It is possible to use complex shapes but at first I always work with easiest cases at start. Now, knowing current "eating" position (mouth), position of fish and they arrangement, it is possible to get current fish that should be eaten (fish_position - mouth_position) / fish_size (you also need to check that it is valid cell in fish array).
3) Once fish is eaten, simplest solution is to set it's position using set_instance_transform to very big value. But if we have 10000 fishes in bulk and only one is alive, we will still drawing 10000 fishes. This is obviously not good. This can be fixed by usage of visible_instance_count property. Swapping eaten fish with last fish and reducing visible_instance_count by one is solution to this problem. But now order of fish is chaotic and it is impossible to get index of fish. This can be fixed by having array of fish cell -> fish index in MultiMesh. Then, once two fishes are swapped, this array should update values too.
This is just rough solution, but I think it should work. After implementing this, you can add variation to fish positions by shaders (here you will need to pass random value using uniform to make predictable position of fish), add space between fish and etc.

by (1,314 points)

Thank you.

This worked, with hundreds of ships and good performance. I haven't yet tried targeting a random instance and swapping... so far only taking them in reverse order. I'll do the other later, after we finish higher priority items. I'll also show the end product, when we get something to show.

BTW, I'm actually doing an animated space battle, with spaceships that are being blown up, rather than fish being eaten, but the principle worked!

Thanks again!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.