Beispiel #1
0
    public async void DoFlip(Vector2 down, int input)
    {
        if (isFlipping != null)
        {
            return;
        }

        FlipKind flip;

        if (input == 1)
        {
            flip = flip1;
        }
        else
        {
            flip = flip2;
        }

        Quaternion delta;

        switch (flip)
        {
        case FlipKind.CW: delta = Quaternion.AngleAxis(90, Vector3.back); break;

        case FlipKind.CCW: delta = Quaternion.AngleAxis(-90, Vector3.back); break;

        case FlipKind.Horizontal: delta = Quaternion.AngleAxis(-180, down); break;

        case FlipKind.Vertical:
            var axis = Quaternion.AngleAxis(90, Vector3.back) * down;
            delta = Quaternion.AngleAxis(-180, axis);
            break;

        default: return;
        }

        var overlaps = Physics.AllOverlaps(physics)
                       .Select(o => (o.Item1, o.Item2, o.Item1.GetComponent <Flippable>()))
                       .Where(o => o.Item3 != null)
                       .ToList();

        var partials = overlaps
                       .Where(o => o.Item1.bounds != o.Item2)
                       .ToList();

        if (partials.Any())
        {
            foreach (var partial in partials)
            {
                ShowFlipError(partial.Item2);
            }
            return;
        }

        var objects = overlaps.Select(o => o.Item3).ToList();

        isFlipping = this;
        audioSource.PlayOneShot(FlipSound);
        var levelController = FindObjectOfType <LevelController>();

        levelController?.SaveUndoState();

        var parents = objects.Select(o => o.transform.parent).ToList();

        foreach (var o in objects)
        {
            o.transform.SetParent(transform, true);
            o.DoBeginFlip();
        }

        var cancelled = false;

        cancelFlip = () =>
        {
            cancelled = true;
            foreach (var(o, parent) in objects.Zip(parents, (l, r) => (l, r)))
            {
                o.transform.SetParent(parent, true);
                o.DoEndFlip(delta);
            }
            cancelFlip = null;
        };

        var originalPos = transform.position;

        transform.position = originalPos + new Vector3(0, 0, -5);

        var q0 = transform.rotation;
        var q1 = delta * q0;

        var anim = Animations.Animate(FlipTime, Animations.EaseInOutSine);

        while (!anim.isComplete)
        {
            if (!Physics.IsEnabled)
            {
                await Util.NextFrame(); continue;
            }
            await anim.NextFrame();

            if (cancelled || this == null)
            {
                return;
            }

            transform.rotation = Quaternion.Lerp(q0, q1, anim.progress);
        }

        transform.position = originalPos;
        cancelFlip();

        foreach (var o in objects)
        {
            var collider = o.GetComponentInChildren <MyCollider>();
            if (collider is MyStatic || collider is MyDynamic)
            {
                var(other, overlap) = Physics.AllCollisions(collider).FirstOrDefault();

                if (other != null)
                {
                    ShowFlipError(overlap);
                    levelController.DoUndo();
                    break;
                }
            }
        }

        isFlipping = null;
    }