Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

iStep - Premium Foot Placement Solution

Discussion in 'Assets and Asset Store' started by Kreshi, Apr 13, 2022.

  1. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    I see, that's great to hear that you solved the problem that fast :).
    The approach piqued my interest a bit, so why does your custom character controller need to use its own ragdoll colliders or colliders attached to its rig for collision detection?
    Usually those colliders are set to layers where they don't interfere with the character controllers collision detection at all until some ragdoll-functionality is activated and the ragdoll takes over. So are you using some kind of active controlled ragdoll here or is there any other reason that your character controller requires such a setup?

    I ask out of interest and because I had a case once where a customer used Opsive Ultimate Character Controller with iStep and an attached ragdoll while having set the ragdolls colliders to a layer that made the colliders later being used by Ultimate Character Controller as part of their internal collision detection algorithm which resulted in a broken behaviour. As I remember correctly I think the issue was fixed by changing the ragdolls layer to a layer that wasn't setup in Ultimate Character Controller to be used as part of its internal collision detection. In general a capsule is absolutely enough for typical character controller collision detection and it really isn't required to use dynamic colliders attached to the rig in addition :). But that's just the general case and there may be many special cases where someone may want this specific behaviour.

    Anyway, I would be super thankful if you could tell me more about your setup :) (if you want of course :D).
     
  2. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    @MrCarterMan I saw that the character you are using is Dystopia Solder 2 from Maksim Bugrimov. I will make you an individual tutorial video for exactly this character presumably tomorrow :). For this character it's absolutely essential that you set the "Avatar Definition" to "Copy From Other Avatar" for all its animations (animation import settings) and set the character-models avatar as the target-value. It will be more clear in the tutorial but this is essential, otherwise the animations will be broken (this is independent from iStep and essential on its own :)).

    I also optimized some settings for this model (not all, just a few), so here you are:

    - Global Character Y Offset: 0.01
    - Ik Max Correction: 0.7
    - Ik Foot Height: 0.18
    - Ik Foot Length: 0.35
    - Ik Foot Widht: 0.11
     
    MrCarterMan likes this.
  3. jnbbender

    jnbbender

    Joined:
    May 25, 2017
    Posts:
    488
    Sure. I am using Invector's controller & decided to do something along the lines of what you describe with Opsive. I wanted to create a more detailed collision setup as well as custom damage per body part. So I added the same Colliders a ragdoll would add I just didn't add joints. I added the "BodyPart" layer which will be the only impact layers than an enemy can hit so the main capsule collider on the "Player" layer would not be detected.
    This type of setup also makes it simple to use RASCAL Skinned Mesh Renderer if I decide to get "perfect" collision detection.
     
    Kreshi likes this.
  4. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Yeah the concept of using multiple colliders for hit-detection is definitely a very good one and definitely required for high-quality productions :).
    However the case I tried to describe earlier was a bit different I guess, I didn't mean additional colliders for hit-detection but additional colliders for the character controllers internal physics collision and intersection calculations (while being dynamic in relation to each other due to being attached to an animated rig) :).
     
  5. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    @MrCarterMan
    I finished your specific tutorial video that should resolve all your problems :).
    It's a very detailed and long video and most stuff is about correctly importing/converting assets and not so much about iStep, but you will need all this :).

     
    MrCarterMan likes this.
  6. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    A short and compact video tutorial on how to integrate Synty Studios 3D models was created as well :):

     
  7. jnbbender

    jnbbender

    Joined:
    May 25, 2017
    Posts:
    488
    No, nothing fancy like that.
     
    Kreshi likes this.
  8. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Another video tutorial has been finished, this time it's about integrating iStep with Invector. In addition iSteps "adapt so surface slope" addon will be explained at the end of the video :). With this addon you can solve specific intersection issues when you have a character that is sliding right into slopes.

     
  9. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Hi guys,

    I am preparing the release of iStep 1.2.7 which will contain the following features:

    • You will be able to switch between the currently default interpolation method LERP and the newly added interpolation method SMOOTH_DAMP.
    • Foot placement can now detect and automatically react to dynamic moving objects even when minimum movement threshold is not zero and the player stands still in idle animation.
    • Minor improvements to the included character controller regarding steep slopes and jump behaviour.

    Here is the WebGL demo with the new features in preview: https://istepunity.web.app/starterdemo/
    The difference between LERP and SMOOTH_DAMP is very sublte, but if you have any feedback regarding which of the two should be used as the default value, please let me know :) (you can switch between these two values in the WebGL demo).
     
    Last edited: Jul 25, 2022
  10. developer_bigdipperstudio

    developer_bigdipperstudio

    Joined:
    Dec 31, 2014
    Posts:
    10
    Hi, I would like to ask if it is possible to use it with the vrm type of model?
     
  11. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Do you mean VRoid Studio VRM exported models?
    I tested VRoid models today in the morning and they were compatible with iStep. I will make a short video tutorial for you later in the day :).
     
  12. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Alright, like promised, here is the video tutorial for integrating VRoid Studio models with iStep:

     
  13. developer_bigdipperstudio

    developer_bigdipperstudio

    Joined:
    Dec 31, 2014
    Posts:
    10
    Thanks for the video! i can finally made my model use the istep by following the step in video. :)
    However if i try to build from a new scene and follow the eight steps listed in the Manual.pdf document it seems that it does not works. Is there any parts that l missed? As I am not native speaker of English i may have missed out some points in the video:(
    upload_2022-7-29_15-23-24.png
    My settings now is just pull the animator out of the vrm and setup the Animator with VrmAvatar as suggested, Controller using StarterAssetsThirdPerson in the project as dummy.
    When I play it and move the sphere it simply doesn't work.
    upload_2022-7-29_15-28-2.png
    Please kindly advise how I can handle this. Many thanks!
     
  14. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    In iStep 1.2.6, dynamically moving underneath objects instead of the character only works when you set Minimum Movement Threshold to 0. iStep 1.2.7 will resolve that when it's released :).
    If Minimum Movement Threshold is bigger 0 (by default it is bigger 0), you would need to move your character back and forth in your scene to see if everything works. Also always make sure IK pass is enabled in your custom Animator Controller :).

    Anyway, here part 2 of the tutorial which resolves your described case:

     
    Last edited: Jul 29, 2022
  15. developer_bigdipperstudio

    developer_bigdipperstudio

    Joined:
    Dec 31, 2014
    Posts:
    10
    Thanks a lot! I found that the idle motion must be a moving motion instead of a still frame in order the make this work. Now i can trigger the moving collider to get istep effect. Many thanks!:)
     
    Kreshi likes this.
  16. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    iStep 1.2.7 has been released :).

    Release Notes:
    • You will be able to switch between the currently default interpolation method LERP and the newly added interpolation method SMOOTH_DAMP
    • Foot placement can now detect and automatically react to dynamic moving objects even when minimum movement threshold is not zero and the player stands still in idle animation
    • Minor improvements to the included character controller regarding steep slopes and jump behaviour
    • Minor updates to the documentation
    Getting the most out of iStep should now be easier than ever :).
     
    shyamarama likes this.
  17. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Hey! I'm a huge fan of iStep, it's really the best IK solution I ever tried!

    However, I have a small issue with the procedural characters. Looks like iStep looking for all the references on Awake(), when a procedural character might not be generated yet. So it just drops a "missing reference" error and does not initialize. Is there any particular reason to keep that part in Awake() or it could be moved to Start() for example? This way it will be possible to initialize iStep manually (just with enabling component when a procedurally created character will be 100% ready).
     
    Kreshi likes this.
  18. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Hi SammmZ,
    I am currently not at home so I can't check the code, but in general there are multiple ways how to solve this issue:

    Method 1) iSteps FootIK script is super robost - you can in general add it at any given point during runtime. To solve your case, you could start a coroutine, wait for the end of the frame and add the FootIK script delayed so that everything else is initialized when the FootIK script is attached.

    Method 2) Deriving from FootIK with your CustomFootIK class, overriding the Awake function with an empty implementation and overriding the Start function and call in your Start: base.Awake(); base.Start();

    This is from the top of my head and I hope it works for you :). I should be back home tomorrow at night in case more help is required :).

    Edit: regarding your question about Awake/Start functions: It is recommended to use Awake for initializing variables and Start for affecting variables. I just stick to the documentation when I chose which one to use for initialization :).
     
    Last edited: Aug 19, 2022
  19. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Oh, thanks for your detailed reply! For now, I just edited the original code to be sure it will work in Start and not in Awake, but you're right, I should derive from the original script and just get my own edit in a separate file :)
     
  20. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Hello everyone,

    iStep 1.2.8 has been released.

    Release Notes:
    • Support for Animation Rigging added, please see the documentation and/or watch the associated video tutorial if you want to integrate Animation Rigging with iStep.
    • Two new IK hint position computation algorithms added that you can choose from. The new algorithms compute the IK hint position based on bones. This can be very useful if you setup multiple animation layers with custom avatar masks where one layer is responsive for foot IK and the other for root rotation / hips rotation and other body parts. The reason why it will be useful for such setups is, because Unity doesn't recalculate IK hint positions based on overall blended bone transitions but uses the unblended IK hint positions from the layer corresponding for foot IKs instead. With the new IK hint position algorithms that you can choose from this will be resolved which leads to much better results when using such multi-layer animation setups.
    • Other minor improvements.
    • Updates to the documentation.

    And here the video tutorial for integrating Animation Rigging with iStep:


    Also here the video tutorials associated sample project for download so that you can have a look at the structure and how everything has been setup (requires iStep + Animation Rigging package): https://hoax-games-downloads.web.app/istep/iStepAnimationRiggingExample.unitypackage
     
  21. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Hello everyone,

    iStep 1.2.9 has been released (silently).

    Release Notes:
    • Improved Effects Player functionality

    It's only a small update with minor improvements to the Effects Player though :).
     
  22. merpheus

    merpheus

    Joined:
    Mar 5, 2013
    Posts:
    202
    Does it work with Motion Matching for Unity asset?
     
  23. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Yes in my tests it was fully compatible.
    To make iStep work with the player controller inside the motion matching demo scene, I created an empty AnimatorController, enabled IK pass for the Base Layer of the created Animator Controller and assigned it to the players Animator component. I then attached iSteps FootIK script and it worked very well :).

    Here the results:

     
    merpheus likes this.
  24. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    I recently updated iStep to the latest version and surprisingly it stops working for me.
    Instead, I got an error on each frame. Any idea what's happening? :(
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. HoaxGames.FootIK.updateIK (UnityEngine.Vector3 feetZeroPos) (at Assets/_ThirdParty/!Scripts/iStep/Scripts/FootIK.cs:785)
    3. HoaxGames.FootIK.OnAnimatorIK (System.Int32 layerIdx) (at Assets/_ThirdParty/!Scripts/iStep/Scripts/FootIK.cs:505)
     
  25. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    At that line, the animator is NULL. The animator is initialized in Awake, the issue is probably related to your local changes from that time:



    "Hey! I'm a huge fan of iStep, it's really the best IK solution I ever tried!

    However, I have a small issue with the procedural characters. Looks like iStep looking for all the references on Awake(), when a procedural character might not be generated yet. So it just drops a "missing reference" error and does not initialize. Is there any particular reason to keep that part in Awake() or it could be moved to Start() for example? This way it will be possible to initialize iStep manually (just with enabling component when a procedurally created character will be 100% ready)."



    I guess your previous manual changes may have been overriden by the update.
    You can either move the code from the Awake function to the beginning of the Start function like last time (simple + fast), or you try it the suggested way to avoid any issues when updating to newer versions: :)



    "Hi SammmZ,
    I am currently not at home so I can't check the code, but in general there are multiple ways how to solve this issue:

    Method 1) iSteps FootIK script is super robost - you can in general add it at any given point during runtime. To solve your case, you could start a coroutine, wait for the end of the frame and add the FootIK script delayed so that everything else is initialized when the FootIK script is attached.

    Method 2) Deriving from FootIK with your CustomFootIK class, overriding the Awake function with an empty implementation and overriding the Start function and call in your Start: base.Awake(); base.Start();

    This is from the top of my head and I hope it works for you :). I should be back home tomorrow at night in case more help is required :).

    Edit: regarding your question about Awake/Start functions: It is recommended to use Awake for initializing variables and Start for affecting variables. I just stick to the documentation when I chose which one to use for initialization :)."
     
  26. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    I also thought about it in the first place, but I deliberately make sure that my changes were implemented back using my version control. Maybe it was somehow broken on a merging process? Here is how my Start/Awake looks atm:

    Code (CSharp):
    1.         protected virtual void Awake()
    2.         {
    3.  
    4.         }
    5.  
    6.         protected virtual void Start()
    7.         {
    8.             //Pigedit start
    9.             m_transform = this.transform;
    10.             m_animator = this.GetComponent<Animator>();
    11.  
    12.             if (m_animator != null)
    13.             {
    14.                 m_spineTransform = m_animator.GetBoneTransform(HumanBodyBones.Spine);
    15.                 m_leftShoulderTransform = m_animator.GetBoneTransform(HumanBodyBones.LeftShoulder);
    16.                 m_rightShoulderTransform = m_animator.GetBoneTransform(HumanBodyBones.RightShoulder);
    17.                 m_prevBodyPosition = m_animator.GetBoneTransform(HumanBodyBones.Hips).position;
    18.                 m_leftUpperLeg = m_animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
    19.                 m_rightUpperLeg = m_animator.GetBoneTransform(HumanBodyBones.RightUpperLeg);
    20.             }
    21.  
    22.             m_prevTransformPosition = m_transform.position;
    23.             m_resultLeft = new IKResult(Vector3.zero, Vector3.zero, false, Vector3.zero, Vector3.zero, Vector3.up, null, null);
    24.             m_resultRight = new IKResult(Vector3.zero, Vector3.zero, false, Vector3.zero, Vector3.zero, Vector3.up, null, null);
    25.  
    26.             foreach (var entry in m_forceInvalidOnAnimatorStates) m_deactiveOnAnimatorState.Add(new KeyValuePair<int, int>(entry.layer, Animator.StringToHash(entry.animatorState)));
    27.             foreach (var entry in m_forceActivateCrouchingBehaviour) m_activateCrouchingOnAnimatorState.Add(new KeyValuePair<int, int>(entry.layer, Animator.StringToHash(entry.animatorState)));
    28.  
    29.             for (int i = 0; i < m_averageSlopeLeaningFixedQueueCount; i++) m_averageSlopeLeaningValuesQueue.Enqueue(0);
    30.  
    31.             //Pigedit end
    32.             m_prevTransformPosition = m_transform.position;
    33.             m_ikFootHeightToUseLeft = m_ikFootHeight;
    34.             m_ikFootHeightToUseRight = m_ikFootHeight;
    35.             m_ikFootLengthToUseLeft = m_ikFootLength;
    36.             m_ikFootLengthToUseRight = m_ikFootLength;
    37.         }
     
  27. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    You have an issue in your initialization method - this is not the whole initialization content of the newest iStep version :).
    The newest version has this content:

    Code (CSharp):
    1. protected virtual void Awake()
    2.         {
    3.             m_transform = this.transform;
    4.             m_animator = this.GetComponent<Animator>();
    5.  
    6.             if (m_animator != null)
    7.             {
    8.                 m_spineTransform = m_animator.GetBoneTransform(HumanBodyBones.Spine);
    9.                 m_leftShoulderTransform = m_animator.GetBoneTransform(HumanBodyBones.LeftShoulder);
    10.                 m_rightShoulderTransform = m_animator.GetBoneTransform(HumanBodyBones.RightShoulder);
    11.                 m_prevBodyPosition = m_animator.GetBoneTransform(HumanBodyBones.Hips).position;
    12.                 m_leftUpperLeg = m_animator.GetBoneTransform(HumanBodyBones.LeftUpperLeg);
    13.                 m_rightUpperLeg = m_animator.GetBoneTransform(HumanBodyBones.RightUpperLeg);
    14.                 m_leftLowerLeg = m_animator.GetBoneTransform(HumanBodyBones.LeftLowerLeg);
    15.                 m_rightLowerLeg = m_animator.GetBoneTransform(HumanBodyBones.RightLowerLeg);
    16.                 m_leftFoot = m_animator.GetBoneTransform(HumanBodyBones.LeftFoot);
    17.                 m_rightFoot = m_animator.GetBoneTransform(HumanBodyBones.RightFoot);
    18.  
    19.                 findLegsForwardAxes(out m_leftAxisHint, out m_isLeftAxisHintNegative, out m_rightAxisHint, out m_isRightAxisHintNegative);
    20.             }
    21.  
    22.             m_prevTransformPosition = m_transform.position;
    23.             m_resultLeft = new IKResult(Vector3.zero, Vector3.zero, false, Vector3.zero, Vector3.zero, Vector3.up, null, null);
    24.             m_resultRight = new IKResult(Vector3.zero, Vector3.zero, false, Vector3.zero, Vector3.zero, Vector3.up, null, null);
    25.  
    26.             foreach (var entry in m_forceInvalidOnAnimatorStates) m_deactiveOnAnimatorState.Add(new KeyValuePair<int, int>(entry.layer, Animator.StringToHash(entry.animatorState)));
    27.             foreach (var entry in m_forceActivateCrouchingBehaviour) m_activateCrouchingOnAnimatorState.Add(new KeyValuePair<int, int>(entry.layer, Animator.StringToHash(entry.animatorState)));
    28.  
    29.             for (int i = 0; i < m_averageSlopeLeaningFixedQueueCount; i++) m_averageSlopeLeaningValuesQueue.Enqueue(0);
    30.         }
    31.  
    32.         protected virtual void Start()
    33.         {
    34.             m_prevTransformPosition = m_transform.position;
    35.             m_ikFootHeightToUseLeft = m_ikFootHeight;
    36.             m_ikFootHeightToUseRight = m_ikFootHeight;
    37.             m_ikFootLengthToUseLeft = m_ikFootLength;
    38.             m_ikFootLengthToUseRight = m_ikFootLength;
    39.         }
    Nonetheless I strongly recommend to NOT edit the codebase directly to avoid any form of issues when updating to a newer version.

    I recommend to try out using a derivative class of FootIK instead and configure it to your likings like in this example below:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class MyCustomFootIKExample : HoaxGames.FootIK
    6. {
    7.     protected override void Awake()
    8.     {
    9.         // do nothing
    10.     }
    11.  
    12.     protected override void Start()
    13.     {
    14.         StartCoroutine(customTimingInitialization());
    15.     }
    16.  
    17.     IEnumerator customTimingInitialization()
    18.     {
    19.         // wait for how long you have to wait until your procedural character initialization has been finished
    20.         yield return new WaitForEndOfFrame(); // wait for end of the frame
    21.         yield return new WaitForEndOfFrame(); // wait for end of the next frame
    22.  
    23.         // initialize
    24.         base.Awake();
    25.         base.Start();
    26.     }
    27.  
    28.     protected override void OnAnimatorIK(int layerIdx)
    29.     {
    30.         if (this.m_animator == null) return; // make sure nothing happens when initialization isn't finished
    31.  
    32.         base.OnAnimatorIK(layerIdx);
    33.     }
    34. }
    35.  
     
  28. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Damn, I knew it! Should have checked before asking for help. Thanks a lot for your support <3 <3
    (Yeah, I should definitely move to the smarter ways of adding changes)
     
    Kreshi likes this.
  29. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    You are welcome :) :).
     
  30. KOCGI

    KOCGI

    Joined:
    Aug 15, 2018
    Posts:
    5
    In the webdemo you can tell there is an obvious and huge problem with that AA implimantion!
    When the character position is changed the camera does not follow!!!
    Is there any way to change that behaviour so it doesn't break games? (aiming and camera position are important in games you know?)
     
  31. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    I don't really understand the question. In the WegGL demo, the camera does follow the player :). Also: please take into consideration, that iSteps selling proposition is not the included character controller from the demo, but the professional foot placement solution :).

    iStep should be compatible with all major custom character controllers you can get from the Unity Asset Store as well, so you can always add iStep on top of your preferred character controller.

    If you have any more questions, feel free to ask, I will try to answer them as good as I can :).
     
  32. KOCGI

    KOCGI

    Joined:
    Aug 15, 2018
    Posts:
    5
    Thank you for the replay. I mean the camera is not following the Y-Axis when the character is placed a little lower or higher. Instead the camera stays at the same height position. I would like to know if it can be made so that it follows the player height offset. I don't know how to describe it any better. Other than that the asset looks fantastic
     
    Kreshi likes this.
  33. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Alright, now I understand :D.
    Yes you can do that as well :).

    Here a super short video tutorial showing how to do it for the included character controller using the GlobalIKTargetCorrector scirpt:


    You can also access the applied body-position-offset in your custom scripts by using the fullBodyOffset variable from the FootIK script directly from code and apply it to any custom target you wish :).
     
  34. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    terrain texture recognition has been added to the included EffectsPlayer addon :).
    Alltogether it supports now layers, tags and terrain textures^^.

    iStep 1.3.0 has been officially released:

    https://assetstore.unity.com/packages/tools/animation/istep-215843


    Release Notes:
    • Added terrain texture recognition support for the Effects Player
    • Fixed minor bugs

    A video regarding the new functionality will follow soon :).
     
    Last edited: Nov 17, 2022
    dock and SammmZ like this.
  35. KOCGI

    KOCGI

    Joined:
    Aug 15, 2018
    Posts:
    5
    Outstanding :)
     
    Kreshi likes this.
  36. lvulcanis

    lvulcanis

    Joined:
    May 2, 2016
    Posts:
    6
    Does this work with NavMeshAgent?
     
  37. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Yes it does :).

    The only requirements iStep has are:
    - The character must be of type humanoid
    - IK pass must be enabled in your AnimatorController
     
    lvulcanis likes this.
  38. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Is there a way to keep iStep not on the Character's root but on a child of the root? I changed the init part to this
    Code (CSharp):
    1. m_transform = this.transform.parent;
    2. m_animator = this.GetComponentInParent<Animator>();
    and it finds an animator, but seems like it was not enough :(
     
    Last edited: Nov 23, 2022
  39. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    The reason the suggested approach can't work this way is because the OnAnimatorIK function will only be called for scripts attached to the same GameObject where the corresponding Animator component is attached onto as well. That's a Unity "thing": https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html

    If you can show me your code section that is making you trouble, there is a chance that I could help you fix it without the need of making any modification to the original FootIK script :).
     
  40. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Oh, well. Bad luck :D
    It's mostly an "architecture" issue. My character root is created procedurally, it hosts an animator, NavMeshAgent, and all the game logic. Then, as a child of this root object, I'm loading a prefab with an actual character with all the necessary scripts attached. I definitely don't want to create FootIK on the runtime and set up all values, layers, and especially events that should be attached to it... (tbh I don't even have an idea how to setup events on runtime lol). So I expected I can pre-setup FootIK on my character prefab that would be later attached to the actual Root... But, well... Seems like it's impossible :(
     
  41. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Oh, I see. Looks like I technically can't assign most of the important stuff on runtime anyway. Like, I can't set collisionLayerMask with a script, etc...

    EDIT. Ok, that was easier than I expected, lol. But yeah, it would be nice to have all the major stuff available to set by default as well. Like this:
    Code (CSharp):
    1.         LayerMask m_collisionLayerMask = 1 << 0; public LayerMask collisionLayerMask { get { return m_collisionLayerMask; } set { m_collisionLayerMask = value; } }
     
    Last edited: Nov 23, 2022
  42. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    That is possible actually :).

    The easiest way to achieve that would be to first add these lines of code to the FootIK script:

    Code (CSharp):
    1.         public virtual void reinitialize()
    2.         {
    3.             Awake();
    4.             Start();
    5.         }
    and then, in your own code, do something similar to this:

    Code (CSharp):
    1. using HoaxGames;
    2. using System.Reflection;
    3. using Unity.VisualScripting;
    4. using UnityEngine;
    5.  
    6. public class DebugComponentCopy : MonoBehaviour
    7. {
    8.     [SerializeField] FootIK m_targetFootIk;
    9.     [SerializeField] GameObject m_sourceGameObject;
    10.  
    11.     // Start is called before the first frame update
    12.     void Start()
    13.     {
    14.         FootIK footIk = m_sourceGameObject.GetOrAddComponent<FootIK>();
    15.         copyClassValues(m_targetFootIk, footIk);
    16.         footIk.reinitialize();
    17.     }
    18.  
    19.     public void copyClassValues<T>(T sourceComp, T targetComp)
    20.     {
    21.         FieldInfo[] sourceFields = sourceComp.GetType().GetFields(BindingFlags.Public |
    22.                                                          BindingFlags.NonPublic |
    23.                                                          BindingFlags.Instance);
    24.         for (int i = 0; i < sourceFields.Length; i++)
    25.         {
    26.             var value = sourceFields[i].GetValue(sourceComp);
    27.             sourceFields[i].SetValue(targetComp, value);
    28.         }
    29.     }
    30. }
    31.  
    m_sourceGameObject represents your procedurally generated character that has the Animator component attached onto and m_targetFootIK represents your instantiated object that you want the values copied from. However take into consideration that in case you configured iSteps FootIK events (like OnFootstepLeftStart,..) on the target object as well, that those references on the procedurally generated character will still point to the target instead and therefore will need separate reconfiguring.

    Hope this helps :).

    (Source for the copyClassValues function: https://answers.unity.com/questions/740055/can-i-move-component-of-one-gameobject-to-other.html)
     
    Last edited: Nov 23, 2022
    SammmZ likes this.
  43. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    The FootIK script has a lot of setter properties and setter functions too in case that you prefer setting the values at runtime directly :). Also in case any setter is missing, you can always derive from FootIK and add the respective setter function or property that you need :).
     
  44. SammmZ

    SammmZ

    Joined:
    Aug 13, 2014
    Posts:
    174
    Reflections! That's smart, thanks a lot for your support :rolleyes:
     
    Kreshi likes this.
  45. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
  46. xodennisxo

    xodennisxo

    Joined:
    Mar 25, 2020
    Posts:
    24
    i'd like to ask how can you achive to not use manually set animation curve to indicate if foot in the orignial animation is lifting to avoid foot is glued to ground surface during walking?
     
  47. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    Hi @xodennisxo

    I have difficulty to understand the question. Is this a technical question how I managed to do it without animation curves or is it an issue you are experiencing that you want to solve? :)
     
  48. xodennisxo

    xodennisxo

    Joined:
    Mar 25, 2020
    Posts:
    24
    Sorry for my english. Yes, Its a technical question about how you manage to do it without setting curves. I don't meet any issue;)
     
    Kreshi likes this.
  49. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    448
    In general, I calculate the correct body-position to ground the character first and then I adapt the foot-position accordingly to the geometry. In case the dynamic character-animation has its IK-position higher than the calculated IK-adapted position to fit the geometry, the IK-position given by the animation overrides the calculated IK-position based on geometry and therefore smoothly and automatically transitions back to the necessary animation-IK-position :).

    This is a small but important part of the algorithm. Alltogether there are like "thousand" edge-cases (not literally :D) like this handled to achieve the final results that iStep achieves :).
     
  50. xodennisxo

    xodennisxo

    Joined:
    Mar 25, 2020
    Posts:
    24
    Thank you for the infomation. Excelent work!
     
    Kreshi likes this.