이미 답변을 검색했지만 비싼 함수 / 계산을 처리하는 가장 좋은 방법을 찾지 못했습니다.
현재 게임 (2D 타일 기반 도시 건물)에서 사용자는 건물을 배치하고 도로를 건설 할 수 있습니다. 모든 건물은 사용자가지도의 경계에 배치해야하는 교차점에 연결해야합니다. 건물이이 정션에 연결되지 않은 경우 영향을받는 건물 위에 "도로에 연결되지 않음"표시가 나타납니다 (그렇지 않으면 제거해야 함). 대부분의 건물에는 반경이 있으며 서로 관련이있을 수 있습니다 (예 : 소방서에서 반경 30 타일 내에있는 모든 주택을 도울 수 있음). 그것이 도로 연결이 변경 될 때 업데이트 / 확인해야하는 것입니다.
어제 큰 성능 문제가 발생했습니다. 다음 시나리오를 살펴 보겠습니다. 사용자는 물론 건물과 도로를 지울 수도 있습니다. 따라서 사용자가 접속점 바로 다음에 연결을 끊으면 동시에 많은 건물을 업데이트해야합니다 . 첫 번째 조언 중 하나는 중첩 루프를 피하는 것입니다 (이 시나리오에서는 분명히 큰 이유입니다).하지만 확인해야합니다 ...
- 도로 타일이 제거 된 경우 건물이 여전히 교차점에 연결된 경우 (해당 도로의 영향을받는 건물에만 해당). (이 시나리오에서는 더 작은 문제 일 수 있습니다)
반지름 타일 목록을 작성하고 반지름 내에 건물을 가져옵니다 (중첩 루프-큰 문제!) .
// Go through all buildings affected by erasing this road tile. foreach(var affectedBuilding in affectedBuildings) { // Get buildings within radius. foreach(var radiusTile in affectedBuilding.RadiusTiles) { // Get all buildings on Map within this radius (which is technially another foreach). var buildingsInRadius = TileMap.Buildings.Where(b => b.TileIndex == radiusTile.TileIndex); // Do stuff. } }
이 모든 것이 FPS 를 1 초 동안 60에서 거의 10으로 나눕니다 .
그렇게 할 수있을 것입니다. 내 아이디어는 다음과 같습니다.
- 이 스레드에는 주 스레드 (업데이트 기능)를 사용하지 않고 다른 스레드를 사용합니다. 멀티 스레딩을 사용할 때 잠금 문제가 발생할 수 있습니다.
- 대기열을 사용하여 많은 계산 처리 (이 경우 가장 좋은 방법은 무엇입니까?)
- 더 많은 계산 (예 : 반경이있는 건물)을 피하려면 객체 (건물)에 더 많은 정보를 보관하십시오.
마지막 접근법을 사용하여 대신이 foreach 형태로 하나의 중첩을 제거 할 수 있습니다.
// Go through all buildings affected by erasing this road tile.
foreach(var affectedBuilding in affectedBuildings) {
// Go through buildings within radius.
foreach(var buildingInRadius in affectedBuilding.BuildingsInRadius) {
// Do stuff.
}
}
그러나 이것이 충분한 지 모르겠습니다. 플레이어가 큰지도를 가지고있는 경우 도시 스카이 라인과 같은 게임은 훨씬 더 많은 건물을 처리해야합니다. 그들은 어떻게 그런 일을 처리합니까?! 모든 건물이 동시에 업데이트되지는 않으므로 업데이트 대기열이있을 수 있습니다.
나는 당신의 아이디어와 의견을 기대하고 있습니다!
고마워요!