public void ShowAttackArrow()
    {
        FreeArrow();

        DataMission dataMission = _dataCampaign.missions [_selectTileIndex];

        for (int i = 0; i < DataMission.ARROW_COUNT_MAX; ++i)
        {
            DataConfig.CAMPAIGN_ARROW arrow = dataMission.arrows[i];
            float arrowRotation             = dataMission.arrowsRotation[i];
//			arrowRotation = 180;

            if (arrow != DataConfig.CAMPAIGN_ARROW.UNKNOWN)
            {
                string     spineName  = GetArrowFileName(arrow);
                GameObject spineArrow = ResourceHelper.Load(spineName);
                _skeletonAnimArrows.Add(spineArrow);

                Spine.Slot boundingSlot = GetBoundingSlot(_selectTileIndex);
                Vector3    center       = SpineHelper.CalcTileArrowOffset(boundingSlot, _skeletonAnim.transform, arrowRotation);
                spineArrow.transform.position = center + new Vector3(0, 0, -1);
                spineArrow.transform.Rotate(0, 0, arrowRotation);
            }
        }
    }
    public Vector3 GetTileCenter(int index)
    {
        if (index >= 0)
        {
            string     name = GetTileName(index);
            Spine.Bone bone = _skeletonAnim.Skeleton.FindBone(name);

            Vector3 center = SpineHelper.GetBoneCenter(_skeletonAnim.transform, bone);
            return(center);
        }

        return(Vector3.zero);
    }
    // ==========================================================================
    // collision

    public int DetectTileIndex(Vector3 worldPoint)
    {
        foreach (Spine.Slot slot in _skeletonAnim.skeleton.slots)
        {
            string boneName = slot.Bone.Data.Name;
            if (!IsTileName(boneName))
            {
                continue;
            }

            bool inside = false;

            Spine.Slot boundingSlot = _skeletonAnim.Skeleton.FindSlot("_" + boneName);
            if (boundingSlot != null)
            {
                inside = SpineHelper.IsPointInsideBounding(worldPoint, boundingSlot, _skeletonAnim.transform);
            }

            /*
             * Spine.BoundingBoxAttachment bounding = boundingSlot.Attachment as Spine.BoundingBoxAttachment;
             * float[] vertices = (float[])bounding.Vertices.Clone();
             *
             * int n = vertices.Length / 2;
             * for(int i = 0; i < n; ++i)
             * {
             *      float localX = vertices[i * 2 + 0];
             *      float localY = vertices[i * 2 + 1];
             *      float worldX;
             *      float worldY;
             *      bone.localToWorld(localX, localY, out worldX, out worldY);
             *
             *      Vector3 p = new Vector3(worldX, worldY, 0);
             *      p = _skeletonAnim.transform.TransformPoint(p);
             *
             *      vertices[i * 2 + 0] = p.x;
             *      vertices[i * 2 + 1] = p.y;
             * }
             *
             * bool inside = GeometryHelper.IsPointInsidePolygon(mx, my, vertices);
             */

            if (inside)
            {
                int index = GetTileIndex(boneName);
                return(index);
            }
        }

        return(-1);
    }
    private void ShowBoundingBox()
    {
        if (_boundingBox == null)
        {
            _boundingBox           = ResourceHelper.Load(AppConfig.FOLDER_PROFAB_CAMPAIGN + "CampaignBoundingBox");
            _boundingBoxLineRender = _boundingBox.GetComponent <LineRenderer>();
        }

        if (_selectTileIndex < 0)
        {
            _boundingBoxLineRender.SetVertexCount(0);
            return;
        }

        Spine.Slot boundingSlot = GetBoundingSlot(_selectTileIndex);
        SpineHelper.ShowBounding(boundingSlot, _skeletonAnim.transform, _boundingBoxLineRender);

        /*
         * Spine.BoundingBoxAttachment bounding = slot.Attachment as Spine.BoundingBoxAttachment;
         * float[] vertices = bounding.Vertices;
         *
         * int n = vertices.Length / 2;
         * _boundingBoxLineRender.SetVertexCount (n);
         * for(int i = 0; i < n; ++i)
         * {
         *      float localX = vertices[i * 2 + 0];
         *      float localY = vertices[i * 2 + 1];
         *      float worldX;
         *      float worldY;
         *      bone.localToWorld(localX, localY, out worldX, out worldY);
         *
         *      Vector3 p = new Vector3(worldX, worldY, 0);
         *      p = _skeletonAnim.transform.TransformPoint(p);
         *
         *      _boundingBoxLineRender.SetPosition(i, new Vector3(p.x, p.y, -1));
         * }
         */
    }