Replies: 3 (Who?), Viewed: 958 times.
Virtual gardener
staff: administrator
Original Poster
#1 Old 9th May 2020 at 5:43 PM Last edited by Lyralei : 10th May 2020 at 6:37 PM. Reason: fixing brackets
Default [TUTORIAL] Jazz scripts - Adding animations to your objects (FINISHED)
Hi everyone!

Jazz scripts, as modders we've all heard of them. I was one of those modders who avoided those like the plague, but once I was working on my sewing table I had no other choice than working with them. Once I did start working on them, they were actually quite easy to do! Problem is, is that other Jazz script tutorials (as amazing and helpful as they are!) are incredibly advanced in the information they share. Modders who know a bit about animating and a little bit of scripting will have issues understanding them because of it. So I really hope that this tutorial will fix any confusion you have about jazz scripts!

What we want to achieve at the end of this tutorial:
  • A basic code setup that you can easily copy/paste into your Run().
  • A basic Jazz script setup that you can always use and copy
  • Understanding the basics of working with jazz scripts and how to link those to your C# script.
  • A basic understanding of how props, CLIP files and actors are read by the game.
What this tutorial won't teach:What you need:Let's get started!

The C# part

Let's open up our Visual studio/SharpDevelop/etc. If you've followed the Sims 3 Object modding tutorial, you should have something like this:



If not, feel free to copy this :D

With Jazz scripts, I always like to imagine in words, what exactly I want. In this case, we want the following:
  • I want to first let the game know which object and/or sim I want to animate
  • I then want it to start running
  • Then, after the animation is done playing, I want the animation to stop playing. As well as my sim to stop using it
Pretty straightforward stuff, right? Now, if you're working on something intenser than just animating a tissue box and a sim, this is definitely a great thing to write down in your 'run()' function (Well, as long as you use the commenting syntaxes )


Getting acquainted with the tools/code we can use:

You might have seen EA's run functions on objects that has a lot of animation and code that has all sorts of checks. But in reality it's quite easy stuff if you strip out the checks and logistics of those. Let's get over all the regularly used functions for initiating an animation:

base.StandardEntry();
Tells the game that the object and interaction will currently be used and setting up the 'LookAt' function. (unless, you turned this off by using the moviemakercheatsenabled cheat. The code will still run though!)

base.EnterStateMachine("TissueBoxAnim", "Enter", "x");
Takes 3 parameters:
1. "TissueBoxAnim" - is the name of the statemachine (jazz script).
2. "Enter" - is the name of the 'enter state'.
3. "x" - is your sim (also known as the actor). 
4. base.EnterStateMachine() - Enter state machine is the part where the game searches for your jazz script and goes right to the "enter" function in our Jazz script. More on that later of course 

NOTE:
1. 
You can name the statemachine ('tissueBoxAnim') anything you like it to be! We'll be using this name later in our Jazz script.
2. Always use 'x' in this piece of code. "x"
3. COPY PASTE YOUR ENTER STATE MACHINE FUNCTION IN NOTEPAD!! This is merely so that we can look back at it once we get to the jazz script.

// OBJECT:
base.SetActor("TissueBox_object", base.Target);
Takes 2 parameters:
1. "TissueBox_object" is the name I'm giving my object. Later on, we'll reference the object in the Jazz script this way. 
2. base.Target - here is where the C# script and the Jazz script work together and figure out who we mean as "TissueBox_object". See it like this: You know someone's name, but once you point at the person, you know who they are and what they look like!
3. base.SetActor(); - This function is, as I said before, a way for the C# script and Jazz script to work together. To visualise who this name belongs to  And, it initiates the actors as well as checking if the actors even exist!

NOTE:
1. "Why does it think my object is an actor?". Basically, see it as 'who needs to move/animate?'. After you know, you also know that they need to become an actor. Despite being human or not. 
2. Adding a second object to be an actor, you'd do like this:

Code:
//GET OBJD KEY TO CREATE A GAMEOBJECT
mFabric = (SewingTable_ClothProp)GlobalFunctions.CreateObject(ResourceKey.FromString("0x319E4F1D:0x00000000:0x0361BDCA336A8546"), slotPosition, 0, forwardOfSlot, null, null);
// CHECK IF OBJD KEY WAS FOUND AND OBJECT EXISTS
if(mFabric != null)
{
       base.SetActor("fabric", mFabric); // See how we call it "fabric" and then point at the variable? This is super important!
}
base.EnterState("x", "Enter");
Takes 2 parameters:
"x" - is what we told it being the sim actor (See EnterStateMachine()); 
"Enter" - Is, again, the name of the 'enter state'. However now it's interesting since it will look and run this function. Base.EnterStateMachine(), however just checks if there's an enter state
base.EnterState(); - Runs the 'Enter' Script inside of the Jazz code. It also runs this code on the "x" actor (our sim!) We'll get over this in a bit once we get to the jazz scripts!

