// Start is called before the first frame update
    void Start()
    {
        dictFloor = new Dictionary <uint, FloorController>(floorData.Count);

        foreach (KeyValuePair <uint, FloorData> item in floorData)
        {
            GameObject floor = Instantiate(pfFloor, layoutFloor.transform);
            floor.transform.SetAsFirstSibling(); // for the right visual order
            FloorController component = floor.GetComponent <FloorController>();
            if (component)
            {
                component.SetFloorData(item.Value);
                component.UpdateUI();
                component.SetCallElevatorRequestCallback(OnGetCallElevatorRequest);
                dictFloor.Add(item.Key, component);
            }
        }

        FloorController topFloorController = GetFloorController(GameConfig.GetTopFloor());

        if (topFloorController)
        {
            // Cannot use position of top floor because its correct position will be updated in next frame.
            elevatorController.SetAtDefaultAnchoredPositionY();
        }

        elevatorController.SetOnElevatorStatusUpdateCallback(OnGetElevatorStatusUpdateRequest);
        elevatorController.SetUpdateElevatorPositionCallback(OnGetUpdateElevatorPositionRequest);

        SendElevatorData();
        SendElevatorStatusResponseToAllFloor();
    }