Пример #1
0
    /*
     * If the player releases the right mouse button, the last grid-element is being removed and the input-behaviour is reset.
     * @param   context The information provided with the triggering event. In this case the release of the right-mouse-button.
     */
    public void StopRemoving(InputAction.CallbackContext context)
    {
        // Before resetting the input-bevaviour to not remove any object, after the mouse moved, remove the last element which was hit.

        // Placing and removing objects is only allowed, when the selection is not blocked.
        // This indicates that there is no socket left to place for a logic-element.
        if (!_selectionBlocked)
        {
            // Cast a ray from the camera through the cursor and identify the hit object.
            Ray        ray = _camera.go.GetComponent <Camera>().ScreenPointToRay(Mouse.current.position.ReadValue());
            RaycastHit hit;

            // If any object has been hit, remove it from the grid and play a feedback sound.
            if (Physics.Raycast(ray, out hit))
            {
                // Play a sound through to indicate a successfull removal.
                AudioManager.instance.PlaySound(clips[0]);

                // Identify the hit by it's coordinates in the grid.
                Vector2Int temp = _mainGrid.grid.GetCoordinate(hit.point);

                // Place a filler-element on the identified coordinates, thusly "removing" the element.
                Placer.PlaceObject(_mainGrid.grid, _filler.go, temp.x, temp.y, _filler.go);
            }
        }

        // After the last element has been removed, reset to normal input-bevahiour
        _inputs.Schaltnetz.PreviewBuilding.performed -= RemoveMore;
    }
Пример #2
0
    private void Awake()
    {
        UITableFiller.FillTable(_panel, _resolveResults, _variableCount.value, _expectedResults.valueArray, 2);
        UITableFiller.FillTable(_expectedPanel, _expectedResults.valueArray, _variableCount.value, _expectedResults.valueArray, 2);
        inventory      = new Grid(1, 1, 20, new Vector3(-30, 0, 0));
        grid           = new Grid(_width, _height, _cellSize, _offset);
        _mainGrid.grid = grid;
        _auxGrid.grid  = inventory;
        GameObject ground = Resources.Load <GameObject>("Prefabs/ground");

        for (int i = 0; i < _width; i++)
        {
            for (int j = 0; j < _height; j++)
            {
                Placer.PlaceObject(grid, ground, i, j);
            }
        }
        InputHandler.instance.ChangeGIT(GameInputType.GateBuilder);
        Placer.PlaceObject(inventory, ground, 0, 0);
        GameObject start = Resources.Load <GameObject>("Prefabs/start");
        GameObject end   = Resources.Load <GameObject>("Prefabs/end");

        foreach (StartingPointData startingpoint in _startingpoints)
        {
            GameObject temp = Placer.PlaceObject(grid, start, startingpoint.position.x, startingpoint.position.y);
            temp.GetComponent <StartingPoint>().SetCharge(startingpoint.charge);
        }
        Placer.PlaceObject(grid, end, _endpoint.x, _endpoint.y);
    }
