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.