Tutorial:Sims 3 Custom Animations

From SimsWiki
Revision as of 04:20, 22 August 2010 by Rothn (Talk | contribs)

Jump to: navigation, search

Contents

Introduction

This tutorial will cover the process of creating an object with a custom animation. This tutorial assumes that you have basic knowledge of object modding and cloning.

What You'll Need

Figuring Stuff Out Beforehand

In any part of this tutorial, if you see something wrapped in curly braces {}, substitute it with one of the values below. For example, in my case, {YourNamespace} would change to "rothn" (without the quotes).</h3> YourNamespace - This is the namespace that your object's script will use. I generally use my forum username (rothn). ObjectClass - This is the class that your object's script will use. There can't be multiple classes in the same namespace, so I generally choose a concise description of the object (e.g. AnimTutorial) ObjectClassHash - This is the Fnv64 hash of your ObjectClass. AnimName - This is the name of the specific animation that you will play (I used "a2o_test_x") AnimNameHash - This is the Fnv64 hash of your AnimName. SourceName - This is a name used for a group of animations (I used "a2o_test.ma")

Setting Up Your Environment

  1. Create a directory somewhere. You will use this in the development of the object.
  2. Choose an object to clone.
    • Note that if you select an object which doesn't already make use of animations, you will have to do an extra step later in this tutorial.
    • Put the package file of your new object in the aforementioned directory.
  3. Create a new CLR dll project in Visual C#.
    • Make sure that the Sims 3 DLL's you're using are the most recent and from the same version of TS3.
    • I will not go farther into this topic, as I assume that you are not new to making your own scripted objects.
  4. Create a new jazz script in Smooth Jazz.
  5. Open FullBuild0.package in "%ProgramFiles%\Electronic Arts\The Sims 3\GameData\Shared\Packages".
    1. Choose an animation (S3PE shows the tag CLIP for animations) to base your animation on.
    2. Right click on that animation, mouse over "Export", and click on "To File".
    3. Save the file in your object's directory.
  6. Extract "rigfile.txt" from "adult_bodies_4_anim_2010_02_19.rar" and put it in your object's directory.
  7. Extract all the contents of "AnimTool.rar" or "AnimTool-04a.rar" (whichever you downloaded), and put them in your object's directory.