Пример #3
0
    private void Awake()
    {
        _selectionPanel.go = _selectionPanelGO;
        _results           = new int[(int)Mathf.Pow(2, _variableCount.value)];
        _outputs           = new MultiCellElement[_outputCount.value];
        _mainCamera.go     = this.gameObject;
        _grid = new Grid(100, 100, 5, Vector3.zero);
        InputHandler.instance.ChangeGIT(GameInputType.Plotter);
        InputHandler.instance.floatingText = _floatingText;
        _mainGrid.grid = _grid;
        GameObject empty = Resources.Load <GameObject>("Prefabs/emptyCube");

        _filler.go = empty;
        for (int i = 0; i < _width; i++)
        {
            for (int j = 0; j < _height; j++)
            {
                GameObject tempObj = Placer.PlaceObject(_grid, empty, i, j);
            }
        }
        int offSetX = _startingPointGo.GetComponent <GridElement>().size.x;
        int offSetY = _startingPointGo.GetComponent <GridElement>().size.y;

        for (int i = 0; i < _variableCount.value; i++)
        {
            GameObject tempMCE = Placer.PlaceMultiCellObject(_grid, _startingPointGo, _startingpoints[i].x, _startingpoints[i].y, _filler.go);
            if (tempMCE.GetComponentInChildren <TMP_Text>())
            {
                tempMCE.GetComponentInChildren <TMP_Text>().text = ((Charge)i + 1).ToString();
            }

            Vector2Int tempVecOutgoingSocket = new Vector2Int(_startingpoints[i].x + offSetX, _startingpoints[i].y);
            GameObject tempObj = Placer.PlaceObject(_grid, _outGoingSocket, _startingpoints[i].x + offSetX, _startingpoints[i].y);

            tempMCE.GetComponent <MultiCellElement>().AddToList(tempMCE.GetComponent <MultiCellElement>().outgoingSockets, tempVecOutgoingSocket);
            tempMCE.GetComponent <MultiCellElement>().outgoingSocketObjects.Add(tempObj.GetComponent <OutGoingSocket>());
        }
        for (int j = 0; j < _outputCount.value; j++)
        {
            GameObject tempMCE = Placer.PlaceMultiCellObject(_grid, _endPointGo, _endPoints[j].x, _endPoints[j].y, _filler.go);
            if (tempMCE.GetComponentInChildren <TMP_Text>())
            {
                tempMCE.GetComponentInChildren <TMP_Text>().text = j.ToString();
            }
            Vector2Int tempVecIncomingSocket = new Vector2Int(_endPoints[j].x - 1, _endPoints[j].y);
            GameObject tempObj = Placer.PlaceObject(_grid, _incomingSocket, tempVecIncomingSocket.x, tempVecIncomingSocket.y);
            tempObj.GetComponent <SocketOfGridElement>().coordsToTarget = new Vector2Int(_endPoints[j].x, _endPoints[j].y);
            tempObj.GetComponent <SocketOfGridElement>().targetGo       = tempMCE;
            tempMCE.GetComponent <MultiCellElement>().AddToList(tempMCE.GetComponent <MultiCellElement>().incomingSockets, tempVecIncomingSocket);
            _outputs[j] = tempMCE.GetComponent <MultiCellElement>();
        }
    }
Пример #4
0
    ////////////////////////////////////////////////////////////////////////////////////////////
    // General Input-Behaviour Methods

    /*
     * Cancel method, to either present the Pause menu, or stop placing a logic element on Powercity.
     * @param   context Information provided by the triggering event. In this case the buttonpress on the ESC-key.
     */
    private void Cancel(InputAction.CallbackContext context)
    {
        // If the selection is blocked, and therefore the player must be placing sockets to an logic-element in powercity, stop this process.
        if (_selectionBlocked)
        {
            Placer.PlaceObject(_mainGrid.grid, _filler.go, tempTargetCoord.x, tempTargetCoord.y, _filler.go);
            _incomingSocketsToPlace = 0;
            _outgoingSocketsToPlace = 0;
            _selectionBlocked       = false;
            selected.go             = null;
            return;
        }
        // In any other case, pause the game.
        PauseGame();
    }
Пример #5
0
    /*
     * After being added to the input-behaviour, this method is called every frame the mouse has moved and is used to continously place connections,
     * while the left mouse-button is being held down.
     * @param   context Information provided by the triggering event. In this case the movement of the mouse.
     */
    private void PlaceConnection(InputAction.CallbackContext context)
    {
        // Cast a ray from the camera through the cursor and keep a reference to the hit object.
        Ray        ray = _camera.go.GetComponent <Camera>().ScreenPointToRay(Mouse.current.position.ReadValue());
        RaycastHit hit;

        // If an object was hit, place a connection-element on it's place.
        if (Physics.Raycast(ray, out hit))
        {
            // Get the coordinates of the hit grid-element, if it is one.
            Vector2Int temp = _mainGrid.grid.GetCoordinate(hit.point);
            // Place a connection element on the hit grid-element.
            Placer.PlaceObject(_mainGrid.grid, selected.go, temp.x, temp.y, _filler.go);
        }
    }
