コード例 #1
0
    void InitTileEntity()
    {
        if (hasInitTileEntity)
        {
            return;
        }

        foreach (Vector3Int pos in tileEntityList)
        {
            if (!tileEntityObjs.ContainsKey(pos))
            {
                int              sectionIndex = pos.y / 16;
                TagNodeCompound  Section      = Sections[sectionIndex] as TagNodeCompound;
                TagNodeByteArray Blocks       = Section["Blocks"] as TagNodeByteArray;
                TagNodeByteArray Data         = Section["Data"] as TagNodeByteArray;

                int        yInSection = pos.y % 16;
                int        blockPos   = yInSection * 16 * 16 + pos.z * 16 + pos.x;
                byte       rawType    = Blocks.Data[blockPos];
                NBTBlock   generator  = NBTGeneratorManager.GetMeshGenerator(rawType);
                byte       blockData  = NBTHelper.GetNibble(Data.Data, blockPos);
                GameObject obj        = generator.GetTileEntityGameObject(this, blockData, pos);

                tileEntityObjs[pos] = obj;
            }
        }

        hasInitTileEntity = true;
    }
コード例 #2
0
ファイル: SoundManager.cs プロジェクト: wetstreet/Theircraft
    public static void PlayBreakSound(byte type, GameObject gameObject)
    {
        string material = NBTGeneratorManager.GetMeshGenerator(type).soundMaterial.ToString();

        AkSoundEngine.SetSwitch("Materials", material, gameObject);
        AkSoundEngine.PostEvent("Player_Break", gameObject);
    }
コード例 #3
0
    bool CanAddBlock(Vector3Int pos)
    {
        NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(InventorySystem.items[ItemSelectPanel.curIndex].id);

        // 手上的
        if (generator == null)
        {
            return(false);
        }

        byte     type            = NBTHelper.GetBlockByte(pos);
        NBTBlock targetGenerator = NBTGeneratorManager.GetMeshGenerator(type);

        if (generator is NBTPlant)
        {
            if (generator == targetGenerator)
            {
                return(false);
            }

            byte belowType = NBTHelper.GetBlockByte(pos + Vector3Int.down);

            //如果手上拿的是植物,则判断下方是否是否是实体
            NBTBlock targetBelowGenerator = NBTGeneratorManager.GetMeshGenerator(belowType);
            return(targetBelowGenerator != null && !(targetBelowGenerator is NBTPlant));
        }
        else
        {
            //如果手上拿的不是植物,则判断碰撞盒是否与玩家相交
            return(!cc.bounds.Intersects(new Bounds(pos, Vector3.one)));
        }
    }
コード例 #4
0
    void DrawWireFrame()
    {
        WireFrameHelper.render = false;
        int cubeLayerIndex        = LayerMask.NameToLayer("Chunk");
        int otherPlayerLayerIndex = LayerMask.NameToLayer("OtherPlayer");
        int plantLayerIndex       = LayerMask.NameToLayer("Plant");

        if (cubeLayerIndex != -1 && otherPlayerLayerIndex != -1 && plantLayerIndex != -1)
        {
            int layerMask = 1 << cubeLayerIndex | 1 << otherPlayerLayerIndex | 1 << plantLayerIndex;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(center), out hit, 5f, layerMask))
            {
                if (hit.transform.gameObject.layer == cubeLayerIndex || hit.transform.gameObject.layer == plantLayerIndex)
                {
                    Vector3Int pos = Vector3Int.RoundToInt(hit.point - hit.normal / 100);
                    NBTHelper.GetBlockData(pos.x, pos.y, pos.z, out byte type, out byte data);
                    if (type != 0)
                    {
                        if (pos != WireFrameHelper.pos)
                        {
                            breakingTime = 0;
                        }

                        WireFrameHelper.render    = true;
                        WireFrameHelper.pos       = pos;
                        WireFrameHelper.hitPos    = hit.point;
                        WireFrameHelper.type      = type;
                        WireFrameHelper.data      = data;
                        WireFrameHelper.generator = NBTGeneratorManager.GetMeshGenerator(type);
                    }
                }
            }
        }
    }
