Example #1
0
    /// <summary>
    /// Executes an unprecise raycast.
    /// Only use this for getting the block position. if you need the face you should use the TerrainRaycastPrecise() function.
    /// </summary>
    /// <returns><c>true</c>, if raycast unprecise was terrained, <c>false</c> otherwise.</returns>
    /// <param name="ray">Ray.</param>
    /// <param name="length">Length.</param>
    /// <param name="hitInfo">Hit info.</param>
    public static bool TerrainRaycastUnprecise(Ray ray, float length, out CubicRaycastHitInfo hitInfo)
    {
        Vector3 startPoint = ray.origin;
        Vector3 direction  = ray.direction;

        return(TerrainRaycast(startPoint, direction, 0.49f, length, out hitInfo, false));
    }
Example #2
0
    /// <summary>
    /// Terrain raycast overloaded function.
    /// </summary>
    /// <returns><c>true</c>, if raycast hit a block, <c>false</c> otherwise.</returns>
    /// <param name="ray">Ray.</param>
    /// <param name="stepWidth">Step width.</param>
    /// <param name="length">Length.</param>
    /// <param name="hitInfo">Hit info.</param>
    /// <param name="calculateHitFace">hitFace will only get set if this is true.</param>
    public static bool TerrainRaycast(Ray ray, float stepWidth, float length, out CubicRaycastHitInfo hitInfo, bool calculateHitFace)
    {
        Vector3 startPoint = ray.origin;
        Vector3 direction  = ray.direction;

        return(TerrainRaycast(startPoint, direction, stepWidth, length, out hitInfo, calculateHitFace));
    }
Example #3
0
    /// <summary>
    /// Terrain raycast overloaded function.
    /// </summary>
    /// <returns><c>true</c>, if raycast hit a block, <c>false</c> otherwise.</returns>
    /// <param name="ray">Ray.</param>
    /// <param name="stepWidth">Step width.</param>
    /// <param name="length">Length.</param>
    /// <param name="hitInfo">Hit info.</param>
    /// <param name="calculateHitFace">hitFace will only get set if this is true.</param>
    public static bool TerrainRaycast(Ray ray, float stepWidth, float length, out CubicRaycastHitInfo hitInfo, bool calculateHitFace)
    {
        Vector3 startPoint = ray.origin;
        Vector3 direction = ray.direction;

        return TerrainRaycast (startPoint, direction, stepWidth, length, out hitInfo, calculateHitFace);
    }
Example #4
0
    public void Update()
    {
        // Right mouse button.
        if (Input.GetMouseButtonDown(1))
        {
            // The unity physics way

            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo   = new RaycastHit();
                Ray        cameraRay = this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 50, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                    {
                        return;
                    }

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent <CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            // Delete the clicked block
                            Vector3 block = chunk.GetBlockPosition(hitInfo, -0.5f);

                            chunk.chunkData.SetVoxel((int)block.x, (int)block.y, (int)block.z, -1);
                        }
                    }
                }
            }
            else
            {
                // Cubic World Physics way
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastUnprecise(this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    // Debug.Log ("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);
                    // Hit block
                    CubicTerrain.GetInstance().SetBlock((int)hitInfo.blockHit.x, (int)hitInfo.blockHit.y, (int)hitInfo.blockHit.z, -1);
                }
            }
        }
    }
Example #5
0
    public void Update()
    {
        // Right mouse button.
        if (Input.GetMouseButtonDown(1))
        {
            // The unity physics way

            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo = new RaycastHit();
                Ray cameraRay = this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 50, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                        return;

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent<CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            // Delete the clicked block
                            Vector3 block = chunk.GetBlockPosition(hitInfo, -0.5f);

                            chunk.chunkData.SetVoxel((int)block.x, (int) block.y, (int) block.z, -1);
                        }
                    }
                }
            }
            else
            {
                // Cubic World Physics way
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastUnprecise(this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    // Debug.Log ("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);
                    // Hit block
                    CubicTerrain.GetInstance().SetBlock((int)hitInfo.blockHit.x, (int)hitInfo.blockHit.y, (int)hitInfo.blockHit.z, -1);
                }
            }
        }
    }