Пример #6
0
    // Start is called before the first frame update
    void Awake()
    {
        SetParams();
        UITableFiller.FillTable(_expectedPanel, _expectedResults.valueArray, _variableCount.value, _expectedResults.valueArray);
        int cellCount = Convert.ToInt32(Math.Pow(2, _variableCount.value));

        while (_width * _height != cellCount)
        {
            if (_width == _height)
            {
                _width *= 2;
            }
            else
            {
                _height *= 2;
            }
        }


        _charges.keyValuePairs      = new Dictionary <char, bool>();
        _charges.keyValuePairs['A'] = true;
        _charges.keyValuePairs['B'] = true;
        _charges.keyValuePairs['C'] = true;
        _charges.keyValuePairs['D'] = true;
        _charges.keyValuePairs['E'] = true;
        _grid          = new Grid(_width, _height, 12, _gridOffset);
        _mainGrid.grid = _grid;

        InputHandler.instance.ChangeGIT(GameInputType.KV);
        Dictionary <char, bool> temp = new Dictionary <char, bool>();
        GameObject empty             = Resources.Load <GameObject>("Prefabs/empty");


        for (int i = 0; i < _width; i++)
        {
            for (int j = 0; j < _height; j++)
            {
                temp = PrepareCharge(i, j);
                GameObject tempObj = Placer.PlaceObject(_grid, empty, i, j);
                tempObj.GetComponent <KVelement>().charge = ChargeCombinationToInt(temp);

                tempObj.GetComponent <KVelement>().text.text = ChargeCombinationToInt(temp).ToString();
            }
        }
        DrawIndicators();
    }
Пример #7
0
    /*
     * This functions places an incoming socket and adjusts it's parameters to react correctly when being visited.
     * @param   coords      The coordinates to place the socket on the grid.
     * @param   targetCoord The coordinates of the logic-element to which this sockets belongs to.
     * @param   filler      The filler-object that is used to fill spaces, in case the placement of the sockets causes a conflict with a multi-cell-element.
     */
    private void PlaceIncomingSocket(Vector2Int coords, Vector2Int targetCoords, GameObject filler)
    {
        // Only place the socket, if the coords is adjacent to the logic-element.
        if (Placer.IsAdjacent(_mainGrid.grid, coords, targetCoords))
        {
            // Get a reference to the newly placed socket.
            GameObject tempObj;
            tempObj = Placer.PlaceObject(_mainGrid.grid, selected.go, coords.x, coords.y, _filler.go);

            // If the placement was successfull, play a sound and adjust attributes of the socket and the logic-element.
            if (tempObj)
            {
                // Auditive feedback for the successfull placement.
                AudioManager.instance.PlaySound(clips[0]);
                // Set the target-logic-element coordinates to the saved coordinates.
                tempObj.GetComponent <SocketOfGridElement>().coordsToTarget = tempTargetCoord;
                // Set the target-logic-element to be the target of the socket.
                tempObj.GetComponent <SocketOfGridElement>().targetGo = _mainGrid.grid.GetObjFromCoordinate(tempTargetCoord);
                // Add this socket to the list of incoming sockets of the logic-element.
                MultiCellElement targetMCE = _mainGrid.grid.GetObjFromCoordinate(tempTargetCoord).GetComponent <MultiCellElement>();

                // Nullchecking the element. Might not really be neccessary, if the inventory is correct, which it should.
                if (tempObj.GetComponentInChildren <TMP_Text>())
                {
                    // Set the text of the prefab to the corresponding variable it resembles.
                    // The first incoming socket is always A, the second is B, the third is C and so on.
                    tempObj.GetComponentInChildren <TMP_Text>().text = ((Charge)targetMCE.incomingSockets.Count + 1).ToString();
                }
                targetMCE.AddToList(targetMCE.incomingSockets, coords);

                // Decrement the number of incoming sockets needed to be placed by the player.
                _incomingSocketsToPlace--;
            }
        }
        // Show a message, reminding the player that sockets need to be placed adjacent to the element.
        else
        {
            floatingText.GetComponent <Animation>().Play();
        }
    }
