Sign in to follow this  

Animation System

This topic is 3317 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I'm currently working on a 2D animation system (C#/SlimDX). I've got things set up so it's used like so:
// Inside "Skeleton.cs", to be loaded from an XML file but for now just part of the default rig.
mRoot.Joint("RightShoulder").Attach(new Bone("UpperArm"));
mRoot.Joint("RightShoulder").Bone("UpperArm").Attach(new Joint("Elbow", new Vector3(0.07f, 0.05f, 0), 45f));
So I can set up skeletons like so, and everything renders properly. The problem is I would like to disallow access to the Position & Rotation properties except within the library by using the internal keyword and strictly provide animation to skeletons through an interface (IAnimation). However, since the user will need to inherit from IAnimation in a different assembly, it will not be able to access either the Position or Rotation of the bones/joints its trying to work on. So far I can think of 3 solutions: 1) Screw marking the properties as internal. This means that users of the library won't be restricted to inheriting from IAnimation to provide animation. I don't like this since it could make things messy if they have bones moving all over the jiff (Code-wise, not animation-wise). Plus it just wouldn't be as cool :). 2) Have Skeleton.Update() accept an array of XML files describing different active animations. I don't like this however as it would be a lot of work (I think) and possibly not as customizable as being able to describe an animation through code. 3) Provide something like a AnimationSkeleton to the user for use within classes which implement IAnimation, then within Skeleton.Update(IAnimation[] a) just do something like:
for each matching Bone/Joint in (Skeleton)this and a.AnimationSkeleton
    { this.Bone.Position += a.AnimationSkeleton.Bone.Position; }
// Note: It's += so multiple animation will sort of blend together.
But thats just silly, isn't it? Anyway, does anyone have any solutions, recommendations or insights into this problem :)? I have a feeling the C++ friend keyword would come in handy here, but I'm not sure. Either way C# doesn't have it so :'(. Thanks!

Share this post


Link to post
Share on other sites
solution 1. An animation system is ultimately used to lerp a bunch of rotations and positions, and usually without exception you really will want to access those values in your game code. I see no reason why

float Rot = mRoot.Joint("RightShoulder").Bone("UpperArm").Rotation;
Vector3 Pos = mRoot.Joint("RightShoulder").Bone("UpperArm").Position;


should ever be disallowed..... I'd make them public tbh.

Share this post


Link to post
Share on other sites
Yeah, 1 is the solution I went with. Especially since I'm really the only one using the library I'll just enforce myself to not abuse it.

I was mostly just wondering if there was any way to allow access to Position & Rotation only within a class which implements IAnimation, to keep things clean. Looks like there isn't though :(.

Whose up for a new keyword in C# just for that eh?

limited<IAnimation> Vector3 Position { get; set; }


[grin].

Share this post


Link to post
Share on other sites
I second what RobTheBloke said: There is no need to restrict the access for a single (base) class. The skeleton is a complex but nevertheless state variable. It should play no role how and what clients work on the state as long as the state consistency is ensured. I.e. it should not be possible to violate constraints, but that cannot be reached simply by restricting access for a single base class.

I don't know C#. Normally I'd say that if you want to ensure consistency, you can introduce public const getters and public setters, the latter giving the possibility to check and perhaps correct the state.

Share this post


Link to post
Share on other sites
Quote:
Original post by haegarr
Normally I'd say that if you want to ensure consistency, you can introduce public const getters and public setters, the latter giving the possibility to check and perhaps correct the state.


It's not that I want to ensure constraints and the like are kept (Infact, since it's only a simple animation system I'm not going to worry about restraints at all). It's that I would like to ensure users don't fall into a crazy mess like this:


// Somewhere in Actor.cs
Skeleton.*Rotate & Position arms to face bad guy*

// Somewhere in Main.cs
someActor.Skeleton.*rotate head to look at something*;

// Somewhere in Weapon.cs
*Animate the actor's skeleton holding the weapons arms to look like its reloading the weapon*

// Somewhere in etc.cs
*Animate the actor to do something else*



Instead, if they were forced to do things only through IAnimation, it would look more like this:


// In Actor.cs
mAnimationList.Add(new AnimationRunning()); // A custom running animation which moves hands and feet
mAnimationList.Add(new AnimationAim(someVector)); // Custom animation which aims skeleton at a given vector.
mAnimationList.Add(new AnimationReload()); // You know it :).

mSkeleton.Animate(mAnimationList);



The first scenario I posted is of course a very unlikely one (You'd have to be crazy to have your animation code all over the jiff like that) but it could happen to someone who's not so good with OO design. Then again, now that I read my wording as "Forced", I guess it would be better just to "Encourage" users to do it the IAnimation way, and only modify it outside if absolutely necessary (But we all know people can be lazy [smile]).

Share this post


Link to post
Share on other sites
Quote:
Original post by Kobalt64
The first scenario I posted is of course a very unlikely one


Correction. It's *very* likely!

Quote:
Original post by Kobalt64(You'd have to be crazy to have your animation code all over the jiff like that) but it could happen to someone who's not so good with OO design.


But until you've designed and built an animation system into a game, you won't know the best way to encapsulate the functionality behind and interface. It's a bit like having a PlaySound() function. It's simple to use, easy to understand, and why would anyone want anything more complex?

Well, modifying the pan, pitch, volume as well as applying DSP effects are very soon likely to become requirements, and then you'll quickly realise that the simplified interface is probably not enough. The exact same thing is also true of an animation system.

Quote:
Original post by Kobalt64Instead, if they were forced to do things only through IAnimation, it would look more like this:


Which looks far too restrictive to be of much use (if any) in a typical game scenario. The code you posted as an example of what you are trying to avoid, is in actual fact closer to the ideal animation interface than you think. Animation code has a habit of generally being a bit messy (and that's ok), but it has to be open to be able to usefully integrate it with other systems within your game engine, eg

- particle and sound engines to emit dust and footstep sounds when the feet touch the ground
- the user input system that aim's the characters gun
- the collision system so that it knows where the limbs are
- the physics engine to integrate ragdoll physics

The list goes on and on. Sure you can do a number of things to improve encapsulation within the animation system, but I'd recommend refactoring in that encapsulation at a later date when you have a working game. The results will be far better if you attempt it that way.

Share this post


Link to post
Share on other sites

This topic is 3317 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this