Organizing your code in a Mecanim-heavy project as it gets larger

As my project gets larger, I’m starting to get struck by analysis paralysis on how best to organize my code with respect to Mecanim.

My initial implementation was to have a “MecanimMotor” of sorts, with functions that handle all interactions with the controller, and then both player input scripts and NPC AI scripts could send messages to it. But as my controller grows more complex, I’m afraid my MecanimMotor is going to grow monstrously huge and unweildy, and difficult to maintain. Also, if I want to add a new character type that shares some mecanim-driven capabilities, but not all, with the previous, I’m not sure how best to handle it.

I thought about separating out individual mecanim-based actions into their own components, rather than maintaining everything in one big MecanimMotor script, but many actions depend on knowing the states of other actions and layers, to know whether or not they can fire (for instance, you shouldn’t be able to attack if you’re dodging). So each component would have to cache their own references to the Animator and the layer/state info that they care about, and that seems a little sloppy to me.

Any ideas?

Inheritance? Have your main class with the parts all of the characters use… its the base class. Next have a slightly more specialized class extend the base. You can make classes that extend the base or any part down the chain. If you have a class that’s quite different but still needs the base part… its all there if you inherit it. It’ll keep your files smaller and easier to maintain but keeps all the functionality of your monstrous file.

I’ve thought about it, but what if I have a more specialized class that doesn’t require all the parts of the base? Like, a character that can attack but can’t dodge. If the base class attack function checks the mecanim graph to make sure its not currently dodging, that knowledge is unnecessary and superfluous to this new subclass.

Move Dodge further down the chain till its only in the base of what needs it.

Okay, then lets say we throw blocking into the mix. There’s a character that can only attack, one that can attack and dodge, and one more that can attack, block, and dodge. Then what?

Hmm dunno buddy. Maybe do it and strip it out later:

public class Character : Monobehaviour
{
      public void Attack(){
          // I do stuff
      }
      public  void Dodge(){
         // I do Stuff
      }
      public void Block(){
           // I do Stuff
      }
}

public class AD : Character
{
      // I inherit Attack stuff   
   
      // I inherit Dodge Stuff

    // override block.... now no block 
      public override void Block(){
         
      }
}

public class AB : Character
{
      // I inherit Attack Stuff   

      // I inherit Block Stuff
   
      // blank dodge means I guess I can't dodge
      public override void Dodge(){
        
      }
}

public class ABD : Character
{
    
      public override void Attack(){
         base.Attack();   // I inherit Attack Stuff
         // can add more if I do more by over ride as well
      }

}

Inheritance was worth discussion, but composition is definitely the way to go. There’s nothing wrong with each component caching just what it needs (Animator, state info, etc.). It makes each component lean and purpose-driven, without carrying any extra baggage from inheritance.

You’re definitely doing the right thing by separating control from animation with an intermediate motor layer. That way, you can interchange AI and player control systems without having to touch the motor or animation layers.

You can subscribe to C# events to hook into functionality without components having to know the inner details of each other. For example, say you have a jump component. Later on, you add a character who always flips his cape dramatically behind his back whenever he jumps. The cape component could hook into the jump component’s OnJumped event to get notified when the character jumps and trigger the cape-flipping state. This requires no advance planning about cape-flipping in your jump component, leaving the jump component simple to write and maintain.

You can also use a blackboard as a shared space for components to exchange information while still remaining decoupled from each other.

I hope some of these ideas help. It’s an approach that’s worked very well for me.

Thanks Tony. I’m a big fat baby and that was just the encouragement I needed :slight_smile:

Yeah I admit somewhere I missed part of your initial post because yes in your case components would do great. On another note… is my code above the correct way to do things in the character situation you have above? I was just guessing how I’d handle it so was kinda hoping for some conformation or for someone better than I to tell me how wrong I was kinda thing… anyway glad you got yours figured out.

novashot, I’m certainly not going to claim to be better, but as a relative old-timer I’m happy to share my experiences through the pains of structured programming, then object-oriented design (inheritance, etc.), then component-based design. The idea behind your code would work, although I’d recommend making the base class abstract if you really went this way. But apart from the snags PrimeDerektive mentioned (e.g., what if you want to add functionality to a parent class without affecting a child class?), I see a public method as a contract. When you expose a method named “Attack()”, it’s a promise to the user that the character will attack when you invoke the method. It gets really confusing if you invoke Attack() but it doesn’t do anything. So, having gone through it myself, for this type of situation using a component-based approach just ends up being tidier and easier to expand.

Yeah, I’m also a fan of the component approach.

Keep in mind, though, that just because you’re using Unity and you want to do something with a component based architecture does not mean that they need to be Unity components. You can make your own internal components and a custom Inspector to make configuring them easy. (Whether that is a better or worse approach is up to you.)

Then what’s the different using the method shown by novashot with this ==> http://cardboardkeep.com/dev-blog-inheritance-in-unity-3d/

No difference. That blog entry is just a general overview of inheritance. novashot provided more details on using inheritance specifically for character animation.

I think it’s great that Calum Spring generously wrote a blog tutorial on inheritance for new Unity programmers. I disagree with this statement though:

First, in C# (which Spring uses), you can use interfaces to allow parents and children to co-exist as members of a single collection, without tying them up in inheritance dependencies.

Second, you can share functionality by re-using the same component on different objects, again without having the issues of inheritance.

Don’t get me wrong; inheritance is useful in the right place. For example, the Dialogue System decouples data from UI using a C# interface named IDialogueUI. But the built-in implementations of IDialogueUI for Unity GUI, DF-GUI, TK2D, etc., all derive from a base class named AbstractDialogueUI using inheritance. This allows it to inherit functionality common to all of the implementations. But if a user wants to implement their UI differently, they only need to implement the IDialogueUI interface. They don’t need to deal with the baggage provided in AbstractDialogueUI.

It all comes down to design choices, and I thought I’d share my experiences with the design choices I made.