Example #1
0
    // Update is called once per frame
    void Update()
    {
        if (mode == EditableModelMode.Trileset)
        {
            return;
        }

        if (Input.GetKey(KeyCode.E))
        {
            if (Input.GetMouseButtonDown(0))
            {
                RaycastHit rh;
                if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rh))
                {
                    Vector3 hitPointWorld = rh.point - ((rh.normal / 16 / 2) * 1.1f);
                    IntPos  hitPosArray   = IntPos.Vector3ToIntPos((hitPointWorld * 16) + Vector3.one * 8);

                    if (hitPosArray.isContained(0, 16))
                    {
                        if (data.Contains(hitPosArray))
                        {
                            data.Remove(hitPosArray);
                        }

                        UpdateMesh();
                    }
                }
            }
            if (Input.GetMouseButtonDown(1))
            {
                RaycastHit rh;
                if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rh))
                {
                    Vector3 hitPointWorld = rh.point + ((rh.normal / 16 / 2) * 1.1f);
                    IntPos  hitPosArray   = IntPos.Vector3ToIntPos((hitPointWorld * 16) + Vector3.one * 8);

                    if (hitPosArray.isContained(0, 16))
                    {
                        if (!data.Contains(hitPosArray))
                        {
                            data.Add(hitPosArray);
                        }
                        UpdateMesh();
                    }
                }
            }
        }
    }
    private bool _ShowBlockAtPosition(IntPos pos)
    {
        bool opResult = false;

        try
        {
            if (_blocks[pos.x, pos.y, pos.z] != (byte)BLOCK_ID.AIR)
            {
                _blockArray[pos.x, pos.y, pos.z] = (Instantiate(blockDatabase.GetBlockPrefab(_blocks[pos.x, pos.y, pos.z]), pos.Vec3(), Quaternion.identity));
                _blockArray[pos.x, pos.y, pos.z].transform.SetParent(theWorld.transform);
                opResult = true;
            }
        }
        catch (System.Exception ex)
        {
            Debug.Log("Error: PlaceBlock: " + ex.Message);
        }

        return(opResult);
    }
    /// <summary>
    /// Remove a block from the world and replace it with air. Will NOT remove air blocks
    /// </summary>
    /// <param name="blockPos"></param>
    /// <returns>
    /// true if the operation succeeded
    /// </returns>
    public bool RemoveBlock(IntPos blockPos)
    {
        bool opResult = false;

        try
        {
            if (_blocks[blockPos.x, blockPos.y, blockPos.z] != (byte)BLOCK_ID.AIR)
            {
                // fill with air
                _blocks[blockPos.x, blockPos.y, blockPos.z] = (byte)BLOCK_ID.AIR;
                Destroy(_blockArray[blockPos.x, blockPos.y, blockPos.z]);
                _UpdateBlockNeighborhood(blockPos);

                opResult = true;
            }
        }
        catch (System.Exception ex)
        {
            Debug.Log("Error: RemoveBlock: " + ex.Message);
        }

        return(opResult);
    }
    public static bool[,,] GetModelDataFromTrile(Trile trile)
    {
        int size = 16;

        TrixelState[,,] states = new TrixelState[size, size, size];
        bool[,,] returnArray   = new bool[size, size, size];

        Vector3[] dirs = new Vector3[] { Vector3.up, Vector3.down, Vector3.right, Vector3.left, Vector3.forward, Vector3.back };

        //Pass 1, put the mesh collider into the array's data.
        for (int x = -1; x < size + 2; x++)
        {
            for (int y = -1; y < size + 2; y++)
            {
                for (int z = -1; z < size + 2; z++)
                {
                    try {
                        states[x, y, z] = TrixelState.Unchecked;
                    }
                    catch {
                    }
                    foreach (Vector3 d in dirs)
                    {
                        Vector3 pos = (((new Vector3(x, y, z) - Vector3.one / 2) / size) - Vector3.one / 2) + importerCollider.transform.position;

                        RaycastHit rh;

                        if (Physics.Raycast(new Ray(pos, d), out rh, 1f / size))
                        {
                            rh.point -= importerCollider.transform.position;
                            IntPos hitPos = IntPos.Vector3ToIntPos((rh.point * 16) - rh.normal / 2) + (size / 2);
                            try {
                                states[hitPos.x, hitPos.y, hitPos.z] = TrixelState.isCollider;
                            } catch {
                            }
                        }
                    }
                }
            }
        }

        //Pass 2, check if each trixel exposed to in any of the 6 cardinal directions.
        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                for (int z = 0; z < size; z++)
                {
                    int blockCount = 0;

                    foreach (Vector3 d in dirs)
                    {
                        Vector3 currPos    = new Vector3(x, y, z);
                        IntPos  currPosInt = new IntPos(x, y, z);

                        bool isBlocked = false;

                        while (currPosInt.isContained(0, size))
                        {
                            TrixelState getState = states[currPosInt.x, currPosInt.y, currPosInt.z];
                            if (getState == TrixelState.isCollider || getState == TrixelState.isNotExposedToEdge)
                            {
                                isBlocked = true;
                                break;
                            }
                            currPos   += d;
                            currPosInt = IntPos.Vector3ToIntPos(currPos);
                        }
                        if (isBlocked)
                        {
                            blockCount++;
                        }
                    }

                    if (blockCount == 6)
                    {
                        states[x, y, z] = TrixelState.isNotExposedToEdge;
                    }
                    else
                    {
                        states[x, y, z] = TrixelState.isExposedToEdge;
                    }
                }
            }
        }



        //Pass 3, check if each trixel is exposed to a trixel that's exposed to air.
        //This is actually done twice, just in case.
        for (int i = 0; i < 2; i++)
        {
            TrixelState[,,] tempStates = new TrixelState[16, 16, 16];

            for (int x = 0; x < size; x++)
            {
                for (int y = 0; y < size; y++)
                {
                    for (int z = 0; z < size; z++)
                    {
                        tempStates[x, y, z] = states[x, y, z];
                    }
                }
            }

            for (int x = 0; x < size; x++)
            {
                for (int y = 0; y < size; y++)
                {
                    for (int z = 0; z < size; z++)
                    {
                        if (states[x, y, z] != TrixelState.isNotExposedToEdge)
                        {
                            continue;
                        }

                        bool isBlocked = true;

                        foreach (Vector3 d in dirs)
                        {
                            Vector3 currPos    = new Vector3(x, y, z);
                            IntPos  currPosInt = new IntPos(x, y, z);

                            while (currPosInt.isContained(0, size))
                            {
                                TrixelState getState = states[currPosInt.x, currPosInt.y, currPosInt.z];
                                if (getState == TrixelState.isExposedToEdge)
                                {
                                    isBlocked = false;
                                    break;
                                }
                                else if (getState == TrixelState.isCollider || getState == TrixelState.isNotExposedToEdge)
                                {
                                    break;
                                }
                                currPos   += d;
                                currPosInt = IntPos.Vector3ToIntPos(currPos);
                            }
                            if (!isBlocked)
                            {
                                tempStates[x, y, z] = TrixelState.isExposedToEdge;
                                break;
                            }
                        }
                    }
                }
            }
            states = tempStates;
        }

        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                for (int z = 0; z < size; z++)
                {
                    if (states[x, y, z] == TrixelState.isCollider || states[x, y, z] == TrixelState.isNotExposedToEdge)
                    {
                        returnArray[x, y, z] = true;
                    }
                    else if (states[x, y, z] == TrixelState.isExposedToEdge)
                    {
                        returnArray[x, y, z] = false;
                    }
                }
            }
        }
        importerCollider.gameObject.SetActive(false);
        return(returnArray);
    }