コード例 #5
0
ファイル: NBTHelper.cs プロジェクト: wetstreet/Theircraft
    public static void SetBlockByte(int x, int y, int z, byte type)
    {
        int chunkX = Mathf.FloorToInt(x / 16f);
        int chunkZ = Mathf.FloorToInt(z / 16f);

        int xInChunk = x - chunkX * 16;
        int zInChunk = z - chunkZ * 16;

        NBTChunk    chunk        = GetChunk(chunkX, chunkZ);
        NBTBlock    oldGenerator = NBTGeneratorManager.GetMeshGenerator(chunk.GetBlockByte(xInChunk, y, zInChunk));
        UpdateFlags updateFlag   = GetUpdateFlags(oldGenerator);

        if (type == 0)
        {
            chunk.GetBlockData(xInChunk, y + 1, zInChunk, out byte topType, out byte topData);
            NBTBlock topGenerator = NBTGeneratorManager.GetMeshGenerator(topType);
            if (topGenerator != null && topGenerator is NBTPlant)
            {
                BreakBlockEffect.Create(topType, topData, new Vector3(x, y + 1, z));
                chunk.SetBlockByte(xInChunk, y + 1, zInChunk, 0);
                updateFlag |= UpdateFlags.NotCollidable;
            }
        }

        chunk.SetBlockByte(xInChunk, y, zInChunk, type);
        if (updateFlag.HasFlag(UpdateFlags.Lighting))
        {
            UpdateLighting(x, y, z);
        }
        chunk.RebuildMesh(updateFlag);

        NBTChunk leftChunk = GetChunk(chunkX - 1, chunkZ);

        if (xInChunk == 0)
        {
            leftChunk.RebuildMesh();
        }

        NBTChunk rightChunk = GetChunk(chunkX + 1, chunkZ);

        if (xInChunk == 15)
        {
            rightChunk.RebuildMesh();
        }

        NBTChunk backChunk = GetChunk(chunkX, chunkZ - 1);

        if (zInChunk == 0)
        {
            backChunk.RebuildMesh();
        }

        NBTChunk frontChunk = GetChunk(chunkX, chunkZ + 1);

        if (zInChunk == 15)
        {
            frontChunk.RebuildMesh();
        }
    }
コード例 #6
0
    static void AddCube(Vector3Int pos, byte type)
    {
        MeshGenerator.pos = pos;
        generator         = NBTGeneratorManager.GetMeshGenerator(type);

        AddFrontFace();
        AddRightFace();
        AddLeftFace();
        AddBackFace();
        AddTopFace();
        AddBottomFace();
    }
コード例 #7
0
ファイル: SoundManager.cs プロジェクト: wetstreet/Theircraft
    public static void PlayFootstepSound(byte type, GameObject gameObject)
    {
        NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(type);

        if (generator == null)
        {
            return;
        }
        string material = generator.soundMaterial.ToString();

        AkSoundEngine.SetSwitch("Materials", material, gameObject);
        AkSoundEngine.PostEvent("Player_Footstep", gameObject);
    }
コード例 #8
0
    public static void Create(byte type, byte data, Vector3 pos)
    {
        GameObject prefab = Resources.Load("Prefabs/BreakBlockEffect") as GameObject;
        GameObject go     = Instantiate(prefab);

        go.transform.localPosition = pos;
        Destroy(go, 1);

        int      chunkX = Mathf.FloorToInt(pos.x / 16f);
        int      chunkZ = Mathf.FloorToInt(pos.z / 16f);
        NBTChunk chunk  = NBTHelper.GetChunk(chunkX, chunkZ);

        BreakBlockEffect effect = go.AddComponent <BreakBlockEffect>();
        NBTBlock         block  = NBTGeneratorManager.GetMeshGenerator(type);

        effect.texturePath = block.GetBreakEffectTexture(chunk, data);
        effect.tintColor   = block.GetFrontTintColorByData(chunk, data);
    }
コード例 #9
0
    void BreakBlock(Vector3Int pos)
    {
        breakTime = 0;

        handAnimator.SetBool("isBreaking", false);

        HideBreakingEffect();
        //DeleteBlockReq(WireFrameHelper.pos);

        NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(WireFrameHelper.type);

        if (generator.hasDropItem)
        {
            Item.CreateBlockDropItem(generator.GetDropItemByData(WireFrameHelper.data), WireFrameHelper.data, pos);
        }

        NBTHelper.SetBlockByte(WireFrameHelper.pos, 0);

        //Item.CreateBlockDropItem(type, WireFrameHelper.pos);
        BreakBlockEffect.Create(WireFrameHelper.type, WireFrameHelper.data, WireFrameHelper.pos);
        SoundManager.PlayBreakSound(WireFrameHelper.type, instance.gameObject);
    }
