Esempio n. 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;
    }
Esempio n. 2
0
    void Update()
    {
        if (!player.IsEnabled)
        {
            return;
        }

        var bounds = player.bounds;
        var panel  = Physics.AllOverlaps(bounds, CollisionMask.Flipping)
                     .Where(o => o.Item2 == bounds)
                     .Select(o => o.Item1.GetComponent <FlipPanel>())
                     .Where(o => o != null)
                     .FirstOrDefault();

        if (panel == previousPanel)
        {
            return;
        }
        previousPanel = panel;

        if (panel == null)
        {
            cw.gameObject.SetActive(false);
            ccw.gameObject.SetActive(false);
            vertical.gameObject.SetActive(false);
            horizontal.gameObject.SetActive(false);
            previousPanel = null;
        }
        else
        {
            var x = panel.transform.localScale.x / 2;
            var y = panel.transform.localScale.y / 2;

            if (panel.flip1 == FlipKind.CW || panel.flip2 == FlipKind.CW)
            {
                cw.transform.position = panel.transform.position + new Vector3(x, y, -10);
                cw.gameObject.SetActive(true);
                cw.ReRender();
                cw.transform.localScale = LevelController.CurrentLevel.title == "Walking on the Walls"
                    ? new Vector3(2, 2, 1)
                    : new Vector3(1, 1, 1);
            }
            else
            {
                cw.gameObject.SetActive(false);
            }

            if (panel.flip1 == FlipKind.CCW || panel.flip2 == FlipKind.CCW)
            {
                ccw.transform.position = panel.transform.position + new Vector3(-x, y, -10);
                ccw.gameObject.SetActive(true);
                ccw.ReRender();
                ccw.transform.localScale = LevelController.CurrentLevel?.title == "Walking on the Walls"
                    ? new Vector3(2, 2, 1)
                    : new Vector3(1, 1, 1);
            }
            else
            {
                ccw.gameObject.SetActive(false);
            }

            var relativeVertical   = player.flip.down.x == 0 ? FlipKind.Vertical : FlipKind.Horizontal;
            var relativeHorizontal = player.flip.down.x == 0 ? FlipKind.Horizontal : FlipKind.Vertical;

            if (panel.flip1 == relativeVertical || panel.flip2 == relativeVertical)
            {
                vertical.transform.position = panel.transform.position + new Vector3(0, y, -10);
                vertical.gameObject.SetActive(true);
                vertical.ReRender();
                vertical.transform.localScale = LevelController.CurrentLevel?.title == "Walking on the Ceiling"
                    ? new Vector3(2, 2, 1)
                    : new Vector3(1, 1, 1);
            }
            else
            {
                vertical.gameObject.SetActive(false);
            }

            if (panel.flip1 == relativeHorizontal || panel.flip2 == relativeHorizontal)
            {
                horizontal.transform.position = panel.transform.position + new Vector3(x, 0, -10);
                horizontal.gameObject.SetActive(true);
                horizontal.ReRender();
            }
            else
            {
                horizontal.gameObject.SetActive(false);
            }
        }
    }