Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Aldrick · Oct 26, 2016 at 10:06 AM · coroutineweaponienumeratortrails

Failed to inplement smooth increment of weapon trail between frames in Mecanim animation

Hello.I am currently scripting a weapon swipe trail tool.I find this one created by Evan Greenwood very helpful: https://www.assetstore.unity3d.com/en/#!/content/2458

I am tweaking and simplying it to meet my needs.Everything goes well until I use Mecanim Animator instead of Legacy Animation Component to play the character action.The trail does not appear smooth any more,It appears jagged updating only one step per frame.

I let the WeaponTrail script,which is the core drawing class,untouched.

What I modified are BladeMaster and AnimationController. As I switch to Mecanim and I do not need to add trajectory movement to the character,Evan's AnimationController has few usage for me. So I merge some of its functions into BladeMaster and simplify them into a single Manager like script:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
  
 // This is the PocketRPG Blade Master class stripped down to just a bit of animation... written by Evan Greenwood
 [AddComponentMenu("TATools/LSF TrailManager Mechanim")]
 public class LSF_TrailManager_Mechanim : MonoBehaviour
 {
     public WeaponTrail MyWeaponSwipe;
     public float TrailDuration = 1.3f;
     public float FadeOutTime = 0.3f;
     protected float DeltaTime = 0.033f;
     private bool Bool_ShowTrail = false;
     //protected float StepDuration = 0.1f;
     protected int thinkState = 0;
     protected float timeScale = 1; // This is here for personal time distortion... like freeze spells that slow enemies... (changing this affects the animation rate)
     protected List<WeaponTrail> trails;
     protected float m = 0;
     protected Vector3 lastEulerAngles = Vector3.zero;
     protected Vector3 lastPosition = Vector3.zero;
     protected Vector3 eulerAngles = Vector3.zero;
     protected Vector3 position = Vector3.zero;
     private float tempT = 0;
     public bool gatherDeltaTimeAutomatically = true; // ** You may want to set the deltaTime yourself for personal slow motion effects
     protected float animationIncrement = 0.001f; // ** This sets the number of time the controller samples the animation for the weapon trails
  
     protected void Awake()
     {
         transform.position = Vector3.zero;
         trails = new List<WeaponTrail>();
         lastPosition = transform.position;
         lastEulerAngles = transform.eulerAngles;
     }
     protected void Start()
     {
         AddTrail(MyWeaponSwipe); // Adds the trails to the animationController which will run them
         MyWeaponSwipe.SetTime(0.0f, 0, 1);
     }
  
     protected void Update()
     {
         DeltaTime = Mathf.Clamp(Time.deltaTime * timeScale, 0, 0.066f);
     }
  
     protected virtual void LateUpdate()
     {
         if (gatherDeltaTimeAutomatically)
         {
             DeltaTime = Mathf.Clamp(Time.deltaTime, 0, 0.066f);
         }
  
         RunAnimations();
     }
  
     public void StartTrailFromAnimationClip()
     {
         MyWeaponSwipe.StartTrail(0.5f, 0.4f);  // Fades the trail in  
         Bool_ShowTrail = true;
         Debug.Log("Start trail");
     }
  
     public void EndTrailFromAnimationClip()
     {
         //MyWeaponSwipe.FadeOut(FadeOutTime);
         MyWeaponSwipe.ClearTrail();
         Bool_ShowTrail = false;
         Debug.Log("End trail");
     }
  
     public void AddTrail(WeaponTrail trail)
     {
         trails.Add(trail);
     }
  
     void RunAnimations()
     {
         if (DeltaTime > 0)
         {eulerAngles = transform.eulerAngles;
             position = transform.position;
  
             while (tempT < DeltaTime)
             {
                 // ** This loop runs slowly through the animation at very small increments,a bit expensive, but necessary to achieve smoother than framerate weapon trails
                 tempT += animationIncrement;
                 // ** steps forward by a small increment
                 m = tempT / DeltaTime;
                 transform.eulerAngles = new Vector3(Mathf.LerpAngle(lastEulerAngles.x, eulerAngles.x, m), Mathf.LerpAngle(lastEulerAngles.y, eulerAngles.y, m), Mathf.LerpAngle(lastEulerAngles.z, eulerAngles.z, m));
                 transform.position = Vector3.Lerp(lastPosition, position, m);
                 // ** Samples the animation at that moment
                 // ** Adds the information to the WeaponTrail
                 for (int j = 0; j < trails.Count; j++)
                 {
                     if (trails[j].time > 0)
                     {
                         trails[j].TrailIterate(Time.time - DeltaTime + tempT);
                     }
                     else
                     {
                         trails[j].ClearTrail();
                     }
                 }
             }
             // ** End of loop
             tempT -= DeltaTime;
             // ** Sets the position and rotation to what they were originally
             transform.position = position;
             transform.eulerAngles = eulerAngles;
             lastPosition = position;
             lastEulerAngles = eulerAngles;
             // ** Finally creates the meshes for the WeaponTrails (one per frame)
             for (int j = 0; j < trails.Count; j++)
             {
                 if (trails[j].time > 0)
                 {
                     trails[j].UpdateTrail(Time.time, DeltaTime);
                 }
             }
         }
     }
  
 }