コード例 #10
0
 void OnRightClick()
 {
     if (WireFrameHelper.render)
     {
         if (WireFrameHelper.generator.canInteract)
         {
             WireFrameHelper.generator.OnRightClick();
         }
         else
         {
             string id = InventorySystem.items[ItemSelectPanel.curIndex].id;
             if (id != null)
             {
                 NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(id);
                 if (generator != null)
                 {
                     generator.OnAddBlock(hit);
                     SoundManager.SetSwitch(generator);
                     SoundManager.Play2DSound("Player_Place");
                 }
             }
         }
     }
 }
コード例 #11
0
ファイル: NBTBlock.cs プロジェクト: wetstreet/Theircraft
    protected bool CanAddBlock(Vector3Int pos)
    {
        byte     type            = NBTHelper.GetBlockByte(pos);
        NBTBlock targetGenerator = NBTGeneratorManager.GetMeshGenerator(type);

        if (this is NBTPlant)
        {
            if (this == targetGenerator)
            {
                return(false);
            }

            byte belowType = NBTHelper.GetBlockByte(pos + Vector3Int.down);

            //如果手上拿的是植物,则判断下方是否是否是实体
            NBTBlock targetBelowGenerator = NBTGeneratorManager.GetMeshGenerator(belowType);
            return(targetBelowGenerator != null && !(targetBelowGenerator is NBTPlant));
        }
        else
        {
            //如果手上拿的不是植物,则判断碰撞盒是否与玩家相交
            return(!PlayerController.instance.cc.bounds.Intersects(new Bounds(pos, Vector3.one)));
        }
    }
コード例 #12
0
    public void RefreshMeshData(UpdateFlags updateFlag = UpdateFlags.All)
    {
        //Debug.Log("RefreshMeshData,chunk=" + x + ",z=" + z);
        UnityEngine.Profiling.Profiler.BeginSample("RefreshMeshData");

        if (updateFlag.HasFlag(UpdateFlags.Collidable))
        {
            collidable.Clear();
        }
        if (updateFlag.HasFlag(UpdateFlags.NotCollidable))
        {
            notCollidable.Clear();
        }
        if (updateFlag.HasFlag(UpdateFlags.Water))
        {
            water.Clear();
        }

        for (int sectionIndex = 0; sectionIndex < Sections.Count; sectionIndex++)
        {
            TagNodeCompound  Section = Sections[sectionIndex] as TagNodeCompound;
            TagNodeByteArray Blocks  = Section["Blocks"] as TagNodeByteArray;
            TagNodeByteArray Data    = Section["Data"] as TagNodeByteArray;

            for (int yInSection = 0; yInSection < 16; yInSection++)
            {
                for (int zInSection = 0; zInSection < 16; zInSection++)
                {
                    for (int xInSection = 0; xInSection < 16; xInSection++)
                    {
                        int      blockPos  = yInSection * 16 * 16 + zInSection * 16 + xInSection;
                        byte     rawType   = Blocks.Data[blockPos];
                        NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(rawType);
                        int      worldY    = yInSection + sectionIndex * 16;

                        if (generator != null)
                        {
                            pos.Set(xInSection, worldY, zInSection);
                            byte blockData = NBTHelper.GetNibble(Data.Data, blockPos);

                            try
                            {
                                if (generator.isTileEntity)
                                {
                                    tileEntityList.Add(pos);
                                }
                                else
                                {
                                    AddCube(generator, blockData, updateFlag);
                                }
                            }
                            catch (System.Exception e)
                            {
                                int        worldX   = x * 16 + xInSection;
                                int        worldZ   = z * 16 + zInSection;
                                Vector3Int worldPos = new Vector3Int(worldX, worldY, worldZ);
                                Debug.LogError(generator.GetType() + ",pos=" + worldPos + "\n" + e.ToString());
                            }
                        }
                        else if (rawType != 0 && rawType != 11)
                        {
                            int        worldX   = x * 16 + xInSection;
                            int        worldZ   = z * 16 + zInSection;
                            Vector3Int worldPos = new Vector3Int(worldX, worldY, worldZ);
                            Debug.LogWarning("generator not exist" + ",pos=" + worldPos + ", type=" + rawType);
                        }
                    }
                }
            }
        }

        UnityEngine.Profiling.Profiler.EndSample();
    }
