Zombie Playground’s Character Pipeline: Designing a Modular Rig Solution

With a greater number of potential characters than Mothhead, our previous Unity project; I went into Zombie Playground’s pre-production with my mind already set on creating an automated rigging solution. I took some inspiration from a Modular Rigging course I followed on 3dBuzz and begun to break down my rigging process into object-oriented code in suite I named Automato.

class BaseSubstruct(object):
    '''
    Abstract class to derive new rig modules from
    '''
    NAME = 'abstractobject'
    NICE_NAME = ''
    CREATION_PARAM_JSON_ATTRNAME = 'creationParams'
    DESCRIPTION = 'generic abstract description'
    MIN_JOINTS = 1  # number of joints needed to create substruct
    REQUIRES_SKELETON_CHAIN = True  # if true, subsruct requires a skeletal chain for creation

    def __init__(self, basename, joints, parent, mainControl):
        '''
        Builds rig in maya and creates an asset node to contain relevant nodes
        '''
        self.container = None
        self.layer = None
        self.containedNodes = list()
        self._rigControls = dict()
        self.lockAttrs = list()
        self.basename = basename  # unique name to identify nodes created by this substruct
        self.parent = parent  # parent to attach top-most rig node
        self.joints = joints  # base skeleton joints to attach
        self.mainControl = mainControl

        self.mainColorAttr = None

        if self.parent is None:
            self.parent = self.joints[0].firstParent2()
            if self.parent:
                self.parent = pm.PyNode(self.parent)
            else:
                if mainControl:
                    self.parent = mainControl

        self.verifyParams()
        self.container = pm.container(name='_'.join([Prefix.CONTAINER, basename, self.NAME]))

        ## Parameter dictionary for storing settings for assets
        ## Children classes can further expand this dictionary with parameters of their own
        self.paramDict = {'classname': self.NAME,
                          'basename': self.basename,
                          'joints': [str(i) for i in self.joints],
                          'parent': str(self.parent),
                          'mainControl': str(self.mainControl),
                          'container': str(self.container)}

        pm.addAttr(self.container, dataType='string', ln=self.CREATION_PARAM_JSON_ATTRNAME)
        pm.addAttr(self.container, at=int, ln='color', min=0, max=31, defaultValue=0, keyable=False, hidden=False)

        self.mainColorAttr = self.container.attr('color')
        self.mainColorAttr.showInChannelBox(True)

        if self.layer is None:
            self.layer = Layers.getLayer(Layers.ANIMATION_CONTROLS)

        self.transform = self.install()
        utils.lockAndHide(self.lockAttrs, True)
        connectControlColors(self.rigControls, self.mainColorAttr)
        self.updateSelectionSets()

        self.layer.addMembers(self._rigControls.values())

        self.containedNodes.append(self.transform)
        self.containedNodes.extend(self._rigControls.values())
        self.container.addNode(self.containedNodes)
        self.containerPublish(self.container)

        self.saveCreationParams()
        pm.parent(self.transform, self.mainControl)

    @property
    def rigControls(self):
        return self._rigControls.values()

    def verifyParams(self):
        if self.REQUIRES_SKELETON_CHAIN and not checkJointsAreHierarchy(self.joints):
            raise SkeletonError('The specified joints must be from the same skeletal chain')

        if len(self.joints) < self.MIN_JOINTS:
            raise SkeletonError('Only works with {0} joints!!'.format(self.MIN_JOINTS))

    def install(self):
        '''
        Main juice function
        Basic rig framework is created
        Return the top-most group node for __init__ method to utilize
        '''
        raise NotImplementedError("Derive me please")

This is a small snippet of the base class I designed all the rig components (known as “Substructs” in my code) to derive from. The BaseSubstruct class contains a set of parameters stored as members that most, or all, of my rigging structures (leg, arm, etc.) share. Using a OOP approach to creating the rig makes for a very scaleable solution for our pipeline. As new creatures are designed and implemented; I can plan out the automation right away, simply making a new class with most of the ground work derived from the original base class. Continue reading

Advertisements

Talking Games: Article Round-Up