base.AnimateSim("Exit");
Takes one parameter:
"Exit" - This is the name of our 'exit state'. We remember the enter state, which enters the animation. in this case, we exit the animation.
base.AnimateSim(""); - The function is actually a simplified "enterState()" function. It will always focus on the "x" actor. So all we say here is "hey look at the Exit function inside the jazz script!" This of course only works with sims. 

//ONLY IF YOU HAVE A SUPER COMPLEX ANIMATION GOING ON, USE THIS:
base.RequestState("TissueBox_object", "DoASpinWooh!");
Takes 2 parameters:
"TissueBox_object" - Our tissuebox actor  See the "SetActor()" function for clarification.
 "DoASpinWooh!" - The state name of the function inside the jazz script! I just called it DoASpinWooh, in case anyone wants it to do something awesome  But this could well just be "Exit" or "Enter" though.
base.RequestState() - Runs the animation 'state' (DoASpinWooh in this case) And applies it on the, in this case, TissueBox_object actor!  It really is just a less simplified version of the function base.AnimateSim.

//ONLY USE THIS IF YOU GOT SKILL OR TRAIT STUFF GOING ON
base.BeginCommodityUpdates();
As far as my research has gone, this helps the traits and skills being recognised  (And I think buffs too?)

base.StandardExit();
Stops the Jazz script and makes sure that the game knows that this sim isn't animating anymore. You need to always end your animation this way! This is what will happen if you don't is this:
Quote:
Originally Posted by Zoe22
Another thing that happened (though I couldn't recreate this, so maybe it's not really a bug, and more just a sim moment) was when my sim stopped sewing to go prepare some food, she was walking to the fridge and got stuck doing the animation, and so then would walk a little bit, sew in the air, walk a bit etc...
(See this thread for image illustration: http://www.modthesims.info/showthre...716#post5635716)

A BASIC WORKING SCRIPT YOU CAN USE:
But there's actually a 'basic' setup you can use on everything, or just use to start out with, which is:

Code:
base.StandardEntry();
base.EnterStateMachine("NameOfStateMachine", "Enter", "x");
base.SetActor("NameOfActor", base.Target);
base.EnterState("x", "Enter");
base.AnimateSim("Exit");
base.StandardExit();

This example is really all you need ever. I'll add some edge cases at the end of this post (Think about Loops, skilling, etc)

Our script should look like this now:



This is literally all the code we need!  

EDGE CASES & EXIT REASONS - EXAMPLES
Now that we know what EA's Animation functions do and why they're there! We can finally get to bits where we'd want to loop our animation or even add skilling to our code. Only in these cases do we really need Exit Reasons, since most animations run for 10 seconds at most I'll use my Sewing table code as an example, with an EA skill. 

LOOPING BASICS - EXITS ONLY WHEN SIM IS IN A BAD MOOD/PLAYER DIRECTED CANCEL




LOOPING WITH A SKILL:




LOOPING WITH A PROGRESS GOING ON:



(Coming soon the JAZZ script)
2 users say thanks for this. (Who?)
Advertisement
Virtual gardener
staff: administrator
Original Poster
#2 Old 9th May 2020 at 5:44 PM Last edited by Lyralei : 10th May 2020 at 5:37 PM.
Default The jazz script - part 2
The jazz script!

(If you don't have an animation/CLIP file yet, see using the pose Blender plugin stuff with objects, 4th post)

Let's get to the even more unknown bits of jazz scripts! So, as it stands, you've got your notepad with copied values, right? Mine looks like this:

Code:
base.EnterStateMachine("TissueBoxAnim", "Enter", "x");
base.SetActor("TissueBox_object", base.Target);
The reason for this being important is because we need to be precise here when doing jazz scripts. A spelling mistake, capitals where they shouldn't be, etc can break the Jazz script horribly!

Let's get into SmoothJazz!
1. Open the SmoothJazz I asked you to download. Make sure that yours is not the one you got off MTS. That one won't work with the current patch version for the game, the simology one I linked does, however! (learned this the hard way :p)
2. Go to File > New

Now you should be able to type!  All you need to do now is copy-paste this and change it to your namings:

Code:
State Machine "StateMachineNameHere"
{
    Properties Default
    Actor "x"
    Actor "SecondActorHere"
    Assign Actor "CLIPNameHere.ma"."x" as "x"
    Assign Actor "CLIPNameHere.ma"."SecondActorHere" as "SecondActorHere"

    State "YourCustomStateName"
    {
        Transitions to "Exit"
        Play "CLIPNameHere" for "x"
        Play "CLIPNameHere" for "SecondActorHere" //OPTIONAL!!
    }
    State "Enter"
    {
        Properties Public, Entry, Explicit
        Transitions to "YourCustomStateName"
    }
    State "Exit"
    {
        Properties Public, Exit, Explicit
    }
}
For a simple Jazz script, this is literally all you need! If you're looking for the loop stuff, see the bottom of this post

What is what?
  • State Machine "StateMachineNameHere" : Here we want to add "TissueBoxAnim". See how in my base.EnterStateMachine("TissueBoxAnim", "Enter", "x"); I have 'TissueBoxAnim'? That's the State machine name! 
  • Actor "X" : Because in our base.EnterStateMachine("TissueBoxAnim", "Enter", "x"); in the C# script, we assigned an "x" at the end (Aka the sim! ), We always start with this one. 
  • Actor "SecondActorHere" : Remember this line in our C# script: base.SetActor("TissueBox_object", base.Target);? TissueBox_object is our second actor! Which means we now have: Actor "TissueBox_object"
NOTE ABOUT ACTORS: You can add as many actors to the list as you want! As long as it meets up with the 'SetActor' function in your C#  
  • Assign Actor "CLIPNameHere.ma"."x" as "x" : Here we assign our CLIPname to the actor that belongs to it  The CLIPname of the animation I made for my sim is "a_spinning_sim". The first 'x' means the in-file(CLIP) name of the actor, the 'as x' is our jazz script actor's name
  • Assign Actor "CLIPNameHere.ma"."SecondActorHere" as "SecondActorHere": Same as the 'x', but in my case this will become Assign Actor "o_spinning_object.ma"."TissueBox_object" as "TissueBox_object"
  • Play: Now we actually put in our proper Clipname WITHOUT the .ma!! so, "o_spinning_object" for example  Then, we assign which actor it's meant for. 
NOTE ABOUT ASSIGN CLIPS TO ACTORS:
Because CLIP files are basically an archive, the actual file *inside* of a CLIP file always has YourCLIPName.ma rather than just 'YourClipName'. 
 IMPORTANT:
You ALWAYS need a "State "Exit" And "State "Enter"! Without these, the C#, as well as the Jazz script, will break! You ESPECIALLY need the 'properties', just so that the jazz script won't catch fire. You also ALWAYS should have a custom third state that will run the animation for you during that state, hence why it's included in the reference!  Those are the minimum requirements of course. If you want to add 5 more custom states, go for it!

State Enter and State Exit are also part of the "base.StandardEntry()" and "base.StandardExit()" function inside our C# code. So this really needs to be included. 

What my code looks like now:

Code:
State Machine "TissueBoxAnim"
{
    Properties Default
    Actor "x"
    Actor "TissueBox_object"
    Assign Actor "a_spinning_sim.ma"."x" as "x"
    Assign Actor "o_spinning_object.ma"."TissueBox_object" as "TissueBox_object"

    State "DoingASpin"
    {
        Transitions to "Exit"
        Play "a_spinning_sim" for "x"
        Play "o_spinning_object" for "TissueBox_object"
    }
    State "Enter"
    {
        Properties Public, Entry, Explicit
        Transitions to "DoingASpin"
    }
    State "Exit"
    {
        Properties Public, Exit, Explicit
    }
}
Save!:
I usually do this in 2 steps:

1. File > Save.
2. Give it any name. I'll call mine 'TissueboxJazz'
3. File > Package into
4. keep the naming that SmoothJazz gives you.
5. Save into a folder you can find back :p We'll put the jazz stuff in later (See S3PE stuff).

"I got a "Parser doesn't recognise literal" error, what do I do?" 
SmoothJazz seems to have a hate for spaces. So ALWAYS use tab. To fix this here's an easy picture tutorial to see what you can try:



If you're experiencing any other errors, do let me know in the comments! 

An Illustration of what links to what:



Somewhat more advanced stuff for SmoothJazz:
http://www.simlogical.com/ContentUp...e/uploads/1240/

Some edge cases:

LOOPING WITH JUST ONE STATE/ANIMATION - JAZZ SCRIPT:
Looping can actually well be done with only one state.
NOTE: Make sure that in your C# Script you have a "base.AnimateSim("Loop");", Else it won't reach the Loop state in the Jazz script ever!



LOOPING WITH JUST MULTIPLE STATES/ANIMATION - JAZZ SCRIPT:
Here's an example with how I did it for my Sewing table

NOTE: Make sure that in your C# Script you have a "base.AnimateSim("Loop");", Else it won't reach the Loop state in the Jazz script ever!

Screenshots
Virtual gardener
staff: administrator
Original Poster
#3 Old 9th May 2020 at 5:44 PM Last edited by Lyralei : 10th May 2020 at 6:02 PM.
Default S3PE setting everything up
Let's set everything up with S3PE!

1. Open up the object package you cloned for this tutorial. IN my case that's the TissueBox package
2. Go to Resources > Import > From package
3. Go to the folder you saved the Jazz package with SmoothJazz. In my case it's called 'TissueBoxAnim.jazz.tigerjazz'
4, Import and voila! You should now see a JAZZ entry in your S3PE!

The preview here is important. If it gives an "error cannot read resource' error, then it might just be that you have the wrong smoothjazz version.


If it looks like the picture above, then you did it!

5. Import your CLIP files! (If unsure how to do this, go to: https://www.youtube.com/watch?v=LGK...6Rxm-KT&index=3 )
6. Resource > Add 
7. Type will be your S3SA, Group 0x0, Instance I just put this in the name input field: Sims3.Gameplay.Objects.Lyralei.MovingTissues and pressed FNV64. 
8. Click ok!
9. Right click the OBJK resource > Edit OBJK
10. In the script field, put in your C# script namespace + the class. In my case it will be: Sims3.Gameplay.Objects.Lyralei.MovingTissues
11. Save! And Then Save the package!
12. Done! Lets play it in-game!



This is what mine does! So hopefully yours works too! (It surprisingly loops well as a gif lol)
Screenshots
Virtual gardener
staff: administrator
Original Poster
#4 Old 9th May 2020 at 5:45 PM Last edited by Lyralei : 10th May 2020 at 6:35 PM.
Default EXTRA Animating objects with Clip Tool
Wanna make a dancing teddy like this one? (Yes, this is actually the in-game teddy bear! No, it's not up for download :/)




Then you're at the right address!

Animating objects is actually incredibly easy! It's just that we have to don't have any tutorials out there who tell us how its done. So i'm changing that here and right now! :p

What you need:
- Blender
- Cliptool: https://sims3cliptool.wordpress.com/download/
- Any cloned object's package. I'll be using the teddy bear, which I cloned with S3OC

Let's get started!

1. Open blender
2. Delete the infamous cube :p
3. Go to Scene > Load prop



4. Select the cloned package object you extracted. For me that's the teddy



Hopefully now you should see your own object!



5. Get into pose mode. Make sure you're selecting the rig and not the teddy mesh! This can be a tricky one, but you can do it!



6. Click on the button next to default and select 'animation'



7. OPTIONAL but for any looping animation it's always good to use the shortcut  'i' > LocRotScale.



8. Let's start animating!



9. When saving a second 'keyframe', or in this case, section of the animation you're working on, make sure you have the GREEN line thingy with 101 underneath it (for me that is, for you it's probably something else) is away from the yellow dots. Else you will override your previous one! Or just make a static pose! After that, you can do the shortcut i > LocRotScale



10. You should have something like this now! See how the yellow dots are apart from each other? if you play your animation now, the teddy will move



11. Time to export! Go to File > Export > Sims 3 Animation



12. For object animations ALWAYS start with o_ Else the game won't recognise it!!



Save your animation and voila!



End result:



NOTE: Unfortunately pose player can't actually run animations on objects, unlike sims. However, if you follow my Jazz script tutorial, it should be relatively easy to set up animations for objects  hopefully this helped!

"But what about objects that are decoratives, etc?" 

They actually have bones! But they have one of the sphere thingies. In that case, use those  All objects that are decoratives and don't actually have a rig like the teddy bear has one.
Back to top