const gamePlayers = useGamePlayers();
const { setGamePlayers } = useGameActions();
const [localPlayerNumber, setLocalPlayerNumber] = useState<number | undefined>();
...
setGamePlayers: (participants) => {
// NOTE 입장 시간으로 정렬
const gamePlayerName = participants.sort((a, b) => {
if (!a.joinedAt || !b.joinedAt) {
return 1; // 존재 하지 않을 시 뒤로 이동
}
return new Date(a.joinedAt).getTime() - new Date(b.joinedAt).getTime();
});
// NOTE - gamePlayers 요소: playerName, playerJoinAt, playerNumber
const gamePlayers = gamePlayerName.map((player, index) => ({
playerName: player.name,
playerJoinAt: player.joinedAt,
playerNumber: index + 1
}));
//NOTE - gamePlayersInfo 저장
set({ gamePlayersInfo: gamePlayers });
}
//NOTE - 게임 시작 이벤트 핸들러
const startHandler = () => {
...
// 게임 시작시 player Number 부여
setGamePlayers(participants);
};
//NOTE - "gamePlayers" 값이 존재(게임 시작 시) 작동
useEffect(() => {
const localNumber = gamePlayers.find((player) => localParticipant.name === player.playerName);
if (localNumber) {
setLocalPlayerNumber(localNumber.playerNumber);
}
}, [gamePlayers]);
처음 정렬 조건을 닉네임을 기준으로 정렬하였다.
이유는 어느 조건의 정렬이든 상관없이 전체 게임 방 players가 동일하게 정렬만 되면 문제가 없었기 때문이다.
Track( 캠, 오디오)
데이터를 앞서 정렬한 순서대로 다시 UI에 보여지게 TrackLoop
하였다. 모든 players의 캠 및 오디오 off
로직이 정상적으로 작동되지 않는 걸 볼 수 있었다. 모든 players의 캠 및 오디오 off
할 시기에 다시 players의 캠 및 오디오 데이터
의 반복문을 돌려 재실행하기에 문제가 발생하였다.해결방법
입장 시간을 기준
으로 자동으로 정렬되기에 캠의 위치를 다시 정렬할 필요없이 입장 시간의 값만 얻을 수 있다면 문제 해결이었다. 그래서 Livekit의 여러 hooks 중 LiveKit에서 제공하는 useParticipants
hooks 요소에서 joinAt
이라는 player의 입장 시간을 hooks 요소로 전달해주는 걸 확인해결: 입장 순으로 정렬 후 번호를 부여하여 캠의 재조정 없이 UI에 표현
그리고 헷갈릴 수 있는 부분인
"useParticipants" 훅의 배열 순서는 Local을 기준으로 정렬되기에 시간순으로 다시 정렬해줘야한다.