- Modifié
Some advice [Unity]
Hi friends,
I just purchased this amazing tool Spine Pro, to use'it in my Unity Project. I have some questions:
What is the best way to use animations from Spine into Unity, default Spine Skeleton or Unity baked mecanim ? I prefer second one because it's more easy for me being a beginner in C# and have a lot of practice with Unity Mecanim.
I noticed that Spine Skeleton gets 5 batches with spineboy, instead 20 with baked one, this mean that baked is more performance cost ?
If I will use the unity baked animation, I will be able to use features like skins, ghosting etc. ?
I’d really appreciated all the advice I will get from you guys, thanks in advance !
Cheers,
- Modifié
Spine-Unity with Mecanim will always be a little crippled.
Using SkeletonAnimation (Spine with Spine-Unity + Spine-C#) has all the features but no Mecanim integration and, because of that, involves some working from scratch.
Using SkeletonAnimator (Spine with UnityEngine.AnimationState as the Animation State Machine) has some problems but is mostly okay, and you can use Mecanim features like blendtrees. Personally, I don't like to use it. Mecanim is for 3D or full-skeletal setups and has problems I don't like to deal with, mostly because the way I animate isn't full-skeletal so I don't get much of a benefit from using it anyway.
But if you want to use Mecanim, this is probably what you want. And if you're comfortable with it, you can use it to save you tons of time implementing an animation controller. But expect things to work a bit weirdly compared to regular Mecanim. Spine with Mecanim uses dummy AnimationClip assets, it currently uses the SendMessage system for callbacks but will soon work via the more reliable C# events (watch out for that update). Spine-Unity acts a bit weird either way, because it's built on a generic Spine-C# runtime.
Feel free to post questions if you don't understand something about Spine interacting with Mecanim. Mitch or the other users can answer them for you. And make sure you watch the tutorial video for SkeletonAnimator.
Using Baking (converting Spine data into Spine-runtime-independent Unity animation assets) lacks a lot of features: animated colors, skins, FFD, reliable C# event handling, Start/End/Complete callbacks... etc. Anything native Unity animations can't do, it can't do.
Baking was NEVER meant to be used if you want to use Spine properly. In fact, unless it's for a ridiculously hyper-simplistic animation, don't use it at all. I begin to wonder if it should be ripped out of the runtime and move it to Examples or a separate package 'cause people keep trying to use it and expecting it to work.
Thanks Pharan :handshake: for your quick reply, I will try to get work directly with Spine Skeleton into Unity, but I find it somehow difficultly maybe because I'm a beginner with Spine API...right now I'm trying to make a custom player controller script from scratch for the Spineboy example (for testing purposes), what I find most difficult and unclear is the transitions for animations. What I did so far is my character have 3 animation states (idle, run & jump), I can't achieve "jump" animation for example when the character run's or staying idle logic: idle->jump->idle or running->jump->running.
Let's say this is my biggest issue, I tried and tested example scenes but not entirely understood the process
My C# script (translated for easier understanding)
using UnityEngine;
using System.Collections;
namespace Dorin
{
public class ControlCaracter : MonoBehaviour
{
//REFERINTE PUBLICE
[Header("PARAMETRI DE BAZA")]
public float runSpeed = 10f;
public float jumpPower = 100;
public SkeletonAnimation scheletAnimatie;
public bool autoRun = false;
public LayerMask collisionLayer;
public bool onGround;
[HideInInspector]
public Vector2 bottomPosition = Vector2.zero;
public float colRay = 10f;
//REFERINTE PRIVATE
Rigidbody2D 2dBody;
float x; //Referinta axa orizontala
float y; //Referinta axa verticala
bool doubleJump = false;
float holdTime = 0f;
string curAnimation;
void Awake()
{
2dBody = GetComponent<Rigidbody2D>();
}
void Update()
{
//AUTO RUN
if (autoRun)
{
x = 1 * runSpeed;
if (x >= 20f)
SeteazaAnimatia("run", true);
else if(x <= 18f)
SeteazaAnimatia("walk", true);
}
//MANUAL CONTROL
else if (!autoRun)
{
bool canJump = Input.GetButtonUp("Jump");
bool canFire = Input.GetButtonDown("Fire1");
x = Input.GetAxis("Horizontal") * runSpeed;
//y = Input.GetAxis("Vertical") * jumpPower;
if (x == 0 && onGround)
{
SeteazaAnimatia("idle", true);
}
if (x >= 18 && onGround)
{
SeteazaAnimatia("run", true);
}
if (onGround && canJump)
{
Salt();
holdTime = Time.time;
Debug.Log("Timp apasata: " + holdTime.ToString());
}
else {
canJump = false;
}
if (canFire)
{
Fire();
}
}
holdTime = 0f;
}
void FixedUpdate()
{
var pos = bottomPosition;
pos.x += transform.position.x;
pos.y += transform.position.y;
onGround = Physics2D.OverlapCircle(pos, colRay, collisionLayer);
2dBody.velocity = new Vector2(x, 2dBody.velocity.y);
}
void SeteazaAnimatia(string animationName, bool loop)
{
if (animationName == curAnimation)
return;
scheletAnimatie.state.SetAnimation(0, animationName, loop);
curAnimation = animationName;
Debug.Log("Animatie curenta:" + animationName.ToString());
}
//JUMP****************************************************
public void Salt()
{
var characterSpeed = 2dBody.velocity;
2dBody.velocity = new Vector2(characterSpeed.x, jumpPower);
SeteazaAnimatia("jump", false);
}
//FIRE****************************************************
public void Fire()
{
SeteazaAnimatia("shoot", true);
2dBody.velocity = new Vector2(2dBody.velocity.x, 2dBody.velocity.y);
}
//DEBUG***********************************************************
void OnDrawGizmos()
{
Gizmos.color = Color.red;
var pos = bottomPosition;
pos.x = transform.position.x;
pos.y = transform.position.y;
Gizmos.DrawWireSphere(pos, colRay);
}
}
}
I'll be publishing some for-sale robust Unity character controllers built around the Spine runtime bundled with Spine project sources really really soon. Just a heads up
I'm working on a text-based Animation Graph right now that drives a SpineSkeleton if that sounds interesting to you.
It's very programming heavy right now, but I already have it working in my game engine and it lets me do things like combo chains, pause one animation to play another then resume, contextual adaptation between 20% and 80% of an animation, etc... but it doesn't do Blend Trees well. Here's a preview if you're interested.
Some Vocab:
Branch = a thing that decides to move from one Stance to Another
Stance = basically a Mechanim State with extra properties
Signal = a message passed to the BranchProcessingMachine
List<Stance> StanceList = new List<Stance>()
{
// Ground Movement
new Stance { Name = "Idle", Animation = "Idle", Looping = true, BundleNames = {"Ground Common", "Ground Common - Echelon Only"}, },
new Stance { Name = "Idle Look Up", Animation = "Idle Look Up", Looping = true, BundleNames = {"Ground Common", "Ground Common - Echelon Only"}, },
new Stance { Name = "Run Forward", Animation = "Run Forward", Looping = true, BundleNames = {"Ground Common", "Ground Common - Echelon Only"}, },
new Stance { Name = "Run Backward", Animation = "Run Backward", Looping = true, BundleNames = {"Ground Common", "Ground Common - Echelon Only"}, },
}
Stances are connected to each other by branches like these. The really cool thing here is that you can just any code you want inside the Condition of a branch to allow it to trigger.
// Stance:Branch Map
Dictionary<string, List<Branch> > StanceBranches = new Dictionary<string, List<Branch> > ()
{
{
"Idle",
new List<Branch>()
{
new Branch {
Condition = context => { return context.Units["Source"].Unit[PS.InputUpward] > 0.5f; },
NextStance = "Idle Look Up",
},
// + Ground Common
}
},
{
"Idle Look Up",
new List<Branch>()
{
new Branch {
Condition = context => { return context.Units["Source"].Unit[PS.InputUpward] < 0.5f; },
NextStance = "Idle",
},
// + Ground Common
}
},
{
"Run Forward",
new List<Branch>()
{
new Branch {
Condition = context => { return context.Units["Source"].Unit[PS.InputForward] < 0.1f; },
NextStance = "Idle",
},
// + Ground Common
}
},
{
"Run Backward",
new List<Branch>()
{
new Branch {
Condition = context => { return context.Units["Source"].Unit[PS.InputForward] > -0.1f; },
NextStance = "Idle",
},
// + Ground Common
}
},
Some branches have "Actions" (Func<MyArg, bool>) which are called when that branch is taken by the machine.
{
"Ground Common - Echelon Only",
new BranchBundle()
{
Name = "Ground Common - Echelon Only",
Branches = new List<Branch>()
{
new Branch {
Signal = Signal.DoJump,
Condition = context => { return context.Units["Source"].Unit[PS.Grounded]; },
Action = DoSparkJump,
NextStance = "Jump Start",
},
new Branch {
Signal = Signal.DoDash,
Condition = context => { return ( Time.time >= fLastDash + DashCooldown ); },
Action = Dash,
NextStance = "Blink Out",
},
}
}
},
And finally, some branches have "automatic" transitions:
// Air Stuff
{
"Jump Start",
new List<Branch>()
{
new Branch {
On = 1.0f,
NextStance = "Jump Upward",
},
new Branch {
Condition = context => {
var src = context.Units["Source"];
return Mathf.Sign(src.Unit.GetCurrentVelocity().y) != src.Unit.GetUpwardDirection() ;
},
NextStance = "Jump Falling",
},
// + Air Common
// + Air Common - Echelon Only
}
},
In this case, as soon at the jump start animation stops running, it begins the "Jump Upward" looping animation... or if for some reason a monster pushes you down, it cancels the "Jump Upwards" animation right away and beings playing a "Fall" animation.
The technique driving this style of state machine is very similar with Mechanim, with a programmer-oriented focus and was used by studios that made God of War and Capcom fighting games, so if deep combo chains are something you want, it might be just right for you.
@Mitch I'm very interested for this kind of product, I wonder what features will have the character controllers?
In my opinion for minimum character controllers will be much appreciated to have at least basically trigger states like:
idle->walk->run->jump->crouch (not in a specific order) => from here I think will be more easy for us to build and customize the scripts :yes: . Thanks & keep up the good work !
@Xelnath thanks a lot for your explicit answer, I will give it a try for sure :time: & will let you know what I did, Thanks !
Have a nice weekend friends,
:beer: :beer: :beer:
Dorin
The two controllers I'm planning on releasing very, very shortly are
Brawler-type (Idle, Walk, Run, Jump(multi jump), Bounce on enemies, punch combo, up attack, down attack, up attack, wall jump, one way platform support, moving platform support)
Run-gun type (idle, walk, run, jump, jetpack, bounce, various weapon equips along with a method to dynamically swap rig for the arms for different weapons efficiently, and the same platform support)
both controllers will be compatible with eachother so they can co-exist in the same game. both also come with proto-characters that flesh out the animation and gameplay for each type.
My hope is that it starts the Spine+Unity community on making some badass platformy type games faster / with a solid base
I think after reading what you said I might have to include a basic / stripped Idle Walk Run Jump Crouch one with all of the packs.
Obviously building complex controllers like the ones I described is hard to do modularly, so I went the route that simply kept them functional and tweakable.
Anyway, I'll post some playable demos later today I hope You can catch a glimpse of it at the end of my Skeleton Ghost demo video
https://youtu.be/xvmw0YsSmk4?t=176
Ahhh, Mitch's secret plan is revealed - and suddenly it becomes clear why his tools are so good!
No. His tools are so good because shut up.
Excelent news Mitch, how soon is "soon" ? :rofl:
BTW the character control from video looks insane, can wait to test it :rock:
P.S Will be compatible with mobile devices ? Right now I'm developing my game for mobiles, wondering for performances reason...
Performance wise it'll be fine... But platforming in general on mobile is rough just because of speed and the design/latency/awkwardness of touch controls. Fair warning
"Soon" is mid-June at the earliest at the moment.
Hi Mitch,
I wonder if it's possible a beta or a pre-order release because I need a good working controller script for my project as soon as possible
Thanks in advance !
Sent you a PM
Waiting for this!! I need the controllers too!
Thank you Mitch, keep us informed.