コード例 #13
0
    public void RefreshMeshData()
    {
        //Debug.Log("RefreshMeshData,chunk=" + x + ",z=" + z);
        collidable.Clear();
        notCollidable.Clear();
        water.Clear();

        Vector3Int pos = new Vector3Int();

        for (int sectionIndex = 0; sectionIndex < Sections.Count; sectionIndex++)
        {
            TagNodeCompound  Section  = Sections[sectionIndex] as TagNodeCompound;
            TagNodeByteArray Blocks   = Section["Blocks"] as TagNodeByteArray;
            TagNodeByteArray Data     = Section["Data"] as TagNodeByteArray;
            TagNodeByteArray SkyLight = Section["SkyLight"] as TagNodeByteArray;

            for (int yInSection = 0; yInSection < 16; yInSection++)
            {
                for (int zInSection = 0; zInSection < 16; zInSection++)
                {
                    for (int xInSection = 0; xInSection < 16; xInSection++)
                    {
                        int      blockPos  = yInSection * 16 * 16 + zInSection * 16 + xInSection;
                        byte     rawType   = Blocks.Data[blockPos];
                        NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(rawType);
                        if (generator != null)
                        {
                            int worldY = yInSection + sectionIndex * 16;
                            pos.Set(xInSection, worldY, zInSection);
                            byte blockData = NBTHelper.GetNibble(Data.Data, blockPos);
                            byte skyLight  = NBTHelper.GetNibble(SkyLight.Data, blockPos);
                            try
                            {
                                if (generator is NBTStationaryWater)
                                {
                                    //generator.GenerateMeshInChunk(this, blockData, pos, water);
                                }
                                else if (generator is NBTPlant)
                                {
                                    generator.AddCube(this, blockData, skyLight, pos, notCollidable);
                                }
                                else
                                {
                                    generator.AddCube(this, blockData, skyLight, pos, collidable);
                                }
                            }
                            catch (System.Exception e)
                            {
                                Debug.LogWarning(generator.GetType() + "\n" + e.ToString());
                            }
                        }
                        else if (rawType != 0 && rawType != 11)
                        {
                            Debug.LogWarning("generator not exist, type=" + rawType);
                        }
                    }
                }
            }
        }

        hasBuiltMesh = true;
        isDirty      = false;
    }
コード例 #14
0
ファイル: IconGenerator.cs プロジェクト: wetstreet/Theircraft
    private void Awake()
    {
        NBTGeneratorManager.Init();
        TextureArrayManager.Init();

        Texture2D day = Resources.Load <Texture2D>("GUI/Day");

        Shader.SetGlobalTexture("_DayLightTexture", day);
        Texture2D night = Resources.Load <Texture2D>("GUI/Night");

        Shader.SetGlobalTexture("_NightLightTexture", night);

        AddGridItem(NBTGeneratorManager.GetMeshGenerator(1), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(2), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(3), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(4), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 2);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 3);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 4);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(5), 5);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(7), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(12), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(13), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(14), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(15), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(16), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(17), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(17), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(17), 2);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(17), 3);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(18), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(18), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(18), 2);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(18), 3);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(20), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(21), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(24), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(26), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 2);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 3);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 4);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 5);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 6);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 7);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 8);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 9);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 10);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 11);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 12);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 13);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 14);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(35), 15);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(45), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(49), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(53), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(54), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(56), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(58), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(67), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(73), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(81), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(82), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(85), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(108), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(125), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 2);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 3);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 4);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(126), 5);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(129), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(134), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(135), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(136), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(161), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(161), 1);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(162), 0);
        AddGridItem(NBTGeneratorManager.GetMeshGenerator(162), 1);

        optionArray = optionList.ToArray();
    }