As I analyze the code.I think the part doing the trick to interpolate many smooth tiny "sections" into the mesh between two frames is as below:

              while (tempT < DeltaTime)
              {
                  // ** This loop runs slowly through the animation at very small increments,a bit expensive, but necessary to achieve smoother than framerate weapon trails
                  tempT += animationIncrement;
                  // ** steps forward by a small increment
                  m = tempT / DeltaTime;
                  transform.eulerAngles = new Vector3(Mathf.LerpAngle(lastEulerAngles.x, eulerAngles.x, m), Mathf.LerpAngle(lastEulerAngles.y, eulerAngles.y, m), Mathf.LerpAngle(lastEulerAngles.z, eulerAngles.z, m));
                  transform.position = Vector3.Lerp(lastPosition, position, m);
                  // ** Samples the animation at that moment
                  // ** Adds the information to the WeaponTrail
                  for (int j = 0; j < trails.Count; j++)
                  {
                      if (trails[j].time > 0)
                      {
                          trails[j].TrailIterate(Time.time - DeltaTime + tempT);
                      }
                      else
                      {
                          trails[j].ClearTrail();
                      }
                  }
              }

It works totally well when I use a legacy Animation(though the exact codes with legacy animation are not the same as above).But when I change it to Mecanim Animator,and use Animation Events on the fbx to trigger the mesh section creating functions,it looks like the tiny smooth interpolated sections between two frame steps do not work anymore.

Trail in Legacy Animation: alt text

Trail in Mecanim animation: alt text

Please,how to solve this issue?

Update: After examing the codes again,I find that it is the FadeInCurrentState() function that really does the job :

 void FadeInCurrentState (float aI)
     {
         // ** This is called every sample to ease in the current animation
         currentStateTime += aI * currentState.speed;
         currentState.time = currentStateTime;
     }
  
     void RunAnimations ()
     {
         if (DeltaTime > 0)
         {
             // ** The Animation Controller also turns the character
             // ** This is very important for smooth trails... Otherwise each frame the trail will jump to wherever the new rotation causes it to be
             // ** This could be taken further and make the animation controller move the character as well... You might want to do this if you have a character that moves very quickly
             while (IncrementProgress < DeltaTime)
             {
                 // ** This loop runs slowly through the animation at very small increments,a bit expensive, but necessary to achieve smoother than framerate weapon trails
                 IncrementProgress += animationIncrement;
                 // ** steps forward by a small increment
                 if (currentState != null)
                     FadeInCurrentState (animationIncrement);
                 // ** Samples the animation at that moment
                 GetComponent<Animation>().Sample ();
                 // ** Adds the information to the WeaponTrail
                 for (int j = 0; j < trails.Count; j++)
                 {
                     if (trails[j].time > 0) {
                         trails[j].TrailIterate (Time.time - DeltaTime + IncrementProgress);
                     } else {
                         trails[j].ClearTrail ();
                     }
                 }
             }
             // ** End of loop
             IncrementProgress -= DeltaTime;
             //
             // ** Finally creates the meshes for the WeaponTrails (one per frame)
             //
             for (int j = 0; j < trails.Count; j++) {
                 if (trails[j].time > 0) {
                     trails[j].UpdateTrail (Time.time, DeltaTime);
                 }
             }
         }
     }

So the question becomes "is there a counterpart of AnimationState.time in mecanim Animator,so that I can add fine control on the character animation in realtime?"Because as the codes show,it is using the AnimationState.time to make the animation forward many tiny steps between 2 updates.But I do not find similar methods in the Animation class.

Thank you guys.

legacy2.png (181.2 kB)
mechanim2.png (256.9 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Crouching-Tuna · Aug 23, 2018 at 02:38 PM 0
Share

Check here https://forum.unity.com/threads/pocket-rpg-framerate-independent-weapon-trails-free.115542/#post-3607175

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

coroutine question c# 2 Answers

Why is this coroutine only firing once? 3 Answers

How does WaitForSeconds actually work behind the scenes? 1 Answer

Get IEnumerator from name or convert MethodInfo to IEnumerator 2 Answers

Coroutine start and stop 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges