Forum rules - please read before posting.

Little advice on character movement

Hello Chris,

Hope you are well.
I need your advice on character movement. Our characters do have an intro and outro animation before (and after) walking. You may have guessed: this sometimes creates a bit of an unwanted effect in which the character starts moving but is actually "about to start moving". So, that's pretty much the question: what type of Animation Engine or option you would recommend for cases such as this in which I want to delay a bit the movement. I'm using Unity Complex and have all sort of arrows from animation to animation. Looks 90% okay but still want to get rid of the movement before the intro-animation kicks in.

Thanks!

Comments

  • Hello Kakyouin, please read the forum rules.

    Unity Sprite Complex is great animation engine to achieve that transition, creating that movement delay will be tricky though. I believe there's currently no way of achieving what you want directly with AC without custom scripting. You could try setting your acceleration to 1 on your character and see if that helps.

    I guess you could Halt you character the moment the character begins its path and then resume to this path after your transition animation is through. You could get the path and then set it back, or maybe it would work to just call the ResumeLastPath method.

  • Hello Keks, thanks for the reply.

    I found those part of a script in an old post before posting but I'm wondering if there's a way to maybe "delay" the walking using Sprite Complex or any other type of movement provided in the AC. It works great, we feel comfortable it's just a little "spice" we want to add to our character.

    I think we tried the acceleration, but I can't remember (sometimes we jump from one subject to another when we wait for a reply so as to use our time as best as possible). Need to try it again and play with it.

    In the scenario that we need to combine a script... my question would be: where or how can I combine both. In the manual I read about the custom scripting and that's exactly what we want to avoid since we may need to do and write every-single-animation.
    Maybe there's a way to mix an action list to wait before turning or moving... looking for something like that, because it's a one second delay we need before moving, for every animation other than idle.

    Hope that adds a bit more info on the subject and as always, I'll post here results so anyone can use this for future references.
    Thanks guys :)

  • If this was for a 3D game, you could make use of Unity's Root Motion features and be done with it.

    For 2D, things are more tricky. A low Acceleration value would have them take longer to build up to "regular" speed, but for something more controlled you might want to look into syncing the "Walk speed" value with the animation itself.

    If you attach the following script to your character's Animator object, you can have your animations update the value of it's "moveSpeedFactor" field. At runtime, this script will then use that to influence the character's speed:

    using UnityEngine;
    
    public class DynamicCharacterSpeed : MonoBehaviour
    {
    
        [SerializeField] private AC.Char character = null;
        public float moveSpeedFactor = 1f;
        private float originalWalkSpeed, originalRunSpeed;
    
        private void Awake ()
        {
            originalWalkSpeed = character.walkSpeedScale;
            originalRunSpeed = character.runSpeedScale;
        }
    
        private void Update ()
        {
            character.walkSpeedScale = originalWalkSpeed * moveSpeedFactor;
            character.runSpeedScale = originalRunSpeed * moveSpeedFactor;
        }
    
    }
    
  • edited March 2022

    Setting the char's speed seems to be the best way to do it. Didn't thought of it at first. I think it would be best to combine it with a StateMachineBehaviour script attached to the transition animation in your Unity Complex Animator.

    public class WalkingTransition : StateMachineBehaviour
    {
        public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            // Set your moveSpeedFactor to 0
        }
    
        public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            // Set your moveSpeedFactor to 1
        }
    }
    
  • Hello community,

    I've tried Chris' script. I've added it to the character and tried in real time the movements. Though it works, I don't see how I could link or modify the moveSpeedFactor through the animations. Maybe I'm missing something or a functionality inside the Animator. I've always done it the other way around: a script would change the animator.

    Is that what you mean by "have your animations update the value of it's "moveSpeedFactor" field".

    Maybe this is super new to me and never done it before. If, by chance I could set a moveSpeedFactor float through the animation (and modify the script's behaviour), then yes, I could make it move from 0 to a value I want and make the desired movement whenever I want to "move" or "stall".

    Thanks a lot!

  • I think I got it!! Let me show you my findings. Maybe this is what you meant. At least now it works so much better!

    public class DynamicCharacterSpeed : MonoBehaviour
    {

    [SerializeField] private AC.Char character = null;
    public float moveSpeedFactor = 1f;
    public float originalWalkSpeed, originalRunSpeed;
    public Animator theAnimator;
    
    private void Awake()
    {
        originalWalkSpeed = character.walkSpeedScale;
        originalRunSpeed = character.runSpeedScale;
    }
    
    private void Update()
    {
        theAnimator.SetFloat("moveSpeedFactor",moveSpeedFactor);
        //character.walkSpeedScale = originalWalkSpeed * moveSpeedFactor;
        //character.runSpeedScale = originalRunSpeed * moveSpeedFactor;
    }
    
    public void SetZeroValue()
    {
        character.walkSpeedScale = originalWalkSpeed * 0.3f;
        character.runSpeedScale = originalRunSpeed * 0.3f;
    }
    
    public void SetOriginalValue()
    {
        character.walkSpeedScale = originalWalkSpeed * moveSpeedFactor;
        character.runSpeedScale = originalRunSpeed * moveSpeedFactor;
    }
    

    }

    And on the animator I've added at the beginning of the Intro to walk and at the beginning of the walk just one event in which I would call the SetZeroValue for the intros and SetOriginalValue on the walking.

    And on the animator just one float called moveSpeedFactor just to check the velocity (no need for this actually).

    Thanks guys!!! :D:D:D

  • Sorry to bring this up again but I noticed that even though this script is attached to NPC and Players, they all move to the speed related to the main character.
    I can create different scripts for each character but at some point it will be a mess. What I want is to check "inside" that particular character which movespeed it has. For some reason I can't access to anything regarding Char and NPC.
    Is there a to check what "that" character has as movespeed and not some global variable?
    Hope I'm clear. In case not, example below:
    Player: movespeed 2.
    NPC 1: movespeed 1.
    NPC 2: movespeed 3.
    On "play" NPC 1 and 2 will be "2" because "character" is 2. I want to have it look inside each character.

    Thanks!

  • The script above doesn't reference the Player/main character directly - only what you assign in the Character and Animator Inspector fields. Are both updated to reference the character it's attached to?

  • MY bad. It was that. Sorry for the confusion.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.