Some nice articles I came across this past week.

Masterpiece: Final Fantasy VII

FFVII is filled with so many unforgettable, emotional scenes that it’s no wonder it still has such a large following. From the opening sequence and the bombing of the first Mako reactor to the final battle with Sephiroth, there’s a lot to take in.

Extra Credit!

“Substantial reward is very important to help motivate the player to push themselves to get better and try more difficult challenges. The difference between unlocking a new way to play the whole game or unlocking a digital badge, or hat for your character is quite large, but adding something as in depth as a new playable character also comes with its own set of difficulties”

Analysis: What the Video Game Industry Can Learn From the Death of Glam Metal

“During the heyday of spandex, excessive use of hairspray, and sing-a-long hair metal anthems, a tiny music scene called grunge managed to rise to greatness, as evidenced by Nirvana’s rise to the top of the music charts. The over-saturation of glam bands in the late eighties and early nineties is a perfect analogy for what’s happening to the gaming industry today.”

Talk Sport Street Fighter IV vs StarCraft 2

“There’s something distinctly feminine about choosing to get really good at a game. Unlike the very male experience of playing whatever, whenever, basically playing as much as you can get, basically waddling around the game shop with your trousers round your ankles, choosing to get good at a game requires commitment, or even devotion. More difficultly, it also requires that you choose a suitor.”

Talking Games: Must-Read Articles

Weekly round-up of articles I’ve read this week that I found most interesting. Some are critiques, others are design related, maybe even some conspiracy theory add-in. Tune in every week and see what pops up next!

Embedded videos of cartoons seen in Heavy Rain

I thought I saw Pyrats during my Heavy Rain playthrough, check out that and the other two animations!

Making Decisions Matter In Morality-Oriented Games

A analysis on the current design faults with games that use a morality systems.

What Virtual Worlds, Facebook And Fads Mean For The Game Industry

Opinion article comparing the current “social game” boom of new to the “virtual worlds” boom of old, plus how does social games impact the core game industry.

The Gears of Hype

“The gaming industry is not shy when it comes to hype. While it may feel, to avid followers of a particular game, that there is never enough media – there usually is.”

Game Over. Necessary Or Just a Nostalgic Relic?

Hard games can be fun and very immersive when done right. Do “Game Over” screens get in the way of fun?  With the progression of technology and proven designs showing how much more fun a game can be without this element, why do games continue to use ‘Game Over’?  The additional menus and loading times can take the player out of the experience and force them to quit prematurely. Maybe it’s time for them to go…

Continue reading

A couple old guides I wrote for GameFAQs

So nostalgic. Guilty Gear X2 is an awesome fighting game, one of the best even. The character designs were truly unique and the animation was superb. This game was my heart and soul before I ditched it for Third Strike, heh. There was even a point where I was so deep into the mechanics of the gameplay I wrote up a few guides on how to play a couple of characters. One was Venom, a very unique character who could create projectiles from pool balls for either offensive pressure or defensive zoning. The other was Axl Low, a long-range character with some awesome corner combos.

GGX2: Venom FAQ

GGX2: Axl Low FAQ

Dead to Rights Retribution Trailer

Been hiding for a few months, but I’m starting to roll out some new stuff. Check out this trailer for the upcoming Dead to Rights: Retribution. It features a few characters I helped skin for Volatile, notably the female in the diner and some of the baddies that get their arses handed to them. I wish I got to help out with the dog, Shadow. The game is looking really awesome and looks like people are getting excited!

Continue reading

E3: Impressions

I didn’t actually go to E3; I instead enjoyed it through gametrailers.com and word-of-mouth around the office. Arguably the best E3 since the reform, there was plenty of competition between the three consoles. After the jump, a quick summary of what I liked and disliked:

Continue reading

Incredible Hulk (the game) is out

Haven’t gotten a hold of my own copy yet, but this a title I done some nice maya rigs for last year. It won’t be until the movie is out when Massive Black and myself can show off some of the characters we’ve worked on.

I’ve heard moslty good things about it so congrats to Sega and Edge of Reality. The game looks great and I enjoyed contributing!