コード例 #15
0
ファイル: DebugUI.cs プロジェクト: takaaptech/Theircraft
    // Update is called once per frame
    void Update()
    {
        sb.Clear();
        sb.Append("Theircraft ");
        sb.Append(Application.version);
        sb.Append("\n");
        sb.Append(GetFPS());
        sb.Append(" fps");

        Vector3 pos = PlayerController.instance.transform.position;

        sb.Append("\nXYZ: ");
        sb.Append(pos.x);
        sb.Append(" / ");
        sb.Append(pos.y);
        sb.Append(" / ");
        sb.Append(pos.z);

        Vector3Int curBlock = PlayerController.GetCurrentBlock();

        sb.Append("\nBlock: ");
        sb.Append(curBlock.x);
        sb.Append(" ");
        sb.Append(curBlock.y);
        sb.Append(" ");
        sb.Append(curBlock.z);

        int chunkX   = Mathf.FloorToInt(curBlock.x / 16f);
        int chunkY   = Mathf.FloorToInt(curBlock.y / 16f);
        int chunkZ   = Mathf.FloorToInt(curBlock.z / 16f);
        int xInChunk = curBlock.x - chunkX * 16;
        int yInChunk = curBlock.y - chunkY * 16;
        int zInChunk = curBlock.z - chunkZ * 16;

        sb.Append("\nChunk: ");
        sb.Append(xInChunk);
        sb.Append(" ");
        sb.Append(yInChunk);
        sb.Append(" ");
        sb.Append(zInChunk);
        sb.Append(" in ");
        sb.Append(chunkX);
        sb.Append(" ");
        sb.Append(chunkY);
        sb.Append(" ");
        sb.Append(chunkZ);

        if (WireFrameHelper.render)
        {
            sb.Append("\nLooking at: ");
            sb.Append(WireFrameHelper.pos.x);
            sb.Append(" ");
            sb.Append(WireFrameHelper.pos.y);
            sb.Append(" ");
            sb.Append(WireFrameHelper.pos.z);

            sb.Append("\nType: ");
            NBTBlock generator = NBTGeneratorManager.GetMeshGenerator(WireFrameHelper.type);
            sb.Append(generator.name);

            sb.Append("\nData: ");
            sb.Append(WireFrameHelper.data);
        }

        label.text = sb.ToString();
    }
コード例 #16
0
    void DrawWireFrame()
    {
        WireFrameHelper.render = false;

        Vector3 center                = new Vector3(Screen.width / 2, Screen.height / 2, 0);
        int     cubeLayerIndex        = LayerMask.NameToLayer("Chunk");
        int     otherPlayerLayerIndex = LayerMask.NameToLayer("OtherPlayer");
        int     plantLayerIndex       = LayerMask.NameToLayer("Plant");

        if (cubeLayerIndex != -1 && otherPlayerLayerIndex != -1 && plantLayerIndex != -1)
        {
            int layerMask = 1 << cubeLayerIndex | 1 << otherPlayerLayerIndex | 1 << plantLayerIndex;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(center), out hit, 5f, layerMask))
            {
                if (hit.transform.gameObject.layer == cubeLayerIndex || hit.transform.gameObject.layer == plantLayerIndex)
                {
                    Vector3Int pos  = Vector3Int.RoundToInt(hit.point - hit.normal / 10);
                    byte       type = 0;
                    byte       data = 0;
                    NBTHelper.GetBlockData(pos.x, pos.y, pos.z, ref type, ref data);
                    if (type != 0)
                    {
                        if (pos != WireFrameHelper.pos)
                        {
                            breakTime = 0;
                        }

                        WireFrameHelper.render = true;
                        WireFrameHelper.pos    = pos;
                        WireFrameHelper.hitPos = hit.point;
                        WireFrameHelper.type   = type;
                        WireFrameHelper.data   = data;

                        if (leftMouseDown)
                        {
                            handAnimator.SetBool("isBreaking", true);

                            breakTime += Time.deltaTime;

                            NBTBlock generator     = NBTGeneratorManager.GetMeshGenerator(type);
                            float    breakNeedTime = generator.breakNeedTime;
                            if (breakNeedTime == 0)
                            {
                                BreakBlock(pos);
                            }
                            else
                            {
                                int curStage = Mathf.FloorToInt(breakTime / (breakNeedTime / 12));
                                if (stage != curStage)
                                {
                                    stage = curStage;
                                    UpdateBreakingEffect(generator, pos, stage);
                                }
                                if (stage >= 10)
                                {
                                    BreakBlock(pos);
                                }
                            }

                            return;
                        }
                    }
                }
            }
        }

        handAnimator.SetBool("isBreaking", false);
    }