<?php
/*
Template Name: Projects
*/
?>

<?php get_header();?>

    <section id="content">
        <section id="main">

            <?php
                $loop = new WP_Query(array('post_type' => 'projects', 'posts_per_page' => 4));
                $i=1;
                while ( $loop->have_posts() ) : $loop->the_post();
            ?>

            <article class="post<?php if($i%2 == 0) { echo ' right'; }; $i++; ?>" id="post-<?php the_ID(); ?>">
                <h2><?php the_title(); ?></h2>
                <section class="entry">
                    <?php the_excerpt(); ?>
                </section>
            </article>

            <?php
                endwhile;
                wp_pagenavi();
            ?>

            <section id="map">
                <img src="<?php bloginfo('template_url') ?>/images/interactive-map.jpg" alt="Interactive Map" />
            </section>
        </section>

<?php get_sidebar(); ?>

    </section>

<?php get_footer(); ?>

I've pagenavi setup immediately after the endwhile. It isn't working, though. It does not even display in the source. Does anybody understand how I'm able to get this work?

I had been getting this same issue. For the posts_per_page parameter, the pagenavi works. You'll have to control the posts per page via Configurations > Reading through rather. I haven't found every other work-arounds.