The order for a single animation is:
start
event
event
complete
event
event
complete
event
event
end
dispose
The only event not shown above is interrupt, which happens when another entry has replaced the current entry.
If you are getting multiple start events you must be setting a second animation. Please show your setAnimation and addAnimation calls.
We have tests so we can carefully monitor how any changes to AnimationState affect event timing and order. See this test:
spine-runtimes/AnimationStateTests.java at 3.8
I don't suggest trying to read the test harness code, it's pretty intense. This test does:
state.setAnimation(0, "events0", false);
state.addAnimation(0, "events1", false, 0).setTrackEnd(1);
The order is:
# EVENT TRACK TOTAL
0 start 0 0
0 event 0 0 0
0 event 14 0.5 0.5
0 event 30 1 1
0 complete 1 1
0 interrupt 1.1 1.1
1 start 0.1 1.1
1 event 0 0.1 1.1
0 end 1.1 1.2
0 dispose 1.1 1.2
1 event 14 0.5 1.5
1 event 30 1 2
1 complete 1 2
1 end 1 2.1
1 dispose 1 2.1
The # column denotes the animation, 0 for events0 or 1 for events1 (it's not the track number, everything is on track 0 for this test). TRACK and TOTAL are times in seconds for the track entry and for the entire AnimationState.
As you can see, complete for the first animation happens before start for the next animation. That is correct in the spine-libgdx runtime, which is the reference implementation. It should behave the same in spine-unity, if it doesn't it's a bug.