Example #6
0
    public void Update()
    {
        bool firstPoint = Input.GetKeyDown (KeyCode.P);
        bool lastPoint = Input.GetKeyDown (KeyCode.L);
        bool definePoint = firstPoint || lastPoint;

        if (this.path != null)
        {
            if (this.path.isReady)
            {
                Debug.Log ("Path found in " + path.runtime + " milliseconds!");
                foreach (Vector3 blockPos in this.path.pathData)
                {
                    CubicTerrain.GetInstance().SetBlock((int)blockPos.x, (int)blockPos.y-1, (int)blockPos.z, -1);
                }
                this.path = null;
            }
            else if (!this.path.foundPath)
            {
                Debug.Log ("Path not found :-( after search for " + path.runtime + " milliseconds!");
            }
        }

        // Right mouse button.
        if (definePoint)
        {
            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo = new RaycastHit();
                Ray cameraRay = this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 5, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                        return;

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent<CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            BlockHitInfo blockHitInfo = chunk.GetBlockHitInfo(hitInfo);
                            int x = (int)blockHitInfo.hitBlock.x;
                            int y = (int)blockHitInfo.hitBlock.y;
                            int z = (int)blockHitInfo.hitBlock.z;

                            // Which face was hit? calculate target position for the new block
                            switch (blockHitInfo.hitFace)
                            {
                            case BlockFace.LEFT:
                                x-=1;
                                break;
                            case BlockFace.RIGHT:
                                x+=1;
                                break;
                            case BlockFace.TOP:
                                y+=1;
                                break;
                            case BlockFace.BOTTOM:
                                y-=1;
                                break;
                            case BlockFace.FRONT:
                                z+=1;
                                break;
                            case BlockFace.BACK:
                                z-=1;
                                break;
                            }

                            Vector3 chunkPos = chunk.chunkPosition;

                            // Get chunk we want to place the block on
                            if (x < 0)
                            {
                                chunkPos.x-= 1;
                                x=chunk.master.chunkWidth-1;
                            }
                            if (x >= chunk.master.chunkWidth)
                            {
                                chunkPos.x+= 1;
                                x=0;
                            }
                            if (z < 0)
                            {
                                chunkPos.z-= 1;
                                z=chunk.master.chunkDepth-1;
                            }
                            if (z >= chunk.master.chunkDepth)
                            {
                                chunkPos.z+= 1;
                                z=0;
                            }

                            // Finally place the object
                            GameObject chunkObject = chunk.master.GetChunkObject((int) chunkPos.x, (int)chunkPos.y, (int) chunkPos.z);
                            chunk = chunkObject.GetComponent<CubicTerrainChunk>();

                            // Get absolute position
                            Vector3 absoluteVoxelspace = chunk.GetAbsolutePosition(new Vector3(x,y,z));

                            Debug.Log ("Point: " + absoluteVoxelspace);
                            if (firstPoint)
                                startPoint = absoluteVoxelspace;
                            else if (lastPoint)
                                goalPoint = absoluteVoxelspace;
                        }
                    }
                }
            }
            else
            {
                // Cubic World Physics way
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastUnprecise(this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    // Debug.Log ("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);
                    // Hit block
                    Vector3 topBlock = hitInfo.blockHit + Vector3.up;
                    Debug.Log ("Top Block: " + topBlock);
                    if (firstPoint)
                        startPoint = topBlock;
                    else if (lastPoint)
                        goalPoint = topBlock;
                }
            }
        }

        if (startPoint != Vector3.zero && goalPoint != Vector3.zero)
        {
            Debug.Log ("Starting A* path finding. Distance: " + Vector3.Distance(startPoint, goalPoint));

            // Start pathfinding
            CubicPathfinding pathfinder = CubicPathfinding.GetInstance();
            this.path = pathfinder.GetPath(startPoint, goalPoint, true);

            startPoint = Vector3.zero;
            goalPoint = Vector3.zero;
        }
    }
Example #7
0
    /// <summary>
    /// Performs a raycast with the current terrain data.
    /// Raycasts are performed very simple, this function will move along your ray by adding direction*stepWidth every step.
    /// In every step it will check if it hit a block and if true it will stop and return the data.
    ///
    /// TODO: Implement a better way (more precise!) for raycasting
    /// </summary>
    /// <returns><c>true</c>, if the raycast hit a block, <c>false</c> otherwise.</returns>
    /// <param name="worldspaceStartpoint">Worldspace startpoint.</param>
    /// <param name="direction">Direction.</param>
    /// <param name="stepWidth">The step width you want to use for raycasting. the lower this is the more precise the result and slower the calculation will be.</param>
    /// <param name="length">The length of the ray.</param>
    /// <param name="hitInfo">The raycast hit info.</param>
    /// <param name="calculateHitFace">hitFace will only get set if this is true.</param>
    public static bool TerrainRaycast(Vector3 worldspaceStartpoint, Vector3 direction, float stepWidth, float length, out CubicRaycastHitInfo hitInfo, bool calculateHitFace)
    {
        // Initialize
        bool    blockHit         = false;
        float   distanceTraveled = 0;
        Vector3 currentPos       = worldspaceStartpoint;

        hitInfo = new CubicRaycastHitInfo();
        Vector3 blockPos = Vector3.zero;

        CubicTerrain terrain = CubicTerrain.GetInstance();

        // Search for blocks on the ray
        while (!blockHit && distanceTraveled < length)
        {
            // Calculate current step data
            currentPos       += direction * stepWidth;
            distanceTraveled += stepWidth;
            blockPos          = terrain.GetBlockPosition(currentPos);

            // Check if there is a block at this position
            if (terrain.HasBlock(blockPos))
            {
                blockHit         = true;
                hitInfo.blockHit = blockPos;
                hitInfo.hitPoint = currentPos;

                if (calculateHitFace)
                {
                    // Get hit face

                    /*LEFT = 0,
                     * RIGHT = 1,
                     * TOP = 2,
                     * BOTTOM = 3,
                     * FRONT = 4,
                     * BACK = 5*/

                    // Back and forward flipped
                    Vector3[] faceNormals = new Vector3[]
                    {
                        Vector3.left,
                        Vector3.right,
                        Vector3.up,
                        Vector3.down,
                        Vector3.forward,
                        Vector3.back
                    };

                    // Get block center position
                    Vector3 blockCenterPosition = blockPos + new Vector3(0.5f, 0.5f, 0.5f);

                    // Get shortest distance face.
                    float shortestDistance = stepWidth + 10;
                    int   shortestFace     = -1;

                    for (int i = 0; i < faceNormals.Length; i++)
                    {
                        // Get distance from hit point to the current normal + blockcenter
                        Vector3 blockNormalPosition = blockCenterPosition + faceNormals[i];
                        float   distance            = Vector3.Distance(currentPos, blockNormalPosition);

                        if (shortestDistance > distance)
                        {
                            shortestDistance = distance;
                            shortestFace     = i;
                        }
                    }

                    // Get face
                    hitInfo.faceHit = (BlockFace)shortestFace;
                }
            }
        }

        return(blockHit);
    }
Example #8
0
    public void Update()
    {
        // Right mouse button.
        if (Input.GetMouseButtonDown(0))
        {
            // Unity physics
            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo   = new RaycastHit();
                Ray        cameraRay = this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 5, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                    {
                        return;
                    }

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent <CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            BlockHitInfo blockHitInfo = chunk.GetBlockHitInfo(hitInfo);
                            int          x            = (int)blockHitInfo.hitBlock.x;
                            int          y            = (int)blockHitInfo.hitBlock.y;
                            int          z            = (int)blockHitInfo.hitBlock.z;

                            // Which face was hit? calculate target position for the new block
                            switch (blockHitInfo.hitFace)
                            {
                            case BlockFace.LEFT:
                                x -= 1;
                                break;

                            case BlockFace.RIGHT:
                                x += 1;
                                break;

                            case BlockFace.TOP:
                                y += 1;
                                break;

                            case BlockFace.BOTTOM:
                                y -= 1;
                                break;

                            case BlockFace.FRONT:
                                z += 1;
                                break;

                            case BlockFace.BACK:
                                z -= 1;
                                break;
                            }

                            Vector3 chunkPos = chunk.chunkPosition;

                            // Get chunk we want to place the block on
                            if (x < 0)
                            {
                                chunkPos.x -= 1;
                                x           = chunk.master.chunkWidth - 1;
                            }
                            if (x >= chunk.master.chunkWidth)
                            {
                                chunkPos.x += 1;
                                x           = 0;
                            }
                            if (y < 0)
                            {
                                chunkPos.y -= 1;
                                y           = chunk.master.chunkDepth - 1;
                            }
                            if (z >= chunk.master.chunkHeight)
                            {
                                chunkPos.y += 1;
                                y           = 0;
                            }
                            if (z < 0)
                            {
                                chunkPos.z -= 1;
                                z           = chunk.master.chunkDepth - 1;
                            }
                            if (z >= chunk.master.chunkDepth)
                            {
                                chunkPos.z += 1;
                                z           = 0;
                            }

                            // Finally place the object
                            GameObject chunkObject = chunk.master.GetChunkObject((int)chunkPos.x, (int)chunkPos.y, (int)chunkPos.z);
                            chunkObject.GetComponent <CubicTerrainChunk>().chunkData.SetVoxel(x, y, z, (short)this.blockId);
                        }
                    }
                }
            }
            else
            {
                // Cubic physics
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastPrecise(this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    Debug.Log("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);

                    // Get block to place position
                    int x = (int)hitInfo.blockHit.x;
                    int y = (int)hitInfo.blockHit.y;
                    int z = (int)hitInfo.blockHit.z;

                    // Which face was hit? calculate target position for the new block
                    switch (hitInfo.faceHit)
                    {
                    case BlockFace.LEFT:
                        x -= 1;
                        break;

                    case BlockFace.RIGHT:
                        x += 1;
                        break;

                    case BlockFace.TOP:
                        y += 1;
                        break;

                    case BlockFace.BOTTOM:
                        y -= 1;
                        break;

                    case BlockFace.FRONT:
                        z += 1;
                        break;

                    case BlockFace.BACK:
                        z -= 1;
                        break;
                    }

                    CubicTerrain.GetInstance().SetBlock(x, y, z, (short)this.blockId);
                }
            }
        }
    }
