private void Perform()
        {
            var mostLeftAndMostRight = environment.MostLeftAndMostRightOfCurrentStage();

            target = FindTarget(caster, environment);
            grid2  = new Grid2(
                info.row, info.column, info.size.x, info.size.y, info.relativePos,
                mostLeftAndMostRight.x, mostLeftAndMostRight.y, info.blacklistRadius,
                target, info.ShowPreferedSide(), info.targetRadius, info.invert
                );
            countSoFar++;
            isTeleportEndTriggered = false;
            Vector2 teleportTargetPosition;

            if (countSoFar == 1)
            {
                teleportTargetPosition = grid2.ObtainFirstTime(target.Position(), caster.Position());
            }
            else
            {
                teleportTargetPosition = grid2.Obtain(target.Position());
            }

            if (info.ground)
            {
                teleportTargetPosition = environment.MapColliders().ClampPositionToGround(teleportTargetPosition);
            }

            //DLog.Log("Teleport to " + teleportTargetPosition);
            Vector2 casterPosition = caster.Position();
            Vector2 originalStartPositionOfLightning = casterPosition;
            Vector2 displacement = teleportTargetPosition - casterPosition;

            skill.TriggerEventWithId(info.beginEventId);
            GameObject appearPrefab = info.ShowDisappearPrefab();

            if (appearPrefab != null)
            {
                environment.InstantiateGameObject(appearPrefab).transform.position = caster.Position();
            }

            if (info.ignoreGate)
            {
                Entity entity = caster.GameObject().GetComponent <EntityReference>().Entity;
                entity.GetComponent <MovementComponent>().ForceSetPosition(teleportTargetPosition);
            }
            else
            {
                caster.DisplaceBy(displacement);
            }

            if (info.resetRoration)
            {
                movementComponent.SetOrientation(Quaternion.identity);
            }

            if (info.duration == 0)
            {
                isTeleportEndTriggered = true;
                skill.TriggerEventWithId(info.endEventId);
                GameObject disappearPrefab = info.ShowAppearPrefab();
                if (disappearPrefab != null)
                {
                    environment.InstantiateGameObject(disappearPrefab).transform.position = caster.Position();
                }
            }

            casterPosition = caster.Position();
            Vector2 originalEndPositionOfLightning = casterPosition;

            if (info.ShowChainingPrefab() != null)
            {
                skill.AddLoopable(
                    new Chaining(
                        info, caster, environment, skill,
                        originalStartPositionOfLightning, originalEndPositionOfLightning
                        )
                    );
            }

            if (info.invisible && invisibleStats != null)
            {
                invisibleStats.SetBaseBoolValue(true);
                gameObjectComponent.DisableRendererComponent();
            }
        }