Example #5
0
 public static float DistanceSqr(IntPos i1, IntPos i2)
 {
     return((i1 - i2).sqrMagnitude);
 }
 public RemoveBlockCommand(byte blockTypeAtPosition, IntPos targetPosition)
 {
     m_targetPosition  = targetPosition;
     blockTypeToRemove = blockTypeAtPosition;
 }
 public RemoveBlockCommand(Vector3 targetPosition)
 {
     m_targetPosition  = new IntPos(targetPosition);
     blockTypeToRemove = s_world.GetBlockID(m_targetPosition);
 }
 public AddBlockCommand(byte placedBlockType, Vector3 targetPosition)
 {
     m_targetPosition    = new IntPos(targetPosition);
     blockType           = placedBlockType;
     m_targetOrientation = new IntPos(0, 1, 0);
 }
 public AddBlockCommand(byte placedBlockType, IntPos targetPosition, IntPos targetOrientation)
 {
     m_targetPosition    = targetPosition;
     blockType           = placedBlockType;
     m_targetOrientation = targetOrientation;
 }
    // Update is called once per frame
    void Update()
    {
        if (itemsHaveChanged)
        {
            _loadItemsFromEquippedList();
            itemsHaveChanged = false;
        }


        bool raycastHit = false;

        RaycastHit hit;

        // only collide raycast with Blocks layer
        int layerMaskBlocksOnly = LayerMask.GetMask("Blocks");

        // Does the ray intersect any objects excluding the player layer
        if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, m_maxBlockPlacingRange, layerMaskBlocksOnly))
        {
            raycastHit = true;
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
        }
        else
        {
            Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 10, Color.white);
        }


        // Input Function
        if (Input.anyKeyDown)
        {
            int numberKey = 0;
            if (int.TryParse(Input.inputString, out numberKey))
            {
                if ((numberKey > 0) && (numberKey < 8))
                {
                    // remap from 1234567890 to 0123456789 (because of keyboard layout)
                    toolbarSlotSelection = (numberKey + 9) % 10;

                    if (activeItems[toolbarSlotSelection].transform.childCount > 0)
                    {
                        string itemName     = activeItems[toolbarSlotSelection].transform.GetChild(0).gameObject.name;
                        int    bracketIndex = itemName.IndexOf("(");
                        itemName           = itemName.Substring(0, bracketIndex);
                        blockTypeSelection = (BLOCK_ID)System.Enum.Parse(typeof(BLOCK_ID), itemName.ToUpper());
                        _hideSelectors();
                        selectors[toolbarSlotSelection].SetActive(true);
                    }
                }
            }
        }


        currentlySelectedBlockUI.text = blockDatabase.GetProperties((BLOCK_ID)blockTypeSelection).m_description;


        // if selection within range
        if (raycastHit)
        {
            // determine if block place position is too close to the player
            Vector3 blockPlacePosition   = new IntPos((hit.point) + (hit.normal * 0.5f) + new Vector3(0.5f, 0.5f, 0.5f)).Vec3();//(new IntPos(((hit.point) + (hit.normal * 0.1f))).Vec3() + new Vector3(0.5f, 0.5f, 0.5f));
            IntPos  integerPlacePosition = new IntPos(blockPlacePosition);

            // position of the block the raycast hit
            IntPos hitBlockPosition = new IntPos((hit.point) + (hit.normal * -0.5f) + new Vector3(0.5f, 0.5f, 0.5f));

            byte hitBlockType = world.GetBlockID(hitBlockPosition);

            // get all properties of the block the raycast hit
            BlockProperties hitBlockProperties = blockDatabase.GetProperties((BLOCK_ID)hitBlockType);

            // show description text for block
            blockDescriptionUI.text = hitBlockProperties.m_description;

            // put visible ghost block there and make it visible
            ghostBlock.transform.position = blockPlacePosition;
            ghostBlock.gameObject.SetActive(true);

            { // Debug block selection
                Debug.DrawRay(blockPlacePosition, new Vector3(0.5f, 0.0f, 0.0f), Color.red);
                Debug.DrawRay(blockPlacePosition, new Vector3(0.0f, 0.5f, 0.0f), Color.green);
                Debug.DrawRay(blockPlacePosition, new Vector3(0.0f, 0.0f, 0.5f), Color.blue);

                Debug.DrawRay(blockPlacePosition, new Vector3(0.0f, -0.5f, 0.0f), Color.yellow);
            }

            // Place Block
            if ((Input.GetButtonDown("PlaceBlock")))
            {
                // determine if block place position is too close to the player
                if (!ghostBlock.IsColliding() && hitBlockProperties.m_canBePlacedUpon)
                {
                    Debug.Log("Placing block!");
                    Command cmd = new AddBlockCommand((byte)blockTypeSelection, integerPlacePosition);

                    if (Execute(ref cmd))
                    {
                        // send notification that a Block was placed
                        NotifyAll(gameObject, OBSERVER_EVENT.PLACED_BLOCK);
                    }
                }   // endif ghostBlock colliding
                else
                {
                    Debug.Log("Cannot place block--Entity is in the way!");
                }
            }

            // Remove Block
            if (Input.GetButtonDown("RemoveBlock"))
            {
                Debug.Log("Removing block!");
                Command cmd = new RemoveBlockCommand(hitBlockType, hitBlockPosition);
                Execute(ref cmd);
            }
        }
        else // endif raycast hit
        {
            ghostBlock.gameObject.SetActive(false);
            blockDescriptionUI.text = "";
        }

        // Undo Last
        if (Input.GetButtonDown("Cancel") || Input.GetKeyDown(KeyCode.Backspace))
        {
            if (commandList.Count > 0)
            {
                var lastAction = commandList.Last;

                if (lastAction.Value.IsCompleted())
                {
                    lastAction.Value.Undo();
                }
                else
                {
                    Debug.Log("Could not Undo! Action not completed! Removing uncompleted action");
                }

                commandList.RemoveLast();
            }
            else
            {
                Debug.Log("Could not Undo! Nothing to Undo!");
            }
        }
    }
    public void Regenerate(bool fromSavedMap)
    {
        if (!fromSavedMap)
        {
            RemoveAllBlocksFromWorld();
            _blocks     = new byte[width, height, depth];
            _blockArray = new GameObject[width, height, depth];
            MakeAllAir();


            float rand = Random.Range(MinPower, MaxPower);

            float offsetX = Random.Range(-1024.0f, 1024.0f);
            float offsetY = Random.Range(-1024.0f, 1024.0f);

            // Generation
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    for (int z = 0; z < depth; z++)
                    {
                        if (y < Mathf.PerlinNoise((x + offsetX) / rand, (z + offsetY) / rand) * height * 0.5)
                        {
                            _blocks[x, y, z] = (byte)Random.Range(1, 3);
                        }
                    }
                }
            }
        }


        // Private Methods
        _InstantiateBlocksFromVoxelData();

        Vector3 playerSpawnPos = new Vector3(width * 0.5f, height + 10.0f, depth * 0.5f);

        ball.transform.position       = playerSpawnPos + new Vector3(1.0f, -1.0f, 0.0f);
        tpBuilding.transform.position = playerSpawnPos + new Vector3(0.0f, -4.0f, 0.0f);

        spawnPoint.transform.position = playerSpawnPos;
        player.transform.position     = spawnPoint.transform.position;


        // spawn temple
        IntPos playerPos = new IntPos(player.transform.position);

        if (!fromSavedMap)
        {
            // create platform
            int spawnPlatformWidth = 3;

            _GeneratePlatform(playerPos.x, playerPos.z, spawnPlatformWidth, 2, 5, BLOCK_ID.MARBLE);
            _GeneratePlatform(playerPos.x, playerPos.z, 1, 1, 1, BLOCK_ID.MARBLE);

            _GenerateColumn(playerPos.x - spawnPlatformWidth, playerPos.z - spawnPlatformWidth);
            _GenerateColumn(playerPos.x + spawnPlatformWidth, playerPos.z + spawnPlatformWidth);

            _GenerateColumn(playerPos.x - spawnPlatformWidth, playerPos.z + spawnPlatformWidth);
            _GenerateColumn(playerPos.x + spawnPlatformWidth, playerPos.z - spawnPlatformWidth);

            _StackBlockOnSurface(playerPos.x, playerPos.z, (byte)BLOCK_ID.COLUMN_BASE);


            // create walls around world

            _GenerateWalls((byte)BLOCK_ID.MARBLE, (uint)height / 2);
        }
    }
    // update neighboring blocks to a passed position so that Block Gameobjects are spawned only when they can be seen
    private void _UpdateBlockNeighborhood(IntPos pos)
    {
        // if the center block is transparent, then its neighborhood might need to have blocks added to it
        if (blockDatabase.IsTransparent((BLOCK_ID)_blocks[pos.x, pos.y, pos.z]))
        {
            //// x
            {
                IntPos newPos = pos;
                newPos.x += 1;

                // if there is no gameobject next to it...
                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    // fill that gameobject spot with the corresponding block type that should be in that voxel (if it is supposed to be air then PlaceBlock will not place one)
                    _ShowBlockAtPosition(newPos);
                }
            }

            {
                IntPos newPos = pos;
                newPos.x -= 1;

                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    _ShowBlockAtPosition(newPos);
                }
            }


            //// y
            {
                IntPos newPos = pos;
                newPos.y += 1;

                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    _ShowBlockAtPosition(newPos);
                }
            }

            {
                IntPos newPos = pos;
                newPos.y -= 1;

                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    _ShowBlockAtPosition(newPos);
                }
            }


            //// z
            {
                IntPos newPos = pos;
                newPos.z += 1;

                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    _ShowBlockAtPosition(newPos);
                }
            }

            {
                IntPos newPos = pos;
                newPos.z -= 1;

                if (_blockArray[newPos.x, newPos.y, newPos.z] == null)
                {
                    _ShowBlockAtPosition(newPos);
                }
            }
        }
        else
        {
            // The target block is opaque, therefore some blocks may need to be hidden
            // TODO: hide blocks that are no longer visible because of an addition of a block on top of it
        }
    }
 /// <summary>
 /// Place a block into the world, will NOT place air blocks
 /// </summary>
 /// <param name="blockTypeID"></param>
 /// <param name="blockPos"></param>
 /// <returns>
 /// true if the operation succeeded
 /// </returns>
 public bool PlaceBlock(byte blockTypeID, IntPos blockPos)
 {
     return(PlaceBlock(blockTypeID, blockPos.x, blockPos.y, blockPos.z));
 }
 public byte GetBlockID(IntPos blockPos)
 {
     return(_blocks[blockPos.x, blockPos.y, blockPos.z]);
 }