예제 #1
0
    void Update()
    {
        toolScale += Input.mouseScrollDelta.y;
        toolScale  = Mathf.Clamp(toolScale, 0f, 50f);

        toolPrefabInstance.transform.localScale = Vector3.one * toolScale;

        Ray ray = cam.ScreenPointToRay(Input.mousePosition);

        Vector3 toolPos = Physics.Raycast(ray, out RaycastHit hitInfo)
            ? hitInfo.point
            : ray.direction * maxDistance + ray.origin;

        bool isNear = Vector3.Distance(toolPos, ray.origin) - toolScale / 2 < minDistance;

        toolPrefabInstance.SetActive(!isNear);
        toolPrefabInstance.transform.position = toolPos;

        if (Input.GetMouseButton(0))
        {
            if (Time.time > nextTick)
            {
                nextTick = Time.time + toolTick;

                var terraformMode = Input.GetKey(KeyCode.LeftShift)
                    ? TerraformMode.Add
                    : TerraformMode.Subtract;

                Voxel.Grid grid = gridGenerator.GetGridFromWorldPosition(toolPos);

                if (!ReferenceEquals(grid, null))
                {
                    Terraform(grid, toolPos, toolScale / 2, toolStrength, terraformMode, toolSmooth);
                }

                ignoreGrids.Clear();
            }
        }
    }
예제 #2
0
    public void Terraform(Voxel.Grid grid, Vector3 pos, float radius, float strength, TerraformMode mode, bool smooth = true)
    {
        ISet <Vector3Int> toRefresh = new HashSet <Vector3Int>();

        grid.ForeachCoordinate(cellPos =>
        {
            GridCell cell = grid.GetCell(cellPos);

            for (int i = 0; i < 8; i++)
            {
                Vector3 valuePos   = (Vector3)grid.GridPosition * grid.GridScale + cell.GetValuePos(i);
                float distanceSqrt = (pos - valuePos).sqrMagnitude;

                if (distanceSqrt < radius * radius)
                {
                    float value = 0.0f;
                    value      += strength;

                    if (smooth)
                    {
                        value *= 1 - distanceSqrt / (radius * radius);
                    }

                    switch (mode)
                    {
                    case TerraformMode.Add:
                        cell.Values[i] -= value;
                        break;

                    case TerraformMode.Subtract:
                        cell.Values[i] += value;
                        break;
                    }

                    cell.Values[i] = Mathf.Clamp(cell.Values[i], -1.5f, 1.5f);

                    if (cellPos.x == 0)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(-1, 0, 0));
                    }
                    else if (cellPos.x == grid.Data.CellCount - 1)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(1, 0, 0));
                    }

                    if (cellPos.y == 0)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(0, -1, 0));
                    }
                    else if (cellPos.y == grid.Data.CellCount - 1)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(0, 1, 0));
                    }

                    if (cellPos.z == 0)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(0, 0, -1));
                    }
                    else if (cellPos.z == grid.Data.CellCount - 1)
                    {
                        toRefresh.Add(grid.GridPosition + new Vector3Int(0, 0, 1));
                    }
                }
            }
        });

        ignoreGrids.Add(grid.GridPosition);

        foreach (Vector3Int gridPos in toRefresh)
        {
            if (ignoreGrids.Contains(gridPos))
            {
                continue;
            }

            if (gridGenerator.Grids.TryGetValue(gridPos, out Voxel.Grid refreshGrid))
            {
                Terraform(refreshGrid, pos, radius, strength, mode, smooth);
            }
        }

        gridGenerator.RefreshGrid(grid.GridPosition);
    }