Пример #8
0
    /*
     * Similar to placing an incoming socket, but still different.
     * @param   coords      The coordinates to place the socket on the grid.
     * @param   targetCoord The coordinates of the logic-element to which this sockets belongs to.
     * @param   filler      The filler-object that is used to fill spaces, in case the placement of the sockets causes a conflict with a multi-cell-element.
     */
    private void PlaceOutgoingSocket(Vector2Int coords, Vector2Int targetCoords, GameObject filler)
    {
        // Also outgoing sockets can only be placed adjacent to logic-elements.
        if (Placer.IsAdjacent(_mainGrid.grid, coords, targetCoords))
        {
            // Get a reference to the newly placed socket.
            GameObject tempObj;
            tempObj = Placer.PlaceObject(_mainGrid.grid, selected.go, coords.x, coords.y, _filler.go);


            // If the placement was successfull, play a sound and adjust attributes of the socket and the logic-element.
            if (tempObj)
            {
                AudioManager.instance.PlaySound(clips[0]);

                // Since outgoingsockets can't be visited, we only need to add the socket to the logic-elements list of outgoing sockets.
                // There is no need to define a target for the outgoing socket.
                MultiCellElement targetMCE = _mainGrid.grid.GetObjFromCoordinate(tempTargetCoord).GetComponent <MultiCellElement>();
                if (tempObj.GetComponentInChildren <TMP_Text>())
                {
                    // Set the text of the prefab to the corresponding variable it resembles.
                    // The first outgoing socket is always 0, the second is 1, the third is 2 and so on.
                    tempObj.GetComponentInChildren <TMP_Text>().text = targetMCE.outgoingSockets.Count.ToString();
                }
                targetMCE.AddToList(targetMCE.outgoingSockets, coords);
                targetMCE.outgoingSocketObjects.Add(tempObj.GetComponent <OutGoingSocket>());


                // Decrement the number of incoming sockets needed to be placed by the player.
                _outgoingSocketsToPlace--;
            }
        }
        // Show a message, reminding the player that sockets need to be placed adjacent to the element.
        else
        {
            floatingText.GetComponent <Animation>().Play();
        }
    }
Пример #9
0
    ////////////////////////////////////////////////////////////////////////////////////////////
    // Trackymania Input-Behaviour Methods

    /*
     * Function to place a selected Track onto the grid in the scene.
     * Is triggered by left-mouse interaction on GateBuilder ActionMap and ClickAction Action.
     * @param   context Inputcontext given bei the Actionevent. This is not needed for further calculations, but is neccessary to subscribe to inputevents.
     */
    private void PlaceSelected(InputAction.CallbackContext context)
    {
        // Fire a ray from the Camera through the Cursor to determine which Object was clicked.
        Ray ray = _camera.go.GetComponent <Camera>().ScreenPointToRay(Mouse.current.position.ReadValue());
        // Hit information of the raycast.
        RaycastHit hit;

        // Continue only if the Raycast hit an object in the scene.
        if (Physics.Raycast(ray, out hit))
        {
            // Calculate the Coordinates of the GameObject hit by the Raycast.
            Vector2Int temp = _mainGrid.grid.GetCoordinate(hit.point);
            // Check if the hit element is a Gridelement.
            GridElement selection = hit.collider.gameObject.GetComponent <GridElement>();

            // If the hit Object has valid coordinates, it must be on the grid. Place the selected Object onto the grid on the calculated coordinates.
            if (temp.x >= 0)
            {
                // If the player has a grid element in the inventory, place it on the gameboard and play a sound.
                if (selected.go != null)
                {
                    AudioManager.instance.PlaySound(clips[4]);
                    Placer.PlaceObject(_mainGrid.grid, selected.go, temp.x, temp.y);
                }
            }

            // If the Coordinates of the hit object are not valid, check if the hit object is a gridelement.
            // This must mean the player has selected a grid element for the inventory.
            else if (selection != null)
            {
                // To add the newly chosen element to the inventory, it must be removeable.
                // This must be done, to remove it from the inventory, in case the player chooses another element for the inventory in the future.
                selection.isRemoveable = true;
                selected.go            = Placer.PlaceObject(_auxGrid.grid, selection.gameObject, 0, 0);
            }
        }
    }
Пример #10
0
    /*
     * Method to be added to the input-behaviour when removing objects is needed. This will be done by the Remove-Method.
     * After adding this method to the input-behaviour, it will be triggered every frame the mouse has moved, removing all objects the mouse has hit.
     * @param   context Informationen provided with the triggering event. In this case the movement of the mouse.
     */
    public void RemoveMore(InputAction.CallbackContext context)
    {
        // Placing and removing objects is only allowed, when the selection is not blocked.
        // This indicates that there is no socket left to place for a logic-element.
        if (!_selectionBlocked)
        {
            // Cast a ray from the camera through the cursor and get a refenrence to the hit object, if there is one.
            Ray        ray = _camera.go.GetComponent <Camera>().ScreenPointToRay(Mouse.current.position.ReadValue());
            RaycastHit hit;

            // If an object was hit, try removing it. This will be successfull, if it is a removeable grid-element.
            if (Physics.Raycast(ray, out hit))
            {
                // Play a sound to indicate a successfull removal.
                AudioManager.instance.PlaySound(clips[0]);

                // Get the coordinates of the hit object in the grid.
                Vector2Int temp = _mainGrid.grid.GetCoordinate(hit.point);

                // Remove the hit object by placing a filler-element on it's coordinates.
                Placer.PlaceObject(_mainGrid.grid, _filler.go, temp.x, temp.y, _filler.go);
            }
        }
    }
