tag:blogger.com,1999:blog-16212027848184122732024-03-14T01:44:14.873-04:00Tumbleweed Express Development BlogWelcome! This blog has been created to chart the development of Tumbleweed Express, a "Travel Defense" game in which the player controls a steam-powered train that travels along the countryside utilizing mounted weaponry to fend off attacking enemies in a "Western Steampunk" setting. This project originated at the 2011 Fall Game Jam that was hosted by the DC Chapter of the International Game Developers Association.Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.comBlogger79125tag:blogger.com,1999:blog-1621202784818412273.post-73388990548934168412016-07-07T11:47:00.003-04:002016-07-07T18:34:16.466-04:00A Tale of 54 Game Jams: Presentation & Panel<div class="MsoNormal">
<b>Presentation Night</b><br />
Recently the team and I visited our project’s “alma matar”,
the DC Chapter of the International Game Developers Association (IGDA), and
gave a presentation on what it was like to develop Tumbleweed Express over the
course of 54 Game Jams. The presentation, available on <a href="http://www.slideshare.net/mattm401/tumbleweed-express-a-tale-of-54-game-jams">SlideShare</a>, was high-level and
designed to provide the audience with an overview of the many events that
occurred during the project’s 4.5 year history; I dare to say that the
presentation went fairly well.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-MEgrOcYzFZ8/V35485zZX7I/AAAAAAAAAX0/aHM3PDiiR5QrWs0lZIVSJsJ-jirocOlWgCLcB/s1600/1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="286" src="https://3.bp.blogspot.com/-MEgrOcYzFZ8/V35485zZX7I/AAAAAAAAAX0/aHM3PDiiR5QrWs0lZIVSJsJ-jirocOlWgCLcB/s320/1.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Matthew Mauriello presents an overview of <br />
the team's development process and history</td></tr>
</tbody></table>
<div class="MsoNormal">
After the presentation, several members of the team were on hand
for an open panel discussion and the audience did not disappoint. Questions
ranged from how we handled team members various creative ideas, how we worked
together with so many team members, and what each of us thought was the most
challenging part of the process. We also discussed how we hired other
developers (e.g., artists, programmers) and how we unfortunately did not really
consider recruiting people with other valuable skills (e.g., marketing), which
was a huge mistake. We promoted the idea that the game jam model was very good
for development, communication, and balancing our commitments; however, we also
had to mention that at various points maturing the project required members of
the team to put in more time than one weekend a month which included committing
to daily updates when external deadlines were looming. Probably the most
important thing we discussed was the importance of having these external
deadlines and how production suffered when we failed to schedule these
milestones into our development timeline.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-sKi4TpdEuv4/V354-V5x2fI/AAAAAAAAAX4/8f73WaMiK48c2nqZq09uvYE4ejst4dxCQCKgB/s1600/2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="225" src="https://1.bp.blogspot.com/-sKi4TpdEuv4/V354-V5x2fI/AAAAAAAAAX4/8f73WaMiK48c2nqZq09uvYE4ejst4dxCQCKgB/s400/2.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Team members (L-R) Jacob Clayman, Matthew Mauriello, David To, and David Weiss<br />
participate in a panel discussion about the challenges faced and successes achieved during the project</td></tr>
</tbody></table>
<div class="MsoNormal">
<b>Avoiding Derailment
and Splitting the Loot<br />
</b>The panel continued through “Last Call” and even outside the venue after
the event was officially over. Walking back to my car, another indie developer asked
me an important question: now that we have released our game on Steam, how does
our team handle the money? Obviously, this is a tough question and the
developer explained to me that he had been unable to find a satisfying answer.
After a brief discussion this developer encouraged me to write a blogpost on
the subject, but unfortunately, there isn’t all that much tell from our team’s
perspective.<b><o:p></o:p></b></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
We believed that it was important to establish with the team
some kind of agreement that detailed the expected commitments from each member
and the expected rewards for that commitment. Our agreement included how we
handled disputes, what happened when a team member did not meet their
commitments, and provided team members with points where they could opt-out of
the project and still receive credit for their work. This might seem
unnecessary in the beginning of a project and indeed it was a full year before
we established a formal agreement, but at many points in our project having
this agreement was (and remains) valuable with respect to the continued health
of the team.<o:p></o:p></div>
<div class="MsoNormal">
<br />
Every year team members were offered a one year contract. If
they completed the contract then they earned a single immutable share in the
game’s future profits and expenses (assuming there would be any). Every active
member (i.e., those with an active contract) received a vote in any decisions
being made by the team during the course of that year. If there was an
important issue that couldn’t be resolved by discussion then a vote could be
called by any active team member. Finally, any vote on important decision
needed a 2/3rds majority vote to go through. While this process wasn’t perfect,
it did allow our team to handle relatively minor issues that came up during the
years that we have been working on the project. Additionally, having this sort
of agreement worked out and going through the process for establishing an LLC
did allow us to have concrete discussions with other developers about joining
the team which may have contributed to our success when it came to hiring new
people when others had left the team. Finally, when we released the game shares became locked.<o:p></o:p></div>
<br />
<div class="MsoNormal">
<b>What’s Next.<br />
</b>The other big question we get asked is: what’s next? And, this is an extremely
difficult question to answer at the moment as were still answering this for
ourselves. I can say for certain that development on and support for Tumbleweed
Express will continue for a time. Over the next year a few new features are
likely to come out along with bug and user experience fixes. I can also say
that we are beginning to reinvestigate some of the experimental content that we
dropped after our Kickstarter campaign (e.g., VR Support); however, it is
really too early to tell if any of these experiments will yield content that
reaches the current quality standard set by the product that is now available
on Steam. I can tell you that some of the things we were working on at our last
game jam (#54) were exciting and I am really hoping to be able to share details with
you all in the near future. Finally, another option we are considering is
starting a brand new project (or projects) though at this time all I can say on that is: stay tuned! <o:p></o:p></div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com1tag:blogger.com,1999:blog-1621202784818412273.post-36489485152259070072016-05-31T12:50:00.000-04:002016-05-31T12:50:57.191-04:00Now Available on Steam<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-0ziUJg2jTIU/V03ATn3lXYI/AAAAAAAAAWw/o0MJSn9feqkvK2VU8BlapKxqjWZ5TQNsgCLcB/s1600/AvailableOnSteam2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" height="225" src="https://1.bp.blogspot.com/-0ziUJg2jTIU/V03ATn3lXYI/AAAAAAAAAWw/o0MJSn9feqkvK2VU8BlapKxqjWZ5TQNsgCLcB/s400/AvailableOnSteam2.jpg" title="" width="400" /></a></div>
<div style="background-color: white; color: #444444; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2px; text-align: center;">
<span style="line-height: 19.32px;">Check out our Steam Store page and be sure to click "Follow":</span></div>
<div style="background-color: white; color: #444444; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.2px; text-align: center;">
<a href="http://store.steampowered.com/app/372350" rel="nofollow" style="color: #365899; cursor: pointer; line-height: 19.32px; text-decoration: none;" target="_blank">http://store.steampowered.com/app/372350</a></div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-52769679819762923402016-05-17T22:19:00.000-04:002016-05-17T22:19:14.271-04:00Launching on Steam: May 31, 2016<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-aPI1P6oKiMw/VzvQstZxfmI/AAAAAAAAAWU/sfqn0wzzi4Ih-yJPVgMep2VJCSyNmINHACLcB/s1600/Header.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-aPI1P6oKiMw/VzvQstZxfmI/AAAAAAAAAWU/sfqn0wzzi4Ih-yJPVgMep2VJCSyNmINHACLcB/s1600/Header.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="background-color: white; color: #1d2129; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 19.32px; margin-bottom: 6px; text-align: center;">
Tumbleweed Express will be launching on Steam:</div>
<div style="background-color: white; color: #1d2129; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 19.32px; margin-bottom: 6px; text-align: center;">
<b> May 31, 2016</b></div>
<div style="background-color: white; color: #1d2129; display: inline; font-family: helvetica, arial, sans-serif; font-size: 14px; line-height: 19.32px; margin-top: 6px;">
</div>
<div style="text-align: center;">
<span style="line-height: 19.32px;">Check out our Steam Store page and be sure to click "Follow":</span></div>
<div style="text-align: center;">
<a href="http://store.steampowered.com/app/372350" rel="nofollow" style="color: #365899; cursor: pointer; line-height: 19.32px; text-decoration: none;" target="_blank">http://store.steampowered.com/app/372350</a></div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-39629822952284354492016-01-04T14:48:00.003-05:002016-01-04T14:48:40.444-05:00Tumbleweed Express Final Release Platforms<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-4AIFZwg5QTw/VorMaBq8O6I/AAAAAAAAAVA/QXnqhSXFcSE/s1600/SquareLogo.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/-4AIFZwg5QTw/VorMaBq8O6I/AAAAAAAAAVA/QXnqhSXFcSE/s320/SquareLogo.jpeg" width="320" /></a></div>
<div style="text-align: center;">
...For PC, Mac, and Ubuntu (Linux)</div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
Get Ready for Exciting News!</div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-51734654342403372462015-05-30T15:55:00.002-04:002015-05-30T16:53:28.049-04:00Steam Greenlight & Audio Contributors Needed!Hello indie game enthusiasts!<br />
<div>
<br /></div>
<div>
The Dirigiballers are proud to announce that we have have recently been Greenlit by Steam! Thus, we are currently ramping up on production planning and execution in the expectation of hitting our internal release date. Obviously we are very excited about these recent events and we hope to make a formal announcement regarding our final plans in the coming months. However, we do find that we are in need of passionate people to provide audio contributions to the project. </div>
<div>
<br /></div>
<div>
<b>Do you have a desire to work on epic western steam punk music? Are you looking to boost your portfolio by contributing to an independent game development project? Do you want to work on rad stuff and help fellow indies get things done? We would love to hear from you!</b></div>
<div>
<br /></div>
<div>
Our team has several critical audio needs and were looking for an individual (or two) who can compose and execute several tracks that match the game's current score. Additionally, we're looking for someone interested in putting a critical ear to the game's audio portfolio (i.e., identifying where sound effects are needed, what's working, what's not, and executing on improvements for the game). If this sounds like something you (or someone you know) would be interested in doing, please send a resume and a portfolio to: <a href="mailto:dirigiballers@gmail.com">dirigiballers@gmail.com</a></div>
<div>
<br />
<b>Our current score is available on SoundCloud:</b><br />
<iframe frameborder="no" height="450" scrolling="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/users/111526728&color=ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false" width="100%"></iframe>
<br />
<b><br /></b>
<b>Our most recent trailer is on YouTube:</b><br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/S8TEnfs_81o/0.jpg" frameborder="0" height="300" src="https://www.youtube.com/embed/S8TEnfs_81o?feature=player_embedded" width="450"></iframe><br />
<br />
<br /></div>
<div>
Cheers, </div>
<div>
<br /></div>
<div>
The Dirigiballers</div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-28667054680855195942014-10-04T16:12:00.000-04:002014-10-04T16:12:19.857-04:00Post Mortem: How to (not) get funded on Kickstarter in 30 days<div align="center" class="MsoNormal" style="text-align: center;">
<br /></div>
<div align="center" class="MsoNormal" style="text-align: center;">
<br /></div>
<div class="MsoNormal">
On Thursday, October 2nd at 2:00p.m. EST the Tumbleweed
Express Kickstarter campaign ended unsuccessfully having reached ~22% of its
funding goal. Firstly, I want to express my sincerest gratitude towards
everyone who supported us during our campaign. The help we received from total
strangers was powerful and surprising and the support we received from friends
and family was heartwarming and encouraging. We met lots of new people, formed
friendships and connections, and strengthened our ties with the communities
that we came from. However, due to the all-or-nothing nature of Kickstarter we
unfortunately will receive none of the amount that was raised.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Mostly I felt relieved at the end of it, as the negative
emotions of frustration and disappointment had already run their course leading
up to the final hours of the campaign. Despite the technical failure of the
campaign however I do want to stress that this past month was the most
successful, intense, and positive marketing push that our project has had in
the three years we've been working on it. That said, I want to evaluate the campaign
and give my impressions on what happened using the following categories:</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>What I Know We Did
Right:</b> Actions we took that tangibly benefit our campaign</div>
<div class="MsoNormal">
<b>What I Think We Did
Right: </b>Actions we took that, while imaginably positive, did not appear to
tangibly benefit our campaign</div>
<div class="MsoNormal">
<b>What I Know We Did
Wrong:</b> Actions we took that tangibly hurt our campaign</div>
<div class="MsoNormal">
<b>What I Think We Did
Wrong:</b> Actions we took that, while imaginably negative, did not appear to
tangibly hurt our campaign</div>
<div class="MsoNormal">
<br /></div>
<h3>
<b>What I Know We Did
Right</b></h3>
<div class="MsoNormal">
<b>Event Outreach <o:p></o:p></b></div>
<div class="MsoNormal">
Undoubtedly, our team's strongest area of marketing is event
outreach. We make it a point to be out at conventions, festivals, and
gatherings as much as possible to get in lots of face-to-face marketing and
feedback. During the Kickstarter campaign we were at the Boston Festival of
Indie Games (FIG) and the Baltimore Innovate App Arcade where we built mailing-lists
with fans and connections to other developers leading to pledge support and cross-promotional
opportunities. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Public, Playable Demo<o:p></o:p></b></div>
<div class="MsoNormal">
Having a public demo was very meaningful for our campaign
because it meant we could give something tangible to interested parties and
potential customers so they could get a real taste of what our game is about
and the direction we're going in to reach a high standard of quality.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Event Journalist
Outreach<o:p></o:p></b></div>
<div class="MsoNormal">
Leading up to Boston FIG I made it a point to do some
background research and send a personal email out with our info and demo to
everyone on the Press list for the event. By the time it was time to drive up
to Boston we had lined up five interviews throughout the one-day event which
lead to a nice handful of articles and podcasts promoting our project and
campaign. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Twitter Outreach<o:p></o:p></b></div>
<div class="MsoNormal">
Halfway through our campaign I stepped up to take the reins
on our Twitter outreach efforts. What I ended up doing was using software to
scum the whole of the Twitterverse using search terms to find anyone talking
about the tools or styles relevant to our project. If anyone on Twitter
mentioned Unity Terrain I would send them a public message linking them to our
branded Unity Heightmap tutorial on our dev blog. Did you mention #Steampunk?
Maybe you'll like this game! And so on... garnering follows and likes and
whatnot building tangible interest one user at a time. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Youtube Outreach<o:p></o:p></b></div>
<div class="MsoNormal">
In the last third of our campaign I went on a mailing spree
using a list of game-related Youtube personalities linked to me by another
developer. Over three days I sent out a couple hundred personalized emails,
with downloadable demo links, to the entire spectrum of youtube gamer popularity
to see if anyone would make a video about our game. In the end we were able to
connect with a handful of Tubers who generously filmed and posted Let's Play
videos of our Demo while linking back to our campaign. </div>
<div class="MsoNormal">
<br /></div>
<h3>
<b>What I Think We Did
Right</b></h3>
<div class="MsoNormal">
<b>Campaign Crafting<o:p></o:p></b></div>
<div class="MsoNormal">
To craft our Kickstarter campaign we sourced other
successful campaigns and post mortems for inspiration while playing to the
strengths of our theme. What we came up with was an art heavy campaign page
with thematic designs for our sections, headers, graphics, and rewards. When
comparing ourselves to other campaigns I would say that our biggest advantages were
with our visuals, our video, our budget and the demo we put up. </div>
<div class="MsoNormal">
We've seen other campaigns go by and get several times more
than our funding goal while barely even having concept art to show for
themselves. We thought to ourselves, "We have an actual playable project
and a sweet trailer, we've guaranteed that this is a real project being worked
on in earnest by real developers". </div>
<div class="MsoNormal">
At the end of the day I can say we're damn proud of the
campaign we built, but it's hard to say how effective it was without getting
access to more exposure. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Update Crafting<o:p></o:p></b></div>
<div class="MsoNormal">
Over the course of our campaign we put out 12 updates total,
amounting to a little more than one update for every three days that the
campaign was running. We made it a point to generate as much content as
possible during the campaign to give as much interest to our backers as
possible while also ensuring to them that we're serious about what we do and
that we're working constantly to bring them new and valuable content.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>IGM Partnership<o:p></o:p></b></div>
<div class="MsoNormal">
Before our campaign started we actually partnered up with
Indie Game Magazine, a digital publication which had previously featured our
project in one of their issues. The deal was that in exchange for giving them a
commission on specific reward tiers they would provide us with free
subscriptions to distribute to our backers as well as run cross promotional
efforts for them. Despite being hesitant we ultimately took the deal. During
the campaign they promoted us on their social media accounts and wrote a couple
of articles about us (<a href="http://indiegamemag.com/tumbleed-express-is-riding-all-kinds-of-rails-onto-kickstarter/">despite
misspelling our project name...</a>). However, at the end of the day, it
doesn't seem like much if any funding at all can be traced back to the cross
promotion they ran for us. </div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Web Journalist
Outreach<o:p></o:p></b></div>
<div class="MsoNormal">
In the month before our campaign launched we put together a
list of as many publications as we could think of and sent out a ton of
personalized emails with our press release, some visual content, and a link to
download a desktop version of our demo. Despite our efforts though we were
unable to hook any big fish before or during our campaign.</div>
<div class="MsoNormal">
<br /></div>
<h3>
<b>What I Know We Did
Wrong</b></h3>
<div class="MsoNormal">
<b>Late Outreach<o:p></o:p></b></div>
<div class="MsoNormal">
Despite our net positive response to our outreach efforts it
seems that the majority of them came too late. Most successful campaigns seem
to have had an effective following
before launching. In fact, you're supposed to have the first 30% of your
funding ready to be pledged in the first week of your campaign. Obviously we
were never able to hit that mark. Perhaps we over-estimated our support before
launching, but we definitely didn't hit our stride in reaching out through
Twitter and YouTube for example until after our campaign was in full swing.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<b>Underutilizing
Facebook<o:p></o:p></b></div>
<div class="MsoNormal">
I believe that as a team we probably underutilized certain
aspects of Facebook as a tool for funding. While we obviously did lots of
'Sharing' and 'Liking', I think it's safe to say that we didn't fully
appreciate the power of simply messaging our friends for support. It wasn't
until the final week of the campaign that I went and manually messaged everyone
on my friendslist and in that process secured a handful of new backers while
simultaneously getting the chance to reconnect with friends I haven't talked to
in a while and who wanted to support our project. If more of our team was open
to that process and if we had put our weight behind it earlier on then we would
have been able to better frontload our initial funding amount.</div>
<div class="MsoNormal">
<br /></div>
<h3>
<b>What I Think We Did
Wrong</b></h3>
<div class="MsoNormal">
<b>Ignoring All Solicitors<o:p></o:p></b></div>
<div class="MsoNormal">
We got a LOT of solicitors during and at the beginning of
our campaign. I'm sure that there are companies that either scum Kickstarter
manually or have automated systems that email their pitch to new campaigns.
Regardless, we did some research early on but shortly after began to
systematically ignore them. A lot of them offered services that seemed to
overlap with work we'd already done, such as crafting content or creating press
releases. On the other hand, they also made grand promises about the number of
customers they were able bring our pitch to. Without formal marketing training
it was hard to evaluate whether or not we would be taken advantage of , but I
imagine that there are legitimate services that we passed up.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<br /></div>
<h3>
<b>What We'll Do Now</b></h3>
<div class="MsoNormal">
As they say, the show must go on! We've received a majority of
positive responses about our game leading up to and during the Kickstarter
campaign and the continued support from strangers has bolstered our confidence
in our design and art decisions. Despite
our lack of funding the team will continue to move into production with the
intention of bringing the project into beta and wrapping up for release. The
tools we need and our overhead expenses will continue to be paid for out of pocket
and the team will contribute the time that's needed to make our project a
reality.</div>
<div class="MsoNormal">
<br /></div>
<br />
<div class="MsoNormal">
Our continued marketing efforts will go towards improving
and marketing our Steam Greenlight campaign so that we have a strong outlet to
release from once the game is complete.</div>
Jake Claymanhttp://www.blogger.com/profile/07696792315286901372noreply@blogger.com1tag:blogger.com,1999:blog-1621202784818412273.post-5528082287431401062014-09-20T14:12:00.001-04:002014-09-20T14:12:17.919-04:00Unity Heightmap TutorialHey guys!<br />
<br />
Jake here. So we've been working with Unity terrain for a while and have run into plenty of hurdles and challenges. One issue we had was that our heightmaps for a long time were imported as segments instead of solid pieces, meaning that each piece needed it's own texture pallet; which is fine for a once-over but quickly became very tedious when needing to update textures or terrain data. The solution was to combine the pieces into a single height map, but that was easier said than done. In fact it took a lot of digging and some experimentation to really get a grip on the import/export process for height maps with Unity. Below is a video tutorial I recorded to demonstrate the method I settled on so I could pay it forward with anyone who might be running into the same problem!<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/dysCvFYMAgE?feature=player_embedded' frameborder='0'></iframe></div>
<br />Jake Claymanhttp://www.blogger.com/profile/07696792315286901372noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-14509006887314454102014-09-02T17:00:00.002-04:002014-09-02T17:01:05.693-04:00Kickstarter Has Launched: Show Your Support!We are very excited to officially launch our Kickstarter:<br />
<br />
<a href="https://www.kickstarter.com/projects/2014686147/tumbleweed-express-the-steampunk-railshooter-tower">https://www.kickstarter.com/projects/2014686147/tumbleweed-express-the-steampunk-railshooter-tower</a><br />
<br />
It would be great for the team if you could please show your support during this time! Once you have checked out our Kickstarter page, we have also re-launched on Greenlight with a full project moving forward on Steam; show us your thumbs:<br />
<br />
<a href="http://steamcommunity.com/sharedfiles/filedetails/?id=309156049">http://steamcommunity.com/sharedfiles/filedetails/?id=309156049</a><br />
<br />
Thanks again for all your support!Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-53990535680166826532014-08-21T11:58:00.001-04:002014-09-02T12:16:12.137-04:00Kickstarter Launch: September 2nd<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-SFxXmi_k5g0/U_YW-mkNHAI/AAAAAAAAAS8/YusenyndS-Q/s1600/kickstarter_annoucement.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-SFxXmi_k5g0/U_YW-mkNHAI/AAAAAAAAAS8/YusenyndS-Q/s1600/kickstarter_annoucement.png" height="640" width="492" /></a></div>
<br />Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-67019389705259497712014-08-10T10:49:00.002-04:002014-08-10T10:57:03.461-04:00Video Gamers United & KickstarterIt has been a long 3 year journey to get this far, but I am happy to report that The Tumbleweed Express will be back on the road! Our team is really excited to announce that our latest build we be presented at Video Gamers United:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-0zlwAYtAdOA/U-eDkomDALI/AAAAAAAAASo/8wnVscJChIA/s1600/VGU+Poster.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-0zlwAYtAdOA/U-eDkomDALI/AAAAAAAAASo/8wnVscJChIA/s1600/VGU+Poster.png" height="640" width="492" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our build will present a number of new features, which include:</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li>New enemies & fancier graphics.</li>
<li>The beginning of our open world level system.</li>
<li>Scaling difficulty of levels through side contracts.</li>
<li>Improved weapons and interfaces.</li>
<li>General usability improvements.</li>
</ul>
We're also proud to announce that we will launching our Kickstarter in September and we're inviting you all to be apart of the final stages of the production of our project. Finally, if you can't make it to VGU then you will have another chance to play the game at the Boston Festival of Indie Games also in September. Looking forward to seeing you take control of the Tumbleweed and supporting our team at these upcoming events!Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-59312350397497439422013-10-02T22:42:00.000-04:002013-10-04T09:54:24.869-04:00New Alpha Trailer!<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;">We just posted a new trailer showing off all our recent progress!</span><br />
<br style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;" />
<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;">Check it out!</span><br />
<br />
<div style="text-align: center;">
<iframe align="center" allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/jjSEFPcqU6c" width="420"></iframe><br /></div>
<br />
<br />
We also revamped out Greenlight concept page with new screenshots, descriptions, and of course the shiny new trailer. Please take a look and rate/favorite us :D<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><span style="margin-left: auto; margin-right: auto;"><a href="http://steamcommunity.com/sharedfiles/filedetails/?id=148875377&searchtext=tumbleweed"><img border="0" height="320" src="http://4.bp.blogspot.com/-K7EIrjqnd4U/UkzX7NOWBoI/AAAAAAAAAg4/QXPvNAQT_64/s320/GreenlightThumbnailWithLogo.jpg" width="320" /></a></span></td></tr>
<tr><td class="tr-caption" style="text-align: center;">or <a href="http://steamcommunity.com/sharedfiles/filedetails/?id=148875377&searchtext=tumbleweed">Click Here</a></td></tr>
</tbody></table>
Uncle_Gunhttp://www.blogger.com/profile/13813318934687257450noreply@blogger.com1tag:blogger.com,1999:blog-1621202784818412273.post-43385147162376593802013-08-14T17:22:00.000-04:002013-08-18T10:04:52.271-04:00Another day. Another new level.After several Jams of tidying up old levels for various showcases, we have finally had the chance to create a new one!<br />
<br />
We went from this sketch in MS Paint:<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ufUPrBKeeVE/Ug_8mbTffWI/AAAAAAAAAeA/71FCqu9hWP4/s1600/track-plans-(1).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="177" src="http://1.bp.blogspot.com/-ufUPrBKeeVE/Ug_8mbTffWI/AAAAAAAAAeA/71FCqu9hWP4/s320/track-plans-(1).png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
To this first draft in L3DT:</div>
<div style="text-align: left;">
</div>
<div style="text-align: right;">
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-ib_J1Klr-to/Ug_8qORtACI/AAAAAAAAAeI/MkN31am1U00/s1600/Unity-2013-07-27-12-03-14-70.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="http://4.bp.blogspot.com/-ib_J1Klr-to/Ug_8qORtACI/AAAAAAAAAeI/MkN31am1U00/s320/Unity-2013-07-27-12-03-14-70.png" width="320" /></a></div>
<br /></div>
<div style="text-align: left;">
And ended with this final landscape in Unity3D: </div>
</div>
<div style="text-align: right;">
</div>
<div class="separator" style="clear: both; text-align: right;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-HyatHKhwcok/Ug_8uGYTF5I/AAAAAAAAAeQ/RgayP_njmA8/s1600/Unity-2013-07-28-01-44-01-40.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="147" src="http://4.bp.blogspot.com/-HyatHKhwcok/Ug_8uGYTF5I/AAAAAAAAAeQ/RgayP_njmA8/s320/Unity-2013-07-28-01-44-01-40.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: right;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We are very excited for the mission we have planned for this level. Here the Tumbleweed will come face to face with a new foe. Who is she? What does she want? And what's with all the sweet talk she's sending on over to dear old Sneaky Pete? Not quite sure I want to know the answer to that, but more to come soon!</div>
Pezzhttp://www.blogger.com/profile/00753579725955859339noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-1537351810040749502013-07-03T08:39:00.000-04:002013-07-03T12:10:36.957-04:00Ride The Rails: With Oculus Rift!Needless to say, here at Dirigiballers, we're excited about the Oculus Rift and the new opportunities it brings for immersive gaming... and our development kit finally arrived! This past weekend, we imported the Unity plugin and took it for a spin. If you've got your own headset, swap this video to fullscreen and check it out!<br />
<br />
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/f3C_7cFxYEg?rel=0" width="420"></iframe><br /></div>
<br />
From a development standpoint, dropping the prefab into the scene was a breeze. After some selective renaming of cameras and connecting a few scripts, we were right there in it - riding the Tumbleweed Express. You can see from the footage it threw off our projectile launchpoint to a space above the caboose's turret (probably the result of interaction between our script calculating projectiles from a third-person mouse orbit and the "neck-height" magic of the Oculus prefab) - and of course our reticle disappeared since it's still keyed to the center of the screen and the GUI is pretty much lost. But the resulting feel? AMAZING. The depth really brings out the beauty of the Tumbleweed world and integrates well with our aiming mechanic (some of us don't want to go back to a mouse). The "aim-with-your-eyes" approach does make it difficult to switch back and forth between the front and back of the train so we'll get Sneaky Pete working on some sort of lever to bring the turret around faster than your neck can move.<br />
<br />
Like many backers, we were disappointed to learn that "Unity Support" means "Unity Support (with Pro License)" but are grateful for the extension of the pro-trial to four months. Since upgrading the team to full licenses is somewhere in the range of college tuition or a new car, we experimented a bit with rolling our own dual-camera prefabs. Could we write our own scripts to read Oculus as a controller and simply output a 1280x800 view from two cameras? Splitting the screen for dual cameras is a pretty simple trick: under the Inspector Camera settings, use the "Normalized Rect View" to set the left camera W to 0.5 with X set to 0 right camera W to 0.5 with X set to 0.5 (i.e. make the cameras half as wide as the screen, and have the right camera view start at the midpoint of the screen). It's easy to see how this could be used in lots of games for handling multi-player on a single screen. With some key-commands to adjust the distance and rotation of the cameras, we were able to calibrate certain parts of the field of view into focus manually, but getting the whole thing in sync seems to depend on the "fisheye" lens-distorting you can see in the increasingly recognizable Oculus-view videos. The difference between the plugin and the roll-our-own dual screen was striking so much appreciation to the Oculus team for doing the heavy lifting! If you're reading this: thanks for keeping the SDK builds coming - we're hoping you're in talks with Unity to find a solution that will make it possible for indie devs to use it without breaking the bank. Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-77119595682437145812013-06-18T13:17:00.005-04:002013-06-18T15:17:58.677-04:00Too Many Games: The Results<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><br />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="267">
<w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" Priority="39" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" Name="toc 9"/>
<w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin-top:0in;
mso-para-margin-right:0in;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0in;
line-height:115%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]-->
<br />
<div class="MsoNormal">
This past weekend a few of the Dirigiballers took our latest
build to <a href="http://www.toomanygames.com/">“Too Many Games”</a>, which is an awesome convention just outside of Philadelphia.
This was a major milestone for our team for many reasons. First, we hired two
new developers (Duy Le and Ben Heard) this year and this build represents the first
major release of their work alongside the continued efforts of our more senior
team members. We saw the release of: (1) Track Switching, (2) Activate-able
Bridges, (3) improved Dirigible behaviors and capabilities, (4) polished new
menus centered around the improved Battle Menu that provides micromanagement of
the players train, and (5) further integration of story and tutorial elements.
I could go on about all the improvements, but let’s just say that we set our
goals earlier this year and we exceed expectations. </div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ZDrM9sPYCIc/UcCVrdVkStI/AAAAAAAAAQk/1XQqBYddeaw/s1600/TMG2013-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="271" src="http://1.bp.blogspot.com/-ZDrM9sPYCIc/UcCVrdVkStI/AAAAAAAAAQk/1XQqBYddeaw/s400/TMG2013-1.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b>Too Many Games: Pushing builds and playtesting!</b></td></tr>
</tbody></table>
<br />
<div class="MsoNormal">
The audience at the convention really seemed to enjoy all
the new features and they provided ample feedback that we hope to incorporate
into our next build shortly. It was a real pleasure to interact with the Philadelphia crowd, you
guys really make game development worth it! I wanted to mention a few of the
awesome indie developers that we got to speak with. The crew behind <a href="http://www.defaultdan.com/">“Default Dan”</a> was awesome to network with and their game is excellent. There was also a neat student project by the <a href="http://www.theautomaticgentlemen.com/">“The Automatic Gentlemen”</a>, which was a great throwback to the
platformer days of old though with an updated modern look and cheeky
characters! Finally, a quick shout out to <a href="http://www.horizonsend.com/">Horizon’s End</a> and <a href="http://www.brokencrowngames.com/">Broken Crown Games, LLC</a>. Please check out these titles as well as all the other great Indies that
attended the convention.</div>
<div class="MsoNormal">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-WBmEOvj0Uq4/UcCVrgP1faI/AAAAAAAAAQo/k0oM2iHaZ4Y/s1600/TMG2013-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="110" src="http://1.bp.blogspot.com/-WBmEOvj0Uq4/UcCVrgP1faI/AAAAAAAAAQo/k0oM2iHaZ4Y/s400/TMG2013-2.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b>Too Many Games: A portion of our awesome audience and playtesters!</b></td></tr>
</tbody></table>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
You might ask, what is next for the Dirigiballers? Well were
still looking for support on our recently launched <a href="http://steamcommunity.com/sharedfiles/filedetails/?id=148875377">Steam Greenlight Concept</a> page.
We have an upcoming jam in two weeks where we will be setting our priorities
for the rest of the year. We should also be working on updating our game trailer
to show off the new content. We are really hoping to make it back to MAGFest and demo our
planned co-op experience for the audience. In the immediate future, we will be bringing an
intermediate build to <a href="https://www.facebook.com/events/662446173771635/">“Indie Con DC”</a>. This is a free and open to all ages event that is
hosted by <a href="https://www.facebook.com/gaminginpublic">“Gaming in Public”</a> and features many great Indie developers from
around the DC area. The event will take place on August 3<sup>rd</sup>, 2013 at
PUBLIC tenley.<span style="mso-spacerun: yes;"> </span>Additionally, Indie developers
can get in touch with the organizers to get their games into the event. Please come out and support all the organizations that are making this unique event possible!</div>
Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-77025339693491193492013-05-21T23:06:00.000-04:002013-05-22T14:35:31.202-04:00Terp Indie Games Fest [Video]Back in April we had a chance to talk about our game and what it was like on our team. We gave a presentation to the club and then demoed the game at their Indie Showcase with some other great local indie developers: e4Software, Omiya Games, and the guys from Broalition. The presentation was recently made available and is actually a pretty good summary of where we are at and where we <i>think</i> we're going at this point. If you have the time I highly suggest watching the video and checking out some neat indie projects here in the DMV area.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/LJiVl9zLcBM?feature=player_embedded' frameborder='0'></iframe></div>
<br />
We would also thank the University of Maryland's Game Development Club for giving us the opportunity to speak with them. Good luck on your projects because we can't wait to check them out!Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-31657963801316180252013-05-05T12:38:00.000-04:002013-05-05T12:38:27.534-04:00The Dirigiballers are Going Full Steam Ahead!The team is still hard at work making improvements to the game on all fronts. More updates will be coming soon, but for now heres what our awesome art team has been working on:
<br />
<br />
First, those crafty Dirigibles have a new "Dirigibomb" in their arsenal in an effort to squash that pesky train from meeting its destination:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-6aFSZzQlNS8/UYaHuNxnhWI/AAAAAAAAAZA/dTQfaPxntVo/s1600/dirigibomb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-6aFSZzQlNS8/UYaHuNxnhWI/AAAAAAAAAZA/dTQfaPxntVo/s320/dirigibomb.png" /></a></div>
<br />
Don't worry though, the train has also had some improvements, getting a tougher look and different compartments on the sides for marshals to help protect the cargo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-C1uzrDj86lo/UYaIBcfIW9I/AAAAAAAAAZI/wXzTp28c_nM/s1600/new_TrainCar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-C1uzrDj86lo/UYaIBcfIW9I/AAAAAAAAAZI/wXzTp28c_nM/s320/new_TrainCar.png" /></a></div>
<br />
<br />
It will still be tough travelling the Badlands with all sorts of new challenges in front of the Tumbleweed Express, including a new heavily guarded draw bridge.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-Qaxsi-7HrqA/UYaKcYe6EvI/AAAAAAAAAZs/3XggK50rMTk/s1600/drawBridge.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="149" src="http://1.bp.blogspot.com/-Qaxsi-7HrqA/UYaKcYe6EvI/AAAAAAAAAZs/3XggK50rMTk/s320/drawBridge.jpg" width="320" /></a></div>
<br />
We are continuing to add new content every week, including new shootable props and environmental upgrades:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-HUlu2FMbrUM/UYaK25eS77I/AAAAAAAAAZ0/sN51fPJxZA8/s1600/HayBail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="http://4.bp.blogspot.com/-HUlu2FMbrUM/UYaK25eS77I/AAAAAAAAAZ0/sN51fPJxZA8/s320/HayBail.jpg" width="320" /></a></div>
<br />
<it a="" all="" badlands="" be="" br="" bridge:="" challenges="" draw="" express="" front="" guarded="" heavily="" in="" including="" new="" of="" sorts="" still="" the="" tough="" traveling="" tumbleweed="" will=""><br />The Dirigiballers are still doing full steam ahead! Stay tuned for updates from the Code and Design teams. They are also working on some awesome stuff that'll take this game to a whole new level! :D</it>Uncle_Gunhttp://www.blogger.com/profile/13813318934687257450noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-43433985012147338922013-04-19T17:37:00.001-04:002013-04-20T00:05:30.318-04:00Presenting Badlands<div style="text-align: center;">
<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;">After a lot of hard work, the Tumbleweed heads north. Presenting, </span></div>
<div style="text-align: center;">
<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;">Act 2:The Badlands!</span></div>
<div style="text-align: center;">
<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-qIqQ0v_1wx8/UXG4wBRmtXI/AAAAAAAAAow/sSZeCgcMPBw/s1600/Unity+2013-04-19+17-23-09-57.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="http://1.bp.blogspot.com/-qIqQ0v_1wx8/UXG4wBRmtXI/AAAAAAAAAow/sSZeCgcMPBw/s400/Unity+2013-04-19+17-23-09-57.bmp" width="400" /></a></div>
<div style="text-align: center;">
<span style="background-color: white; color: #333333; font-family: 'lucida grande', tahoma, verdana, arial, sans-serif; font-size: 13px; line-height: 18px;"><br /></span></div>
Pezzhttp://www.blogger.com/profile/00753579725955859339noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-78286609249627855262013-03-28T23:41:00.000-04:002013-03-28T23:41:10.296-04:00Unity C# AudioManager Tutorial - Part 4 (Music, Pausing, & Voice Over)This is part 4 of a 4 part tutorial to create an audio manager for unity. This tutorial focuses on playing music, pausing fx while keeping music playing, and controlling sound volume including fading.
<br /><br />
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-1.html">Part 1</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-2.html">Part 2</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-3.html">Part 3</a> |
Part 4
<br /><br />
<h2>
Playing Music
</h2>
We'll need a couple more key concepts to play music, but the first is easy. We want music to loop, so we can just call the PlayLoop method with our music clip. In order to distinguish the music from other sounds playing, we will create a member variable m_activeMusic in the AudioManager that will hold a reference to this particular AudioSource. Unless otherwise noted, all code in this tutorial is in our AudioManager class.
<br />
<pre class="brush: csharp">
private AudioSource m_activeMusic;
public AudioSource PlayMusic(AudioClip music, float volume) {
m_activeMusic = PlayLoop(music, transform, volume);
return m_activeMusic;
}
</pre>
Notice that no transform parameter is passed in to identify the music position. Here I am assuming that in game music always plays at its given volume, and is not affected by any object movement in the game. To achieve this, we can to attach the music sound to the transform of the AudioManager, which, as explained in part 1, is attached to the camera, giving it a constant distance from the audio listener of 0.
<br /><br />
The PlayLoop method adds the music sound to our m_activeAudio, but with m_activeMusic we can track this particular sound special, which we will utilize in the next section, fx pause control.
<br /><br />
<h2>
Pause Control
</h2>
Now that we have a list of active sounds in m_activeAudio, we can pause them on command. With our reference to the music, we can indicate that the pause function only pauses all active sounds that are NOT the music:
<br />
<pre class="brush: csharp">
public void pauseFX() {
foreach (var audioClip in m_activeAudio) {
try {
if (audioClip.source != m_activeMusic) {
audioClip.source.Pause();
}
} catch {
continue;
}
}
}
public void unpauseFX() {
foreach (var audioClip in m_activeAudio) {
try {
if (!audioClip.source.isPlaying) {
audioClip.source.Play();
}
} catch {
continue;
}
}
}
</pre>
Fairly straight forward- when AudioManager.Instance.pauseFX() is called, the method cycles through each of the active sounds, and if the current iterator is not the music, it calls Unity's built in 'AudioSource.pause' function. The try/catch block is to catch any timing issues where the audio source is destroyed while this is iterating through the list. If there are any issues on a given element in the list, the method catches the error and simply skips that element, and next time we pause or unpause, the ClipInfo object that errored out on this pass should have been removed in our updateActiveAudio method from part 3.
<br /><br />
When the unpauseFX function is called, it goes through the active sounds, and if any are not playing, it plays them. If the audio is not paused and not playing, Unity automatically resumes them from where they paused. If you have any issues where sounds are restarting unexpectedly, this is the place to check first.
<br /><br />
<h2>
Voice Overs
</h2>
To make sure we can clearly hear a voiceover, we're going to make all sounds that are currently playing quieter while the voiceover is playing. Similar to music, we create a member variable that tracks the active voiceover that is playing. Also like music, we assume that the voiceover is full volume regardless of object positions in the world, so we attach the voice over to the AudioManager transform (the camera.) We're also going to need a volumeMod variable that holds the amount to reduce all the other sounds' volume, and set it low when the voice over is started.
<br />
<pre class="brush: csharp">
private AudioSource m_activeVoiceOver;
private float m_volumeMod = 1.0f;
public AudioSource PlayVoiceOver(AudioClip voiceOver, float volume) {
AudioSource source = Play(voiceOver, transform, volume);
m_activeVoiceOver = source;
m_volumeMod = 0.2f;
return source;
}
</pre>
Now that we have m_volumeMod, we can revisit our updateActiveAudio method to add volume modification to all sounds. Before we loop through the sounds, we will check if m_activeVoiceOver is set, and if it is not, we will set the volume mod to 1.0 (normal volume.) Otherwise, we will keep it's current value, which should be set at 0.2 (as in the PlayVoiceOver method above). Then, when iterating through the active audio, we will check if the audio is our m_activeVoiceOver, and if it is not, we will make the current volume its default volume multiplied by the volume modifier. This makes all sounds but the voice over affected by the volume mod:
<br />
<pre class="brush: csharp">
private void updateActiveAudio() {
var toRemove = new List<ClipInfo>();
try {
if (!m_activeVoiceOver) {
m_volumeMod = 1.0f;
}
foreach (var audioClip in m_activeAudio) {
if (!audioClip.source) {
toRemove.Add(audioClip);
} else if (audioClip.source != m_activeVoiceOver) {
audioClip.source.volume = audioClip.defaultVolume * m_volumeMod;
}
}
} catch {
Debug.Log("Error updating active audio clips");
return;
}
//cleanup
foreach (var audioClip in toRemove) {
m_activeAudio.Remove(audioClip);
}
}
</pre>
There you have it. You can extend this type of pausing/volume modification functionality to additional AudioSource variables if you have other types of sound events in your game. You can also use the concept behind this volumeMod variable to create an in-game master volume slider for the player.
<br /><br />
<h2>
Fading Sound
</h2>
As a final bonus feature, we can make the voice over modification fade the other sounds in and out instead of just snapping to the volume modification. This is a more minor trick, and it requires a few new variables, but it has a pretty significant effect, though subtle in execution.
<br /><br />
First we'll have to add two new variables. A min volume variable to establish how low the volume should go during voice overs, and a voice over fade bool to indicate if we are currently fading for the voice over or not. We'll initialize these new variables in our Awake method.
<br />
<pre class="brush: csharp">
private float m_volumeMod, m_volumeMin;
private bool m_VOfade; //used to fade to quiet for VO
void Awake(){
Debug.Log("AudioManager Initializing");
try {
transform.parent = GameObject.FindGameObjectWithTag("MainCamera").transform;
transform.localPosition = new Vector3(0, 0, 0);
} catch {
Debug.Log("Unable to find main camera to put audiomanager");
}
m_activeAudio = new List<ClipInfo>();
m_volumeMod = 1;
m_volumeMin = 0.2f;
m_VOfade = false;
m_activeVoiceOver = null;
m_activeMusic = null;
}
</pre>
We will update our Update method to gradually decrease the volumeMod to our min volume if our VOfade bool is true, and gradually increase the volumeMod to 1 if our VOfade bool is false. We will have the PlayVoiceOver method activate our VOfade bool, and have the updateActiveAudio method check the m_activeVoiceOver AudioSource and deactivate VOfade if it is null (if the voiceover is not currently active):
<pre class="brush: csharp">
void Update() {
//fade volume for VO
if (m_VOfade && m_volumeMod >= m_volumeMin) {
m_volumeMod -= 0.1f;
} else if (!m_VOfade && m_volumeMod < 1.0f) {
m_volumeMod += 0.1f;
}
updateActiveAudio();
}
public AudioSource PlayVoiceOver(AudioClip voiceOver, float volume){
AudioSource source = Play(voiceOver, transform, volume);
m_activeVoiceOver = source;
m_VOfade = true;
return source;
}
private void updateActiveAudio() {
var toRemove = new List<ClipInfo>();
try {
if (!m_activeVoiceOver) {
m_VOfade = false;
}
foreach (var audioClip in m_activeAudio) {
if (!audioClip.source) {
toRemove.Add(audioClip);
} else if (audioClip.source != m_activeVoiceOver) {
audioClip.source.volume = audioClip.defaultVolume * m_volumeMod;
}
}
} catch {
Debug.Log("Error updating active audio clips");
return;
}
//cleanup
foreach (var audioClip in toRemove) {
m_activeAudio.Remove(audioClip);
}
}
</pre>
Note that I am adjusting m_volumeMod by 0.1 each update. This struck a nice balance for me between having it happen quickly enough to still be effective, but slow enough to keep a smoothness in the transition.
<br /><br />
<h2>
Conclusion
</h2>
You've reached the end of the tutorial! You should now have a straightforward audio manager that acts as a singleton, allows clip playing and control from anywhere, tracks active sound clips, pauses select sounds, fades select sounds, and is simple to modify for further functionality. I hope this provided insight into a way to more easily manage audio in your projects. If you have any questions or feedback, please leave it in the comments, or feel free to contact me at baheard@gmail.com. Special thanks to <a href="http://devmag.org.za/author/herman/">Herman Tulleken</a> and <a href="http://www.blog.silentkraken.com/">Daniel Rodriguez</a> for their related posts.
Anonymoushttp://www.blogger.com/profile/05836510108468329453noreply@blogger.com5tag:blogger.com,1999:blog-1621202784818412273.post-83046119037368366672013-03-22T14:41:00.001-04:002013-03-28T23:44:35.491-04:00Unity C# AudioManager Tutorial - Part 3 (Control)This is part 3 of a 4 part tutorial to create an audio manager for unity. This tutorial builds on the structure developed in
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-1.html">part 1</a>,
expanding the functionality described in
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-2.html">part 2</a>.
It describes new Play options, and how to manage tracked audio clips.
<br /><br />
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-1.html">Part 1</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-2.html">Part 2</a> |
Part 3 |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-4.html">Part 4</a>
<br /><br />
<h2>
Overloading Play
</h2>
The next step is to create a play method that plays a sound on top of an existing object, so when the object moves, the sound moves with it. This is useful for things such as a car with a siren, or a character who is walking while they talk. This is another core method, and similar to our previous play method. Again, the concept is referenced from <a href="http://www.blog.silentkraken.com/2010/04/06/audiomanager/">Daniel Rodriguez's</a> helpful post. Except where specified otherwise, all methods in this section of the tutorial are within our AudioManager class.
<br />
<pre class="brush: csharp">
public AudioSource Play(AudioClip clip, Transform emitter, float volume) {
var source = Play(clip, emitter.position, volume);
source.transform.parent = emitter;
return source;
}
</pre>
Note that instead of a Vector3 parameter, we pass in the GameObject Transform that is emitting the moving sound. This method calls the default play method, creating an object at the emitter position and playing the sound there, but it then attaches the transform of the AudioSource (which is shared by its GameObject) to the emitter object by making the emitter its parent. Now the sound will follow the emitter where it goes. Remember that the original Play method registers the new sound object with the m_activeSounds collection, and destroys the GameObject after the length of the sound has played.
<br />
<br />
<h2>
Looping Sound
</h2>
Since the original play method destroys the sound object after the length of the clip, to loop we need a new method that won't destroy it. It also has to set the audiosource "loop" property to true. I assumed that any sound that loops will have an emitter, but if you needed a looping sound that played in one position in space, you could just remove the line that sets the transform.parent. This method is almost identical to the original except for these changes.
<br />
<pre class="brush: csharp">
public AudioSource PlayLoop(AudioClip loop, Transform emitter, float volume) {
//Create an empty game object
GameObject movingSoundLoc = new GameObject("Audio: " + loop.name);
movingSoundLoc.transform.position = emitter.position;
movingSoundLoc.transform.parent = emitter;
//Create the source
AudioSource source = movingSoundLoc.AddComponent<AudioSource>();
setSource(ref source, loop, volume);
source.loop = true;
source.Play();
//Set the source as active
m_activeAudio.Add(new ClipInfo{source = source, defaultVolume = volume});
return source;
}
</pre>
The setSource method becomes valuable now, because if we want to change any default settings of all the AudioSources that are created through the AudioManager, we only have to change it in the setSource method, and it will updated both this and the original Play method.
<br />
<br />
<h2>
Stopping the Looping Sound
</h2>
Now we've got a looping sound going on endlessly, we need to be able to stop it! This is a simple method that requires you to track the sound you'll want to stop at start time, and pass it in as a parameter when you're ready to stop it.
<br />
<pre class="brush: csharp">
public void stopSound(AudioSource toStop) {
try {
Destroy(m_activeAudio.Find(s => s.source == toStop).source.gameObject);
} catch {
Debug.Log("Error trying to stop audio source "+toStop);
}
}
</pre>
This highlights why it is useful to have all the Play methods return the AudioSource created. Here is an example of a new Init class using the loop and stop methods:
<br />
<pre class="brush: csharp">
public class Init : MonoBehaviour {
//testSound is public in order to set in the inspector
public AudioClip testSound;
private AudioSource playingSound;
void Start(){
playingSound = AudioManager.Instance.PlayLoop(testSound, m_enemy.transform, 1)
}
void Update(){
if(Input.GetKeyDown(KeyCode.Space)){
AudioManager.Instance.stopSound(playingSound);
}
}
}
</pre>
Note that since loop sounds are assigned to a parent on creation, if that parent is destroyed for any reason, the sound will be destroyed with it automatically.
<br /><br />
<h2>
Cleaning Up the Audio List
</h2>
For the final section of this tutorial, I will describe the mechanism for cleaning up inactive ClipInfo objects from our m_activeAudio list. This method will also be key later to control the sounds dynamically.
<br />
<pre class="brush: csharp">
private void updateActiveAudio() {
var toRemove = new List<ClipInfo>();
try {
foreach (var audioClip in m_activeAudio) {
if (!audioClip.source) {
toRemove.Add(audioClip);
}
}
} catch {
Debug.Log("Error updating active audio clips");
return;
}
//cleanup
foreach (var audioClip in toRemove) {
m_activeAudio.Remove(audioClip);
}
}
</pre>
The method creates an empty list of ClipInfo to remove. We can't remove them in the foreach loops since it would illegally modify the iterator. The method then goes through all the ClipInfos in m_activeAudio and checks each one's AudioSource. In the Play method the AudioSource was set to destroy after playing, so after the sound is finished, the AudioSource source of the ClipInfo will be null. If it is null, we add it to the toRemove list to be removed. After going through all active sounds, we go through all the toRemove ClipInfos and remove them from the m_activeAudio list. Since the ClipInfo list is not directly tied to the AudioSource it holds, this will work no matter how the AudioSource is destroyed (time or parent death.)
<br /><br />
Lastly we have to call this in the AudioManager Update() method so that it will be called continuously.
<br />
<pre class="brush: csharp">
void Update() {
updateActiveAudio();
}
</pre>
<h2>
Next time...
</h2>
We now have a working AudioManager that will play a sound at a location, play a sound at an emitter, play a looping sound, stop a looping sound, track all active sounds, and clean them up as they finish. In <a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-4.html">part 4</a>, I will show how this setup allows for dynamic centralized control, including implementing music, pausing non-music sounds, global volume control, and select volume control (for things like voice overs.)
Anonymoushttp://www.blogger.com/profile/05836510108468329453noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-57216835336263696482013-03-15T00:17:00.000-04:002013-03-28T23:43:42.552-04:00Unity C# AudioManager Tutorial - Part 2 (Play)This is part 2 of a 4 part tutorial to create an audio manager for unity. This tutorial focuses on creating the main methods that will play sounds, as will as tracking and managing active sounds.
<br /><br />
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-1.html">Part 1</a> |
Part 2 |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-3.html">Part 3</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-4.html">Part 4</a>
<br /><br />
<h2>
AudioManager - ClipInfo Object
</h2>
We will first create a ClipInfo object as a new data type to hold all the relevant data about each sound that
is handled by the audio manager. Right now it contains only variables for the sound clip to play and its initial volume, but it
could be expanded to hold any information you want to keep track of,
such as the time the clip started playing, or how many times it has
looped. We will add a member variable List of this ClipInfo to our AudioManager to track all audio playing, and we will update our Awake method to initialize this List.
<br />
<pre class="brush: csharp">
public class AudioManager : Singleton<AudioManager> {
class ClipInfo
{
//ClipInfo used to maintain default audio source info
public AudioSource source { get; set; }
public float defaultVolume { get; set; }
}
private List<ClipInfo> m_activeAudio;
void Awake(){
m_activeAudio = new List<ClipInfo>();
[see previous tutorial]
}
}
</pre>
First note that the ClipInfo class is inside the audio manager. This allows
it to be accessed only by the audio manager, hiding the data. You can
read the rules on nesting classes <a href="http://www.codeproject.com/Articles/20628/A-Tutorial-on-Nested-Classes-in-C">here</a>.
<br /><br />
Second, notice that ClipInfo holds the AudioSource directly, ignoring the GameObject that the source must be attached to.
<br /><br />
Lastly, we create a 'defaultVolume' property so that we can change the volume of the audio source dynamically, but remember what volume it was created at. More on this in part 4.
<br /><br />
<h2>
The Play Method
</h2>
For the core functionality of this AudioManager, I’ve referenced <a href="http://www.blog.silentkraken.com/2010/04/06/audiomanager/">Daniel Rodriguez</a> for the basic idea (I also recommend his <a href="http://www.blog.silentkraken.com/2010/06/22/unity3d-manager-systems/">post</a> on setting up managers for your unity projects.) The Play method of the AudioManager will:
<ol>
<li>Create a new GameObject.</li>
<li>Set its AudioSource to be our given sound clip.</li>
<li>Play the AudioSource.</li>
<li>Destroy the object.</li>
</ol>
The beauty of this is that we can play a given audio clip at any time by writing AudioManager.Instance.Play(parameters). We don’t have to worry about
creating the AudioManager since it is a singleton, we don’t have to worry about creating and destroying the accompanying GameObjects because everything is handled within the method.
<br />
<pre class="brush: csharp"> public AudioSource Play(AudioClip clip, Vector3 soundOrigin, float volume) {
//Create an empty game object
GameObject soundLoc = new GameObject("Audio: " + clip.name);
soundLoc.transform.position = soundOrigin;
//Create the source
AudioSource source = soundLoc.AddComponent<AudioSource>();
setSource(ref source, clip, volume);
source.Play();
Destroy(soundLoc, clip.length);
//Set the source as active
m_activeAudio.Add(new ClipInfo{source = source, defaultVolume = volume});
return source;
}
</pre>
For sound data, the method takes an audio
clip and a volume value as parameters, but could be extended to take other parameters to
modify the sound, such as pitch.
<br /><br />
The other parameter here is the Vector3 that indicates the position of the
sound. This is where the sound is playing from, and uses Unity’s built
in sound management to determine the panning and volume of the sound
based on the position of the audio listener component in your scene and
the rolloff for the audio source (more in rolloff in a little bit.)
<br /><br />
This isn’t a long method, and it is the most critical one, so I will step through the code.
<br />
<pre class="brush: csharp"> //Create an empty game object
GameObject soundLoc = new GameObject("Audio: " + clip.name);
soundLoc.transform.position = soundOrigin;
</pre>
This creates an empty GameObject in the world. When running the game, this
will show up in the inspector as “Audio: [whatever your clip name is as
listed in the Unity assets]”. It then moves this newly created object to the Vector3 position passed in.
<br /><br />
Next we attach an audio source to the fresh GameObject we just created:
<br />
<pre class="brush: csharp"> //Create the source
AudioSource source = soundLoc.AddComponent<AudioSource>();
setSource(ref source, clip, volume);
source.Play();
Destroy(soundLoc, clip.length);
</pre>
After creating the AudioSource, we pass a reference of it to ‘setSource’,
which I will outline shortly. Basically this method takes
the values passed in and applies them to the AudioSource of our newly
created GameObject. We start the AudioSource playing, then call the
Destroy method on the new GameObject, passing clip.length as the
parameter of how long to wait before destroying the object. Since
clip.length is the time it takes to play the clip, this will destroy our
AudioSource GameObject immediately after finishing the sound. This is
essentially like playing a one shot of an AudioClip, but since it is an
AudioSource, we can do more things with the clip, such as changing it’s
volume while it is playing, or pausing it, which we will take advantage
of later.
<br /><br />
Lastly, we register this audio source with the AudioManager as a ClipInfo
object which we created earlier. This way the AudioManager tracks the
sound and can handle it as it is playing.
<br />
<pre class="brush: csharp"> //Set the source as active
m_activeAudio.Add(new ClipInfo{source = source, defaultVolume = volume});
return source;
</pre>
<span style="background-color: transparent; color: black; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline;">
Since ‘source’ and ‘defaultVolume’ are public properties of our ClipInfo
object, we can assign them using object initializers (using the curly
braces), which allows us to avoid the need for an explicit constructor.
We add the new ClipInfo object to our AudioManager member variable List
m_activeAudio, which maintains references to all the sounds that are
playing.</span>
<br /><br />
<h2>
setSource Method
</h2>
For the final part of this section of the tutorial, we will create the “setSource” method referenced
above in the “Play” method. This method sets the properties of our new
audio source.
<br />
<pre class="brush: csharp">private void setSource(ref AudioSource source, AudioClip clip, float volume) {
source.rolloffMode = AudioRolloffMode.Logarithmic;
source.dopplerLevel = 0.2f;
source.minDistance = 150;
source.maxDistance = 1500;
source.clip = clip;
source.volume = volume;
}
</pre>
The AudioSource is sent in as a ‘ref’, so that all changes made to the AudioSource
parameter passed in will be kept after this method is finished and our
‘Play’ method resumes.
<br /><br />
Rolloff mode is the way that Unity makes the sound decrease in volume as its
distance from the AudioListener in the scene increases. In the inspector
you can see a graph that models this.
<br />
<a href="http://4.bp.blogspot.com/-2BxWxhIgfFE/UUKXgM7qp5I/AAAAAAAAAB8/_JYNDBnFCs4/s1600/Unity+AudioSource+volume+props.png" imageanchor="1" ><img border="0" src="http://4.bp.blogspot.com/-2BxWxhIgfFE/UUKXgM7qp5I/AAAAAAAAAB8/_JYNDBnFCs4/s320/Unity+AudioSource+volume+props.png" /></a>
<br />
The Linear mode means that the sound decreases at an equal rate as you get further from the listener.
The Logarithmic mode means that the sound decreases sharply as you begin
to move away from the listener, but the farther you get away from the
listener, the less the sound decreases. I opted for Logarithmic sound
because it more closely matches the way you hear sounds in reality- a
noise made at 10ft away will sound much louder than the same noise at
100ft away, but a noise at 500ft away will sound only slightly louder
than the same noise at 800ft away.
<br /><br />
The dopplerLevel is related to how the sound is affected by movement (like sirens on a passing ambulence.)
I set this to .2 because I found that the default value of 1 can create strange sound anomalies
when rotating the camera quickly.
<br /><br />
minDistance and maxDistance are important, particularly for Logarithmic rolloff.
<br /><br />
minDistance is how far the sound must be from the listener before the volume starts
to decrease. This is especially important because if this is set to its
default 0, the sound will start to drop off sharply at any distance
from the listener. This means that a sound made at 1ft away will be
significantly louder than a sound made at 2 ft away, which just does not
feel right in-game. For Tumbleweed, a distance of 150 seems to be
working for now- all sounds less than 150 game ‘units’ away will play at
max volume, and after that the sound dropoff will begin.
<br /><br />
maxDistance is important because it determines both the maximum distance at which a
sound will play, as well as the curve of sound dropoff. With
logarithmic rolloff, you can make this number really huge, and sounds
that play in the far distance and middle distance will still sound
natural.
<br /><br />
Finally, we set the sound clip to our clip, and the default volume to our volume.
<br /><br />
We covered a lot here. If set up
correctly, you should now be able to play any AudioClip by calling
“AudioManager.Instance.Play(AudioClip, Vector3, float)” with your
desired clip, position, and volume.
<br /><br />
Here is a my project setup and in-game hierarchy in Unity so far:
<a href="http://3.bp.blogspot.com/-2wxZXF3CxvY/UUKZom_E81I/AAAAAAAAACE/L652btnp6RQ/s1600/Unity+AM+tut2+final+active.png" imageanchor="1" ><img border="0" src="http://3.bp.blogspot.com/-2wxZXF3CxvY/UUKZom_E81I/AAAAAAAAACE/L652btnp6RQ/s320/Unity+AM+tut2+final+active.png" /></a>
<br />
<h2>
Next time...
</h2>
In <a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-3.html">part 3</a> of the AudioManager tutorial, I will cover placing moving sounds on moving objects, pausing sounds, and changing volumes.
<br /><br />Anonymoushttp://www.blogger.com/profile/05836510108468329453noreply@blogger.com1tag:blogger.com,1999:blog-1621202784818412273.post-10942590381006357162013-03-12T09:45:00.000-04:002013-03-28T23:43:59.652-04:00Unity C# AudioManager Tutorial - Part 1 (Setup)This is part 1 of a 4 part tutorial to create an audio manager for Unity 3d. This tutorial focuses on the initial setup of the singleton and audiomanager classes.
<br /><br />
Part 1 |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-2.html">Part 2</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-3.html">Part 3</a> |
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-4.html">Part 4</a>
<br /><br />
<h2>
Handling Sound in Unity</h2>
Default Unity sound control is clumsy. GameObjects can only have one AudioSource as a component. AudioClips are inflexible. In these posts, I describe an audio manager that is simple to use, easy to organize, and adds versatility to the Unity sound tools, building on its existing structure. This includes playing audio clips dynamically with full control, tracking sounds that are currently playing, pausing select sounds, and controlling volume dynamically. This tutorial assumes you have a basic understanding of sound handling in Unity, check out <a href="http://docs.unity3d.com/Documentation/Manual/Sound.html">the manual</a> for an overview.
<br /><br />
<h2>
Singleton
</h2>
First off, we need the singleton. For this, I’ve referenced the article <a href="http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/" target="_blank">50 tips for working with unity</a>. I
recommend reading this in its entirety- you don’t have to agree with
everything, and you don’t have to absorb every detail, but it’s good
think about these things!
<br /><br />
The premise of the singleton is that you have a single object which can be
accessed at any time, without explicit instantiation, and you know that the instance you are accessing is the
sole instance of the singleton object. It works through a static method
which calls the stored instance of the object. Inside the method, the
singleton checks if the instance exists and returns it. If it does not
exist, it creates one and returns this. From the outside, though, it
seems as if the single instance is always available.
<br /><br />
The great benefit to this for our AudioManager is we do not have to manage a GameObject for it for each scene. We simply have each sound clip to play call the AudioManager, and if the instance doesn’t exist, the singleton creates one, and if it already exists, the singleton uses the existing one, so there is no threat of
creating multiple audio manager instances in one scene, and we don’t have to concern ourselves with its existence.
<br /><br />
<pre class="brush: csharp">
using UnityEngine;
using System.Collections;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {
protected static T instance;
//Returns the instance of this singleton
public static T Instance {
get {
if (instance == null) {
instance = (T)FindObjectOfType(typeof(T));
if (instance == null) {
GameObject container = new GameObject();
container.name = typeof(T)+"Container";
instance = (T)container.AddComponent(typeof(T));
}
}
return instance;
}
}
}
</pre>
The T listed represents a generic type, which allows you to create singletons of various types by inheriting this class. In the context of this post, though, we will only be using it for our AudioManager.
<br /><br />
Also note that the Singleton inherits from MonoBehaviour, which allows us to implement any of its subclasses as components on GameObjects.
<br /><br />
You can google the Unity command “DontDestroyOnLoad” to see how to make a GameObject persistent across scenes, but I am not putting it in this base class since we may not want all derived classes persistent across scenes. For example, in our AudioManager, we do not need a persistent GameObject.
<br /><br />
<h2>
AudioManager - Initialization
</h2>
To begin, we will initialize our new AudioManager class using Awake(). We use this instead of Start() because we want to make sure our AudioManager is available first thing in the scene, in case there are any sounds that start playing immediately (like music.)
<br /><br />
<pre class="brush: csharp">
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class AudioManager : Singleton<AudioManager> {
void Awake() {
Debug.Log("AudioManager Initializing");
try {
transform.parent = GameObject.FindGameObjectWithTag("MainCamera").transform;
transform.localPosition = new Vector3(0, 0, 0);
} catch {
Debug.Log("Unable to find main camera to put audiomanager");
}
}
}
</pre>
We start by creating a message logging the AudioManager initialization.
Next, we try to attach the AudioManager to the main camera, placed
within a try/catch block so that we can log any issue finding the main
camera or attaching this object. This may be something worth playing
around with if your AudioListener isn’t always on your main camera, or you
don’t tag your game camera with the “MainCamera” tag, but for Tumbleweed this works.
<br /><br />
Setting the ‘transform.parent’ property of the object makes it appear under the
parent object in the scene hierarchy while running the scene. It helps organize your hierarchy,
but more importantly, all transforms (movement) of the parent
GameObject will also apply to its children (and its children’s
children.) This way, the AudioManager will stick to the camera like a
cat to a tree. Now we can attach certain sounds (like music) to the AudioManager itself, and know that it will stay on the camera, which means it will not change volume or pan position unless we explicitly instruct it to.
<br /><br />
Initializing AudioManager in a scene:
<br />
<ol>
<li>Any script makes a call to AudioManager.Instance (eg var AM = AudioManager.Instance).</li>
<li>The Singleton base class checks for an instance of AudioManager.</li>
<li>Not finding an instance, the Singleton creates a new AudioManager GameObject and attaches the AudioManager component (script.)</li>
<li>The AudioManager script Awake() method searches for the main camera (with the “MainCamera” tag.)</li>
<li>Finding it, it attaches itself to the main camera by making the camera its parent.</li>
</ol>
Now we have an AudioManagerContainer GameObject with an AudioManager component, and it is a child of the MainCamera. At this point, if you have set these classes up correctly, you should be able to call this in your scene, though it does not do anything yet. You need a GameObject in the scene with the "MainCamera" tag. If you write "var AM = AudioManager.Instance" on the Start() method of any object in your scene, you should receive a Console message that reads "AudioManager Initializing." If you successfully receive this message, you are ready to move on to part 2.
<br /><br />
<h2>
Next time...
</h2>
In
<a href="http://dirigiballers.blogspot.com/2013/03/unity-c-audiomanager-tutorial-part-2.html">part 2</a>,
I will create a Play method, and will discuss some of the controllable attributes of sounds in Unity.
<br />Anonymoushttp://www.blogger.com/profile/05836510108468329453noreply@blogger.com2tag:blogger.com,1999:blog-1621202784818412273.post-63070583347173433332013-02-22T15:19:00.001-05:002013-02-22T15:30:13.741-05:00RoboHeart Released for iPad!We're super proud to say we have completed the Apple review process for our Global Game Jam 2013 Project: <br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://itunes.apple.com/us/app/roboheart/id598290014?mt=8"><img alt="RoboHeart Title Screen" border="0" height="320" src="http://3.bp.blogspot.com/-guHaGc44wEo/USfQv10mwpI/AAAAAAAAAPA/XE2JR-NzAo8/s320/UI_Main_Menu_Bkgrd.png" title="" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://itunes.apple.com/us/app/roboheart/id598290014?mt=8"><b>RoboHeart: https://itunes.apple.com/us/app/roboheart/id598290014?mt=8</b></a></td><td class="tr-caption" style="text-align: center;"><a href="https://itunes.apple.com/us/app/roboheart/id598290014?mt=8"><br /></a></td><td class="tr-caption" style="text-align: center;"><a href="https://itunes.apple.com/us/app/roboheart/id598290014?mt=8"><br /></a></td><td class="tr-caption" style="text-align: center;"><a href="https://itunes.apple.com/us/app/roboheart/id598290014?mt=8"><br /></a></td></tr>
</tbody></table>
<br />
When we conceived this game we envisioned it running on a touch pad device and we're really happy we were able to release the game in a free to play setting. Other than the necessary steps to get the game up on the iStore, this game is more or less exactly as it was at the end of the 48 hour jam that it was created in. We made the design choice to release only for iPad, because we had limited time on our Global Game Jam provided Unity Licenses and the recent upgrades to iOS 6.0 on our development device made things difficult. It is awesome just to have this project out, especially because we're about to go into our February jam session on Tumbleweed Express - positive team confidence booster right before starting an epic weekend!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-1KDQL2nVcm4/USfQyeW3PpI/AAAAAAAAAPI/VXVxH3RXpmE/s1600/Shockwave.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="http://1.bp.blogspot.com/-1KDQL2nVcm4/USfQyeW3PpI/AAAAAAAAAPI/VXVxH3RXpmE/s320/Shockwave.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b>RoboHeart: The Pulse!</b></td></tr>
</tbody></table>
Simple instructions: drag the robot arm on the left bot back to aim, release in the direction you want, and tap the screen once to initiate a pulse and again when it is over an power up you want to use or to cancel the pulse and start again. Instructions are in the top left corner, the top right corner is your time limit. There are a total of 9 levels to play through. Unfortunately the game is "AS IS" because our licenses situation.... what are you going to do? Enjoy!Matthew Mauriellohttp://www.blogger.com/profile/12362338784151038359noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-68865112670405566562013-02-20T17:42:00.001-05:002013-02-20T19:53:17.684-05:00Train Upgraded!Made some tweaks to the train engine. Got the new animated wheels added and put some realistic textures to it. Don't worry, she'll go much faster once we put her on the tracks :P More updates soon!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://dl.dropbox.com/u/26344956/Tumbleweed%20Express%20development/new_Train.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://dl.dropbox.com/u/26344956/Tumbleweed%20Express%20development/new_Train.gif" width="400" /></a></div>
Uncle_Gunhttp://www.blogger.com/profile/13813318934687257450noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-73570454183931629642013-02-05T15:00:00.000-05:002013-02-06T11:40:14.769-05:00Bandito Animation!Decided to play with animation today. I have never really rigged and animated anything before, so its still pretty shaky. I thought it was good for my first try Progress! :P
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://dl.dropbox.com/u/26344956/Tumbleweed%20Express%20development/Robot_Anim_1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://dl.dropbox.com/u/26344956/Tumbleweed%20Express%20development/Robot_Anim_1.gif" width="320" /></a></div>
This is only a portion of a new enemy we are introducing. More details coming soon!Uncle_Gunhttp://www.blogger.com/profile/13813318934687257450noreply@blogger.com0tag:blogger.com,1999:blog-1621202784818412273.post-43537506025560362132013-02-03T10:00:00.000-05:002013-02-03T10:00:18.105-05:00Global Game Jam 5 (2013)<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">This is Ben Heard, I’m joining the Dirigiballers to help with programming on Tumbleweed Express. You can learn more about me at </span><a href="http://www.baheard.com/"><span style="color: #1155cc; font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">www.baheard.com</span></a><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">. I wanted jump in and write a blog entry to introduce myself, and also to write about <a href="http://globalgamejam.org/" target="_blank">Global Game Jam 2013</a>. This event was both my first chance to work with some of the Dirigiballers as well as my first game jam experience.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Global Game Jam</b></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">If you’re on the fence about going to a game jam, I definitely recommend trying it out because It is both fun and free! I’m not sure if I’ve ever had as much fun at a free event that lasted all weekend as I did attending the Global Game Jam. Everyone at the event was really friendly, which included a solid turnout of members from <a href="http://www.facebook.com/groups/115048675174689/" target="_blank">IGDA DC</a>.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">The weekend was not only really fun, but also an intensive learning experience. I went in with a limited knowledge of Unity, and came out feeling like I could make anything. I was surprised at just how easy it is to rapidly develop using Unity and how effectively my knowledge of C# plugged right in. The software is fast, powerful, but also seems deep and extensible.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial;"><span style="font-size: 15px; white-space: pre-wrap;"><b>Day 1</b></span></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">After an initial design brainstorm, we locked in on an idea that would become “Roboheart”, based on the 'heartbeat' theme for the weekend. The game is puzzle based, and the basic idea consists of one robot trying to throw his robot heart to another in a space station. While in the air, the player can activate the heart by clicking the mouse. Activating the heart emits a ‘pulse’, which is an expanding circle like a radar pulse. If the player clicks again while the pulse is over a powerup (or multiple powerups), the powerup is consumed and its effects immediately applied. For example, the main powerups are force vectors, which, when activated, move the heart in the direction the vector is pointing. We had a lot of ideas for powerups, but it turned out the force vectors create a wide variety of potential challenges, so we focused on puzzles with these, as well as an one that reverses the gravity for the heart.</span><span style="font-family: Arial; font-size: 15px; white-space: pre-wrap;"> After deciding on the basic idea, we broke out to work on our parts.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://globalgamejam.org/sites/default/files/styles/large/public/screenshots/2013/Shockwave.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="145" src="http://globalgamejam.org/sites/default/files/styles/large/public/screenshots/2013/Shockwave.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">RoboHeart Pulse!</td></tr>
</tbody></table>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">It was pretty surreal the first night to go to bed at 4am after crunching out the initial mechanics. I layed out my sleeping pad and bag under the flourescent lights of the computer lab, hiding my head under an unused table to help block the light, put in my earplugs, and grabbed some sleep while a few others continued to clack away on keyboards.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Day 2</b></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://globalgamejam.org/sites/default/files/styles/large/public/RoboHeart_1.JPG" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="150" src="http://globalgamejam.org/sites/default/files/styles/large/public/RoboHeart_1.JPG" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">GGJ 2013 Dirigiballers</td></tr>
</tbody></table>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Waking up a few hours later, it was straight back to coding, which was like a dream. Matt was up when I went to sleep, and he was up when I got up, except now he was wrapped in a blanket. Getting the latest build from our SVN server, I started to see the art assets that Jake and Andy had been working on integrating into the game, and what a difference it made! All of a sudden the game, which so far was just numbers and events, starts to have colors and art out of the blue! How cool is that. I think that was the coolest part of the game jam - everyone working at their parts, and the whole game coming together, feeling some ownership of something you could never have done alone.<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"></table>
</span><br />
<br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"><b>Day 3</b></span><br />
<br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span>
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">We had scoped our project well, and were ahead of schedule, so we were able to dedicate most of our third day to testing and polish (menus, sound, etc). The presentations on Sunday were really fun, it was great to see what everyone else had been working on alongside us.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">The most popular game of the weekend was called <a href="http://globalgamejam.org/2013/heartline-0" target="_blank">Heartline</a>. It is a two player co-op local multiplayer sidescroller puzzle game. The player holding the heart has special abilities, but can pass it to the other to help get both players through obstacles. The nature of the puzzles reminded me of Portal 2 co-op. The game featured simple, but effective, 2d art.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">The game that really stood out to me, though, was called <a href="http://globalgamejam.org/2013/heart-dropper" target="_blank">Heartdropper</a>. The main mechanic was that tweets to @heartdropper made powerups drop in-game. The main programmer on this project said he used the Twitter API to read tweets and store them in a MySql database using PHP. The game the then read the tweets from the database to create the powerups in the game. I'm definitely interested in seeing where they take this.</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">The weekend was a blast and I’d recommend it to anyone with an interest in making games - this is definitely a great place to start. The main point of the even is to set aside a weekend to collaborate, learn, manage, structure time, and produce something as well generally promoting the craft. I’ll definitely be attending the Global Game Jam next year and I’m already wondering: what game will come out of it next?</span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;"></span><br />
<span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Roboheart will be available on the app store in the next couple of weeks if you have an iPad, or you can play the game online with the Unity player at:</span><br />
<a href="https://www.intriguingds.com/application/roboheart/"><span style="font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;">Unity Player Version</span></a><br />
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="295" src="http://www.youtube.com/embed/o7ZvugjZpdk" width="480"></iframe>Anonymoushttp://www.blogger.com/profile/05836510108468329453noreply@blogger.com0