Example #9
0
    public void Update()
    {
        bool firstPoint  = Input.GetKeyDown(KeyCode.P);
        bool lastPoint   = Input.GetKeyDown(KeyCode.L);
        bool definePoint = firstPoint || lastPoint;

        if (this.path != null)
        {
            if (this.path.isReady)
            {
                Debug.Log("Path found in " + path.runtime + " milliseconds!");
                foreach (Vector3 blockPos in this.path.pathData)
                {
                    CubicTerrain.GetInstance().SetBlock((int)blockPos.x, (int)blockPos.y - 1, (int)blockPos.z, -1);
                }
                this.path = null;
            }
            else if (!this.path.foundPath)
            {
                Debug.Log("Path not found :-( after search for " + path.runtime + " milliseconds!");
            }
        }

        // Right mouse button.
        if (definePoint)
        {
            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo   = new RaycastHit();
                Ray        cameraRay = this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 5, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                    {
                        return;
                    }

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent <CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            BlockHitInfo blockHitInfo = chunk.GetBlockHitInfo(hitInfo);
                            int          x            = (int)blockHitInfo.hitBlock.x;
                            int          y            = (int)blockHitInfo.hitBlock.y;
                            int          z            = (int)blockHitInfo.hitBlock.z;

                            // Which face was hit? calculate target position for the new block
                            switch (blockHitInfo.hitFace)
                            {
                            case BlockFace.LEFT:
                                x -= 1;
                                break;

                            case BlockFace.RIGHT:
                                x += 1;
                                break;

                            case BlockFace.TOP:
                                y += 1;
                                break;

                            case BlockFace.BOTTOM:
                                y -= 1;
                                break;

                            case BlockFace.FRONT:
                                z += 1;
                                break;

                            case BlockFace.BACK:
                                z -= 1;
                                break;
                            }

                            Vector3 chunkPos = chunk.chunkPosition;

                            // Get chunk we want to place the block on
                            if (x < 0)
                            {
                                chunkPos.x -= 1;
                                x           = chunk.master.chunkWidth - 1;
                            }
                            if (x >= chunk.master.chunkWidth)
                            {
                                chunkPos.x += 1;
                                x           = 0;
                            }
                            if (z < 0)
                            {
                                chunkPos.z -= 1;
                                z           = chunk.master.chunkDepth - 1;
                            }
                            if (z >= chunk.master.chunkDepth)
                            {
                                chunkPos.z += 1;
                                z           = 0;
                            }

                            // Finally place the object
                            GameObject chunkObject = chunk.master.GetChunkObject((int)chunkPos.x, (int)chunkPos.y, (int)chunkPos.z);
                            chunk = chunkObject.GetComponent <CubicTerrainChunk>();

                            // Get absolute position
                            Vector3 absoluteVoxelspace = chunk.GetAbsolutePosition(new Vector3(x, y, z));

                            Debug.Log("Point: " + absoluteVoxelspace);
                            if (firstPoint)
                            {
                                startPoint = absoluteVoxelspace;
                            }
                            else if (lastPoint)
                            {
                                goalPoint = absoluteVoxelspace;
                            }
                        }
                    }
                }
            }
            else
            {
                // Cubic World Physics way
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastUnprecise(this.playerCamera.GetComponent <Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    // Debug.Log ("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);
                    // Hit block
                    Vector3 topBlock = hitInfo.blockHit + Vector3.up;
                    Debug.Log("Top Block: " + topBlock);
                    if (firstPoint)
                    {
                        startPoint = topBlock;
                    }
                    else if (lastPoint)
                    {
                        goalPoint = topBlock;
                    }
                }
            }
        }

        if (startPoint != Vector3.zero && goalPoint != Vector3.zero)
        {
            Debug.Log("Starting A* path finding. Distance: " + Vector3.Distance(startPoint, goalPoint));

            // Start pathfinding
            CubicPathfinding pathfinder = CubicPathfinding.GetInstance();
            this.path = pathfinder.GetPath(startPoint, goalPoint, true);

            startPoint = Vector3.zero;
            goalPoint  = Vector3.zero;
        }
    }
Example #10
0
    public void Update()
    {
        // Right mouse button.
        if (Input.GetMouseButtonDown(0))
        {
            // Unity physics
            if (CubicTerrain.GetInstance().useMeshColliders)
            {
                // Get ready to perform the raycast.
                RaycastHit hitInfo = new RaycastHit();
                Ray cameraRay = this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2));
                Debug.DrawRay(cameraRay.origin, cameraRay.direction, Color.red, 100.0f);

                // Perform the raycast
                if (Physics.Raycast(cameraRay, out hitInfo, 5, this.detectionMask.value))
                {
                    if (hitInfo.collider == null)
                        return;

                    // get collider parent
                    Transform chunkTransform = hitInfo.collider.transform.parent;

                    if (chunkTransform != null)
                    {
                        // Chunk hit?
                        CubicTerrainChunk chunk = chunkTransform.GetComponent<CubicTerrainChunk>();
                        if (chunk != null && !chunk.isDirty)
                        {
                            // Yes, chunk hit!
                            BlockHitInfo blockHitInfo = chunk.GetBlockHitInfo(hitInfo);
                            int x = (int)blockHitInfo.hitBlock.x;
                            int y = (int)blockHitInfo.hitBlock.y;
                            int z = (int)blockHitInfo.hitBlock.z;

                            // Which face was hit? calculate target position for the new block
                            switch (blockHitInfo.hitFace)
                            {
                                case BlockFace.LEFT:
                                    x-=1;
                                    break;
                                case BlockFace.RIGHT:
                                    x+=1;
                                    break;
                                case BlockFace.TOP:
                                    y+=1;
                                    break;
                                case BlockFace.BOTTOM:
                                    y-=1;
                                    break;
                                case BlockFace.FRONT:
                                    z+=1;
                                    break;
                                case BlockFace.BACK:
                                    z-=1;
                                    break;
                            }

                            Vector3 chunkPos = chunk.chunkPosition;

                            // Get chunk we want to place the block on
                            if (x < 0)
                            {
                                chunkPos.x-= 1;
                                x=chunk.master.chunkWidth-1;
                            }
                            if (x >= chunk.master.chunkWidth)
                            {
                                chunkPos.x+= 1;
                                x=0;
                            }
                            if (y < 0)
                            {
                                chunkPos.y-= 1;
                                y=chunk.master.chunkDepth-1;
                            }
                            if (z >= chunk.master.chunkHeight)
                            {
                                chunkPos.y+=1;
                                y=0;
                            }
                            if (z < 0)
                            {
                                chunkPos.z-= 1;
                                z=chunk.master.chunkDepth-1;
                            }
                            if (z >= chunk.master.chunkDepth)
                            {
                                chunkPos.z+= 1;
                                z=0;
                            }

                            // Finally place the object
                            GameObject chunkObject = chunk.master.GetChunkObject((int) chunkPos.x, (int)chunkPos.y, (int) chunkPos.z);
                            chunkObject.GetComponent<CubicTerrainChunk>().chunkData.SetVoxel(x,y,z,(short)this.blockId);
                        }
                    }
                }
            }
            else
            {
                // Cubic physics
                CubicRaycastHitInfo hitInfo = new CubicRaycastHitInfo();
                if (CubicPhysics.TerrainRaycastPrecise(this.playerCamera.GetComponent<Camera>().ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2)), 5.0f, out hitInfo))
                {
                    Debug.Log ("Hit: " + hitInfo.hitPoint + ", Block: " + hitInfo.blockHit + ", Face: " + hitInfo.faceHit);

                    // Get block to place position
                    int x = (int)hitInfo.blockHit.x;
                    int y = (int)hitInfo.blockHit.y;
                    int z = (int)hitInfo.blockHit.z;

                    // Which face was hit? calculate target position for the new block
                    switch (hitInfo.faceHit)
                    {
                        case BlockFace.LEFT:
                            x-=1;
                            break;
                        case BlockFace.RIGHT:
                            x+=1;
                            break;
                        case BlockFace.TOP:
                            y+=1;
                            break;
                        case BlockFace.BOTTOM:
                            y-=1;
                            break;
                        case BlockFace.FRONT:
                            z+=1;
                            break;
                        case BlockFace.BACK:
                            z-=1;
                            break;
                    }

                    CubicTerrain.GetInstance().SetBlock(x,y,z,(short)this.blockId);
                }

            }
        }
    }
Example #11
0
    /// <summary>
    /// Performs a raycast with the current terrain data.
    /// Raycasts are performed very simple, this function will move along your ray by adding direction*stepWidth every step.
    /// In every step it will check if it hit a block and if true it will stop and return the data.
    /// 
    /// TODO: Implement a better way (more precise!) for raycasting
    /// </summary>
    /// <returns><c>true</c>, if the raycast hit a block, <c>false</c> otherwise.</returns>
    /// <param name="worldspaceStartpoint">Worldspace startpoint.</param>
    /// <param name="direction">Direction.</param>
    /// <param name="stepWidth">The step width you want to use for raycasting. the lower this is the more precise the result and slower the calculation will be.</param>
    /// <param name="length">The length of the ray.</param>
    /// <param name="hitInfo">The raycast hit info.</param>
    /// <param name="calculateHitFace">hitFace will only get set if this is true.</param>
    public static bool TerrainRaycast(Vector3 worldspaceStartpoint, Vector3 direction, float stepWidth, float length, out CubicRaycastHitInfo hitInfo, bool calculateHitFace)
    {
        // Initialize
        bool blockHit = false;
        float distanceTraveled = 0;
        Vector3 currentPos = worldspaceStartpoint;
        hitInfo = new CubicRaycastHitInfo ();
        Vector3 blockPos = Vector3.zero;

        CubicTerrain terrain = CubicTerrain.GetInstance ();

        // Search for blocks on the ray
        while (!blockHit && distanceTraveled < length)
        {
            // Calculate current step data
            currentPos += direction * stepWidth;
            distanceTraveled+=stepWidth;
            blockPos = terrain.GetBlockPosition(currentPos);

            // Check if there is a block at this position
            if (terrain.HasBlock(blockPos))
            {
                blockHit = true;
                hitInfo.blockHit = blockPos;
                hitInfo.hitPoint = currentPos;

                if (calculateHitFace)
                {
                    // Get hit face

                    /*LEFT = 0,
                    RIGHT = 1,
                    TOP = 2,
                    BOTTOM = 3,
                    FRONT = 4,
                    BACK = 5*/

                    // Back and forward flipped
                    Vector3[] faceNormals = new Vector3[]
                    {
                        Vector3.left,
                        Vector3.right,
                        Vector3.up,
                        Vector3.down,
                        Vector3.forward,
                        Vector3.back
                    };

                    // Get block center position
                    Vector3 blockCenterPosition = blockPos + new Vector3(0.5f, 0.5f, 0.5f);

                    // Get shortest distance face.
                    float shortestDistance = stepWidth+10;
                    int shortestFace = -1;

                    for (int i = 0; i < faceNormals.Length; i++)
                    {
                        // Get distance from hit point to the current normal + blockcenter
                        Vector3 blockNormalPosition = blockCenterPosition + faceNormals[i];
                        float distance = Vector3.Distance(currentPos, blockNormalPosition);

                        if (shortestDistance > distance)
                        {
                            shortestDistance = distance;
                            shortestFace = i;
                        }
                    }

                    // Get face
                    hitInfo.faceHit = (BlockFace)shortestFace;
                }
            }
        }

        return blockHit;
    }
Example #12
0
    /// <summary>
    /// Executes an unprecise raycast.
    /// Only use this for getting the block position. if you need the face you should use the TerrainRaycastPrecise() function.
    /// </summary>
    /// <returns><c>true</c>, if raycast unprecise was terrained, <c>false</c> otherwise.</returns>
    /// <param name="ray">Ray.</param>
    /// <param name="length">Length.</param>
    /// <param name="hitInfo">Hit info.</param>
    public static bool TerrainRaycastUnprecise(Ray ray, float length, out CubicRaycastHitInfo hitInfo)
    {
        Vector3 startPoint = ray.origin;
        Vector3 direction = ray.direction;

        return TerrainRaycast (startPoint, direction, 0.49f, length, out hitInfo, false);
    }