Пример #11
0
    /*
     * Method to handle left-mouse clicks. These can lead to various cases, depending on the clicked Object in the scene.
     * @param   context Context of the Actionevent. In this case the method is triggered by leftclick. The information about the event are not used further.
     */
    private void LeftClickPC(InputAction.CallbackContext context)
    {
        // First, cast a ray from the camera through the mouse-cursor and check for hits.
        Ray        ray = _camera.go.GetComponent <Camera>().ScreenPointToRay(Mouse.current.position.ReadValue());
        RaycastHit hit;

        // If an object was hit, check various cases.
        if (Physics.Raycast(ray, out hit))
        {
            // Get the coordinates of the hit object in the grid.
            Vector2Int temp = _mainGrid.grid.GetCoordinate(hit.point);

            // If the hit object in the grid is a multiCellElement, show it's truthtable in the selection UI-Panel and return.
            if (_mainGrid.grid.GetObjFromCoordinate(temp).GetComponent <MultiCellElement>())
            {
                FillSelectionResultTable(_mainGrid.grid.GetObjFromCoordinate(temp).GetComponent <MultiCellElement>());
                return;
            }
            // If anything else was hit, hide the selection UI-panel.
            else
            {
                selectionPanel.go.SetActive(false);
            }


            // If the player hasn't selected a specific object to place, start placing connections as long as the left-mouse button is held down.
            // This is done by changing input-behaviour to place a connection every frame, that the mouse has moved.
            // Either the player has already placed a connection-element, in that case only the input-behaviour has to be changed.
            // Otherwise, the connection-element has to be placed in the inventory.
            if (!selected.go)
            {
                _inputs.Schaltnetz.PreviewBuilding.performed += PlaceConnection;
                selected.go = _connection.go;
                UpdatePreview();
            }
            else
            if (selected.go == _connection.go)
            {
                _inputs.Schaltnetz.PreviewBuilding.performed += PlaceConnection;
            }


            // If the player has something in the inventory, that is not null or a connection-element, takes this route.
            if (temp.x >= 0)
            {
                // Check if the player still has to place incoming or outgoingsockets. If so, try to place the correct element on the clicked spot.
                // If there are no left sockets left to place, skip this part

                // If there are sockets to place, first the incoming, then the outgoing sockets are going to be placed.
                if (_incomingSocketsToPlace > 0 || _outgoingSocketsToPlace > 0)
                {
                    if (_incomingSocketsToPlace > 0)
                    {
                        PlaceIncomingSocket(temp, tempTargetCoord, _filler.go);
                        // After placing the last incoming socket, change the element in the inventory for the next placement.
                        if (_incomingSocketsToPlace <= 0)
                        {
                            selected.go = _outgoingSocketPrefab;
                            UpdatePreview();
                        }
                    }
                    // After all incoming sockets have been placed, place all outgoing sockets.
                    else
                    {
                        PlaceOutgoingSocket(temp, tempTargetCoord, _filler.go);
                        // When all outgoingsockets are placed, reset the inventory and unlock the selection.
                        if (_outgoingSocketsToPlace <= 0)
                        {
                            _selectionBlocked = false;
                            selected.go       = null;
                            UpdatePreview();
                        }
                    }
                }

                // This section handles the case, that the player wants to place an element, that is not a connection and has no sockets left to place.
                else
                {
                    // Variable used to store a reference to the newly placed element.
                    GameObject tempObj;

                    // Give the player auditive feedback about the placement.
                    AudioManager.instance.PlaySound(clips[0]);

                    // If the element in the inventory only is 1x1 gridcells big, just place it on the grid.
                    if (selected.go.GetComponent <GridElement>().size.x == 1 && selected.go.GetComponent <GridElement>().size.y == 1)
                    {
                        // Place the object and take a reference.
                        tempObj = Placer.PlaceObject(_mainGrid.grid, selected.go, temp.x, temp.y, _filler.go);
                    }
                    // Bigger elements need to be placed differently, since there can happen multiple conflicts while placing them on the grid.
                    else
                    {
                        // Place the object and take a reference.
                        tempObj = Placer.PlaceMultiCellObject(_mainGrid.grid, selected.go, temp.x, temp.y, _filler.go);

                        // Bigger elements get a text to identify them on the board. They get a Tag with the given name that is placed right above them.
                        if (tempObj.GetComponentInChildren <TMP_Text>())
                        {
                            tempObj.GetComponentInChildren <TMP_Text>().text = tempObj.GetComponent <MultiCellElement>().name;
                        }
                    }

                    // After placing an object, check if the object needs to have incoming or outgoing sockets. If so, set the counters and lock the selection.
                    // This way, the player will have to place all remaining sockets before being able to place more elements.
                    if (tempObj && (tempObj.GetComponent <GridElement>().incomingSocketCount > 0 || tempObj.GetComponent <GridElement>().outComingSocketCount > 0))
                    {
                        // Block the player from placing other elements, while having to place sockets.
                        _selectionBlocked = true;

                        // Save the coordinates of the newly placed object for when the incoming and outgoing sockets are being planced.
                        tempTargetCoord = temp;

                        // Increase the counter to show how many sockets need to be placed.
                        _incomingSocketsToPlace = tempObj.GetComponent <GridElement>().incomingSocketCount;
                        _outgoingSocketsToPlace = tempObj.GetComponent <GridElement>().outComingSocketCount;

                        // Start by placing incoming sockets by filling the inventory with an incoming socket.
                        selected.go = _incomingSocketPrefab;

                        // Update the preview, so the player can see where the element would be placed.
                        UpdatePreview();
                    }
                }
            }
        }
    }