Born in Germiston, Transvaal, McMillan was a right-handed middle- or lower-order batsman and a right-arm leg-break and googly bowler. He had a curious first-class cricket career in that only nine of his 50 first-class matches were played in his native South Africa and five of those were Test matches; there were 25 games on the 1929 tour to England and 16 on the tour to Australia and New Zealand in 1931–32. He started with three matches for Transvaal cricket team in the series of games around Christmas that took the place of the Currie Cup in the 1928–29 season, and was immediately successful. In his first game, he made 61 against Eastern Province and followed that with bowling figures of three for 24 and six for 48 in an innings victory inside two days. He followed that in the very next match with an innings of 185 not out, including a stand of 265 for the fourth wicket with Jock Cameron, against Orange Free State. The innings proved to be the highest of his first-class career and his only century.
On the 1929 South African cricket tour to England, McMillan took more first-class wickets, 91, than any other bowler and he also made 749 first-class runs, mostly batting in the lower-order. Yet he was largely overlooked for the Test matches, playing only in the second game of the five-match series, when Cyril Vincent was injured, and in the last game when the series was already lost. In early matches, he took five wickets for 36 in Glamorgan's second innings, but was overshadowed by Vincent's match figures of 11 for 89. And against Cambridge University he took five for 45. McMillan's Test debut came at Lord's but as a bowler he was unable to make any impact, failing to take a wicket; he scored 17 in his only innings. His Test innings, according to later reports, included a hit for six off England captain and off-spinner Jack White which landed on the head of a lieutenant-general in the stands. Vincent was fit again for the third and fourth Tests, but immediately after the fourth Test, McMillan took eight first-innings wickets for 50 runs against Somersetand 10 for 86 in the match. This led to his recall for the final Test of the series at The Oval and, on a batsman's wicket, he did better than he had done at Lord's, taking three wickets for 78 runs in England's innings and then making an unbeaten 50 in a big South African total. This was to be his only Test match half-century.
Home series against England
Back home in South Africa, McMillan all but disappeared from first-class cricket outside Tests. There was a single appearance in the 1929–30 season and none at all in the 1930–31 season, apart from the five Test matches against England touring team, where he played in every match. The first game prived to be decisive in the series: South Africa won by 28 runs and all the other games in the series were drawn. McMillan's contribution to the victory came with bat rather than ball. With South Africa reduced to 81 for nine wickets, McMillan and last batsman Bob Newsonput on 45 for the 10th wicket, and McMillan was left unbeaten on 45, his highest score of the series, when Newson was bowled by Maurice Tate. He scored 14 in the second innings but took only one English wicket. The second Test was a high-scoring draw, and McMillan took five wickets in the match at a cost of 35 runs apiece. The third match was ruined by rain, and McMillan contributed little with either bat or ball. In the fourth Test, there were a couple of wickets from him and some useful runs in the second innings when, after a competitive declaration by England, South Africa was fleetingly in danger of losing the match. With South Africa needing only to draw the final Test to secure the series victory, McMillan again chipped in with scores of 29 not out and 28, and a couple of wickets as a slow match drifted to a draw. In the series as a whole, McMillan had contributed 180 runs at an average of 30 and 10 wickets at an average of 40.90.
Though McMillan's Test figures had been modest, he was cited as "the best slow bowler of the tourists" in a syndicated Louis Duffus article in Australian newspapers at the start of the 1931–32 tour to Australia and New Zealand. The same article described him as "short and tubby". In fact, the tour marked the end of McMillan's first-class cricket career, and it began very well for him, with a career-best bowling performance of nine wickets for 53 runs in South Australia's second innings in one of the warm-up matches before the first Test. That Test, by contrast, was a personal failure: he failed to score in either innings and took no wickets in 10 expensive overs as Donald Bradman hit the first of four centuries in the series. McMillan was dropped for the second Test, but returned for the third match of the rubber. He took no wickets in the first innings, but then scored 29 and shared in an eighth wicket partnership of 104 with Ken Viljoen in South Africa's first innings. He followed that with four wickets for 150 in Australia's second innings, his best in Test cricket to that point. The fourth Test was not a success for McMillan: he made scores of 19 and 3 and took no wickets. And though there were three wickets for him for 29 runs in the fifth and final Test, the match was decided by South Africa's batting woes in difficult conditions, which saw the whole team dismissed first for 36 and then for 45; McMillan recorded his second "pair" of the series. Having lost the Australian series 5–0, the South Africans then moved on to New Zealand to play two Test matches against much less demanding opposition, winning both games. McMillan had his two best Test bowling performances in these games. In the first of them, he took four for 61 in the first innings and followed that with five for 66 in the second innings. In the second match he took five for 125 in the first innings and a further two wickets in the second.
End of cricket career
The second Test in New Zealand was McMillan's final game of first-class cricket. He did not appear in South African domestic cricket in later seasons. He retired to a career in business and died 3 July 1948 in Randfontein, Transvaal, aged 44.