Preparing Your Object

  1. Open the package file that you created in the previous section in S3PE.
  2. Select the OBJK resource and press "Edit OBJK".
  3. If it isn't checked, check the "Script" checkbox, and replace whatever existing text with "{YourNamespace}.{ObjectClass}" (e.g. "rothn.AnimTutorial")
  4. If the object you cloned is not animated (or if the boxes aren't checked), check the boxes labeled "Sacs", and "Animation".
  5. Create a new S3SA resource, where the instance is {ObjectClassHash}, the group is 0x00000000, and the name is descriptive of your object (e.g. AnimTutorial.dll).
  6. Enter your object's directory, right click on the animation that you exported from S3PE, and click rename.
  7. Change the file's name to "S3_6B20C4F3_00000000_{AnimNameHash}_{AnimName}%%+CLIP.animation".

Creating the C# Script

  1. Go to Visual C# and open up the project that you created in Setting Up Your Environment.
  2. If you know what you're doing, please look at the code sample below (which references a custom jazz script), and go to town. Otherwise, please scroll down to step 3.
  3. public bool DoAnimation(InteractionInstance interaction, Sim Actor)
            {
                interaction.StandardEntry();
                if (Actor.SimDescription.ChildOrAbove)
                {
                    interaction.AcquireStateMachine("animtutorialjazz");
                    //interaction.UseAutoParameters(new TraitNames[] { TraitNames.Clumsy, TraitNames.HotHeaded, TraitNames.Unlucky });
                    interaction.SetActor("x", Actor);
                    //interaction.SetActor("object", this);
                    interaction.EnterSim("Enter");
                    interaction.AnimateSim("OurAnim");
                    interaction.AnimateSim("Exit");
                }
                interaction.StandardExit();
    
                return true;
            }
    
  4. If you don't know what you're doing, or you don't want to bother with writing your own script, paste this code into Visual C#.
  5. using System;
    using System.Collections.Generic;
    using System.Text;
    using Sims3.Gameplay;
    using Sims3.Gameplay.Objects;
    using Sims3.Gameplay.Objects.Seating;
    using Sims3.Gameplay.Abstracts;
    using Sims3.Gameplay.Interfaces;
    using Sims3.Gameplay.Interactions;
    using Sims3.Gameplay.Actors;
    using Sims3.Gameplay.ActorSystems;
    using Sims3.Gameplay.Autonomy;
    using Sims3.SimIFace;
    using Sims3.SimIFace.CustomContent;
    using Sims3.UI;
    using Sims3.Gameplay.ObjectComponents;
    using Sims3.Metadata;
    using Sims3.SimIFace.Enums;
    using Sims3.Gameplay.Core;
    using Sims3.Gameplay.Objects.CookingObjects;
    
    
    namespace {YourNamespace}
    {
    
        public class {ObjectClass} : GameObject, IGameObject, IScriptObject, IScriptLogic, IHasScriptProxy, IObjectUI, IExportableContent
        {
            /*[Tunable, TunableComment("Range: Positive integers.  Description:  Maximum number of Sims that can wait in line.")]
            private static int kMaximumNumberOfSimsInLine = 0x3;
            [TunableComment("Range: Positive floats.  Description: Amount of Sim minutes a Sim will wait in line before timing out and exiting."), Tunable]
            public static float kTimeToWaitInLine = 15f;
            public SimQueue Line = new SimQueue(SimQueue.WaitLocation.HangAroundNearObject, kMaximumNumberOfSimsInLine);*/
    
            protected Sim mRevealingSim;
    
            public override void OnStartup()
            {
                base.AddInteraction(DoAnimation.Singleton);
            }
    
            public bool DoAnimation(InteractionInstance interaction, Sim Actor)
            {
                /*if (!this.Line.WaitForTurn(interaction, SimQueue.WaitBehavior.Default, ~(ExitReason.MidRoutePushRequested | ExitReason.ObjectStateChanged | ExitReason.PlayIdle | ExitReason.MaxSkillPointsReached), kTimeToWaitInLine))
                {
                    return false;
                }
                if (!Actor.RouteToSlotAndCheckInUse(this, Slots.Hash("Routing")))
                {
                    return false;
                }*/
                interaction.StandardEntry();
                if (Actor.SimDescription.ChildOrAbove)
                {
                    interaction.AcquireStateMachine("animtutorialjazz");
                    //interaction.UseAutoParameters(new TraitNames[] { TraitNames.Clumsy, TraitNames.HotHeaded, TraitNames.Unlucky });
                    interaction.SetActor("x", Actor);
                    //interaction.SetActor("object", this);
                    interaction.EnterSim("Enter");
                    interaction.AnimateSim("OurAnim");
                }
                return true;
            }
    
            public bool FinishAnimation(InteractionInstance interaction, Sim Actor)
            {
                if (Actor.SimDescription.ChildOrAbove)
                {
                    interaction.AnimateSim("Exit");
                }
                interaction.StandardExit();
                
                return true;
            }
    
            public class DoAnimation : Interaction<Sim, {ObjectClass}>
            {
                // Fields
                public static readonly InteractionDefinition Singleton = new Definition();
    
                // Methods
                protected override bool Run()
                {
                    //base.BeginCommodityUpdates();
                    base.Target.DoAnimation(this, base.Actor);
                    base.Target.FinishAnimation(this, base.Actor);
                   //base.EndCommodityUpdates(true);
                    return true;
                }
    
                // Nested Types
                private sealed class Definition : InteractionDefinition<Sim, {ObjectClass}, {ObjectClass}.DoAnimation>
                {
                    // Methods
                    protected override string GetInteractionName(Sim actor, {ObjectClass} target, InteractionObjectPair iop)
                    {
                        return "Do Animation";
                    }
    
                    protected override bool Test(Sim a, {ObjectClass} target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
                    {
                        return true;
                    }
    
                }
    
                [DoesntRequireTuning]
                private sealed class ForceDefinition : InteractionDefinition<Sim, {ObjectClass}, {ObjectClass}.DoAnimation>
                {
                    // Methods
                    protected override bool Test(Sim a, {ObjectClass} target, bool isAutonomous, ref GreyedOutTooltipCallback greyedOutTooltipCallback)
                    {
                        return true;
                    }
                }
            }
        }
    }
    
  6. Compile the dll, and put it in your object's folder.
  7. Switch to S3PE and select the S3SA resource that you created in Preparing Your Object.

Creating the Animation

  1. Open Wes Howe's AnimTool.
  2. Press the "Clip -> SMD" button.
  3. In the dialog box that comes up, select the .animation file that you renamed in Preparing Your Object.
  4. Now open up Milkshape 3D
  5. In Milkshape, import the SMD file that you just created with the AnimTool.
  6. Note that if you use bones that the animation you exported doesn't, then the animation will not display correctly ingame.
  7. When you are ready, export the animation from Milkshape 3D as a SMD file, taking care to use the same filename that you set in Preparing Your Object, but with the .smd extension rather than the .animation extension.
  8. Go back to Wes Howe's AnimTool.
  9. In the textbox labeled "Anim Name", type {AnimName}.
  10. In the textbox labeled "Source Name", type {SourceName}.
  11. Now, press SMD -> Clip.
  12. In the dialog box that comes up, select the .smd file that you exported in Milkshape 3D.
  13. Since the only difference between the filenames of the .smd file and the .animation file is the extension, the AnimTool will add a .bak00 extension to the original animation file, and your new .animation file will have the name of the original.
  14. Now, switch back to S3PE, and click "Resource" in the toolbar, mouse over "Import", and click "From file...".
  15. Select the .animation file and click OK in the dialog box that appears.

Creating the Jazz Script

  1. Close all instances of S3PE.
  2. In Smooth Jazz, click "Tools", and then "Options".
  3. Press "Add", navigate to your object's directory, and double click your object's package file.
  4. Press "OK".
  5. In the new jazz script that you created in Smooth Jazz in Setting Up Your Environment, enter the following code.
  6. State Machine "animtutorialjazz"
    {
        Actor "x"
        Assign Actor "{SourceName}"."x" as "x"
        State "Enter"
        {
            Properties Public, Entry, Explicit
            Transitions to "OurAnim"
        }
        State "OurAnim"
        {
            Transitions to "Exit"
            Play "{AnimName}"
        }
        State "Exit"
        {
            Properties Public, Exit, Explicit
        }
    }
    
  7. Now, press "File", and click "Package All Into..."
  8. If there are any other state machines than "animtutorialjazz" that show up in the export dialog, uncheck the checkboxes next to them.
  9. Click "Export".

Finishing Up

  • Please test your object, and PM me (rothn) at ModTheSims if you have any questions or if your object's animation will not play.
  • Note that WesHowe does impose certain limits on the use of his AnimTool. If the Clip file that you try to copy is too big, his AnimTool won't take it. I know, I hate it too, please do PM Wes (also at MTS) so that he releases a version for those of us with top-of-the-line systems (and no frame limits).
Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox