Making the snappy camera of Dude Ranch (Part 2: The Zoom)

Howdy folks! :cowboy:

Back at it again with another breakdown of how I got the camera working for our game, Dude Ranch! This time I’m here to talk about how I implemented the dynamic zoom effect that happens as you mash the mouse buttons to wrangle a particularly thicc Dude into your clutches.

dudeRanchSmall.gif

The logic for this is actually pretty straightforward, so I’ll start with posting the relevant code for you to peruse.

``` private void InitiateImpactZoom() { if (this.ImpactZoomCoroutine == null && this.SnapCoroutine == null) { this.ImpactZoomCoroutine = StartCoroutine(this.ImpactZoom()); } }

private IEnumerator ImpactZoom()
{
    if (this.ImpactReturnCoroutine != null)
    {
        StopCoroutine(this.ImpactReturnCoroutine);
    }

    this.cumulativeYZoom += this.impactZoomAmount;

    Vector3 targetPoint = new Vector3(showcasePoint.x, this.transform.position.y - this.impactZoomAmount, showcasePoint.z);

    while (Mathf.Abs(this.transform.position.y - targetPoint.y) > 0.1f && followPlayer == false)
    {
        this.transform.position = Vector3.Lerp(this.transform.position, targetPoint, this.impactZoomSpeed);
        yield return null;
    }

    this.transform.position = targetPoint;

    this.ImpactReturnCoroutine = StartCoroutine(this.ReturnFromImpactZoom());
    this.ImpactZoomCoroutine = null;
}

private IEnumerator ReturnFromImpactZoom()
{
    Vector3 targetPoint = new Vector3(this.transform.position.x, this.zoomedInYValue, this.transform.position.z);

    while (this.transform.position.y < targetPoint.y && followPlayer == false)
    {
        this.transform.position = Vector3.Lerp(this.transform.position, targetPoint, this.impactReturnZoomSpeed);
        yield return null;
    }

    this.transform.position = targetPoint;
    this.ImpactReturnCoroutine = null;
}

```

I won’t post the full camera script, because honestly it’s a mess of flags and poorly organized code that would probably just serve to confuse rather than educate. But allow me to explain what’s going on here in case any of it’s confusing!

So basically, whenever the player clicks a mouse button to start wrangling a dude in, an event is fired that calls InitiateImpactZoom(). This in turn fires off a coroutine that does the actual zooming. The “showcasePoint” in the ImpactZoom() coroutine is actually the midpoint that we figured out earlier in Part 1. We use this as our anchor to determine what exactly we’re zooming into. Since our game functions on the X/Z plane, we’ll be manipulating the Y position of the camera to zoom in and out.

impactZoomAmount and impactZoomSpeed can be set to whatever you want inside the class, and you can fiddle around with the values to make more bombastic or more understated zoom effects that fit your needs. From there, we just do a simple Lerp in order to ensure that the camera doesn’t jarringly jump to positions and disorient the player.

After the impact zoom was finished, I wanted to have a little “recovery” zoom-out effect that slowly tried to return the camera back to its original position, so it encouraged you to keep wranglin' once you latched onto a Dude.

dudeRanchRecovery.gif

This is called at the end of the ImpactZoom() coroutine, and it slowly “undoes” the effects of the original impact zoom. It’s important to make the value for impactReturnZoomSpeed significantly smaller than the initial impactZoomSpeed, otherwise the camera will look all jumpy zooming in and out between every click. This zoom-out coroutine should also be cancelled if the player clicks again, so it doesn't interfere with the next zoom (this is handled in the first lines of the ImpactZoom() coroutine).

And that’s about it! To be honest, this isn’t the prettiest thing in the world. Every now and then the camera still has its moments where it looks a little jitterier than I would prefer. And as I mentioned before, the whole script that these short functions fit into is an absolute mess, which was the source of many of my frustrating bug hunts…

However, I don’t regret spending so much time fiddling with it and wrestling with bugs, because I like to think the dynamic camera makes a big difference in making our frenetic game feel even more chaotic and playful!

If you’d like, you can see the fruits of our labor by playing Dude Ranch here!

We already have a big ol’ list of games to play from the people who were kind enough to comment on our game, and we’ve already played a ton of super stellar ones already! Be on the lookout for a recommendations post very soon!

‘Til next time! :pointright: :cowboy: :pointright: