Search Unity

[RELEASED] Magica Cloth

Discussion in 'Assets and Asset Store' started by hoshos, Jan 22, 2020.

  1. yukocchi

    yukocchi

    Joined:
    Jul 5, 2018
    Posts:
    8
    Hi, the plugin is very nice with good performance.
    I have two questions.
    You've mentioned self-collision feature and layered collision feature. How is the development going? Looking forward to having them.
    How to avoid the front part of the skirt penetrating the thigh when the character squats? It seems easier to avoid the skirt penetrating the thigh when the character runs.
    Thank you.

    upload_2022-5-23_16-44-27.png upload_2022-5-23_17-11-17.png
     
    Last edited: May 23, 2022
  2. huanghonghong

    huanghonghong

    Joined:
    Jul 8, 2021
    Posts:
    6
    Hi,when i use magica mesh cloth component, i found the size of the prefab is a bit big,VirtualMeshData is the biggest of the 4,How can i optimize this?
    upload_2022-5-24_11-27-11.png

    upload_2022-5-24_11-23-10.png
     
  3. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Self-collisions and layer collisions are still in the experimental stage.
    But when I have time, I'm thinking of testing it again.
    If the skirt gets stuck, try the [Penetration] feature.
    This should solve most penetration problems.
    https://magicasoft.jp/en/prevent-penetration-2/
     
  4. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Unfortunately, it is currently a specification.
    These data are currently required for simulation.
    This increases in proportion to the number of vertices.
    I understand that this amount of data is a concern.
    I am currently working on Magica Cloth ver 2.0.
    To solve this problem, v2.0 has been redesigned so that all data is generated at runtime and no extra data is stored in the prefab.
    So please wait until the release of v2.0 to completely resolve this issue.
    It may be released as early as this fall.
     
  5. unity_3EHYMIDeZjMLJQ

    unity_3EHYMIDeZjMLJQ

    Joined:
    Dec 1, 2021
    Posts:
    2
    Can I take off the clothes?
    I would like to pull a character's clothes off in VR.
     
  6. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello!
    Unfortunately, this is not possible with the current features.
     
  7. unity_3EHYMIDeZjMLJQ

    unity_3EHYMIDeZjMLJQ

    Joined:
    Dec 1, 2021
    Posts:
    2
    I see. Thanks!
     
  8. lenzchu

    lenzchu

    Joined:
    Dec 7, 2013
    Posts:
    15
    Hi! I was wondering if a possible feature can be added to have specific cloth be affected by specific wind volume, but not others who are nearby to that volume. ex: ghost cloth ripple. Something similar to the collider list.
    btw I wanna say I love using ur asset and it's been solving a lot things for me lately!
     
  9. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Thank you for your idea!
    The effect of wind can be set individually in the "Wind Influence" parameter of the [External Force] panel.
    https://magicasoft.jp/en/external-force-2/

    You can set the parameter to 0 to make the component unaffected by the wind.
    Will this feature help you?
     
  10. Natoff

    Natoff

    Joined:
    Feb 24, 2017
    Posts:
    17
    I got error after update to Jobs 0.51.0-preview.32. Problem will be solved by revert back to 0.50.0-preview.x.

    Example message
    Assets\MagicaCloth\Scripts\Core\Physics\Manager\PhysicsManagerParticleData.cs(1356,87): error CS1503: Argument 3: cannot convert from 'out Unity.Collections.NativeMultiHashMapIterator<int>' to 'out Unity.Collections.NativeParallelMultiHashMapIterator<int>'
     
  11. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Thank you for reporting the bug.
    I was able to confirm the problem here as well.
    This is due to the upgrade of Unity's Collections package and the change in class name.
    (To be exact, it seems that some class names have changed due to 1.3.0 of Collections)
    Unity is having a hard time changing the class name on rare occasions without notice.
    Please wait for a while as we will respond from now on.
    Probably you only need to rename the class name, so I think you can update the market immediately.
     
    Natoff likes this.
  12. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Natoff likes this.
  13. eduroam

    eduroam

    Joined:
    Jul 2, 2015
    Posts:
    48
    Hi, great plug in, @hoshos , do you have presets or recommend values to use in a character with a T-shirt?.

    Thanks.
     
  14. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Hello. I have read previous posts about jittering. I have not found a concrete solution to this problem, could you please help me? Thank you:)
     
  15. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    T-shirts can be a little difficult.
    Since Magica Cloth does not have a mesh collider, it is not possible to make an accurate collision judgment according to the shape of the skin.
    So you may suffer from clipping problems.
    If you want to use it, it is better to shake the sleeves and hem part in a limited way, instead of applying it to the whole shirt.
     
  16. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    First of all, can you check when the movement and animation processing is being performed?
    This is either Update () or FixedUpdate ().
    For animation, whether Animator's Update Mode is set to [Animate Physics].
    Do you do both with FixedUpdate ()?
    Or do you use FixedUpdate () on only one side?
     
  17. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Character movement being performed via FixedUpdate(). Animator's Update Mode set to [Animate Physics].
    I didn't understand the question "Do you do both with FixedUpdate()?" If you mean the Update Mod in the MagicaMeshCloth component, then it is set to normal for both (the change to the Unity Physics did not give results).
    I just found out that everything works if the movement being performed is Update(). But unfortunately I need a FixedUpdate, because the frame rate is not constant.
     
  18. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Thank you for your answer.
    If you moved the character with FixedUpdate () and set the Animator to [Animate Physics], you should synchronize by setting the cloth component update mode to [Unity Physics].
    If that doesn't work, something may be wrong.
    It could be a bug in MagicaCloth.
    Are you using the latest version of MagicaCloth?
    Also, what is the Update Mode of Physics Manager set?
    https://magicasoft.jp/en/magica-cloth-physics-manager-2/
     
  19. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    I'm using MagicaClosh v1.12.6, Unity 2020.3.32f1.
    Physics Manager Component have Update Mode: [Unscaled Time] and Update Location: [After Late Update] (Various combinations did not give results)
    MeshCloth component Update Mode to [Unity Physics] didn't not give results:(
     
  20. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    There seems to be no problem with all the settings.
    In the same way, I set Animator to [Animate Physics], prepared a character with the cloth component set to [Update Physics], and moved it with FixedUpdate (), but no vibration occurred.
    Therefore, the cause is not well understood.
    Is it possible to get a prefab or project that can reproduce the problem if possible?
    A sample will help solve the problem.
    If possible, please send it to my [In Box] on this forum or to the following email address:
    support@magicasoft.jp
     
  21. eduroam

    eduroam

    Joined:
    Jul 2, 2015
    Posts:
    48
    I had a similar problem, did you have "Reset After Teleport" activated?. If you do, increase the teleport distance, I see when the player moves "fast", that default value could be too short, creating some "reset" when the player moves.

    I increased the distance, and my problem is gone.

    Regards
     
  22. DrShimizu

    DrShimizu

    Joined:
    Apr 13, 2011
    Posts:
    30
    Hello, thank you for a really cool tool. I have a question:

    I am trying MagicaMeshCloth on hair comprised of many individual strands. I understand that you need to mark the top of the the strands with a red dot to fix it in place. I am finding this process easy some hair models, but totally unmanageable on highly detailed hair models. If you miss hairs then they fall out of the head when the simulation starts. And if you fill in too many dots as red the movement is unatural.

    Really what i would like is some sort of way to ensure that each group of hair is fixed at the top.

    Is there any trick to do this for dense meshes with many overlapping bundles of hair?

    What i am hoping for to be able to click on a dot and have a mode where i can hide everything that isn't topologically connected.
     
  23. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    As eduroam says, it could be an auto-reset issue.
    If [Reset After Teleport] is ON, try turning it OFF by referring to the following document.
    https://magicasoft.jp/en/paramater-world-influence-2/
     
  24. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Thank you for your request.
    We have received many inquiries that it is difficult to paint vertices.
    I am currently working on Version 2 of Magica Cloth.
    And we are working on improving this vertex paint as an important function.
    It will take some time, but I will definitely improve it.
     
  25. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Thanks eduroam for the advice but unfortunately it didn't help. "Reset After Teleport" is disable.
    I sent you a unity package by email. Tried to make it light weight.

    And something else. I use the script from this topic for dressing up and found 2 problems:
    -Сolliders from clothes are not transferred correctly. BeforeDressingUp.png AfterDressingUp.png
    -The character's breast begins to jittering after dressing if the clothes have a Update Mode [Unity Physics], if Update Mode [Normal], then with the breast everything is...Normal:). Video
    Thanks you
     
    Last edited: Jul 10, 2022
  26. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    Thank you for the sample.
    There are some errors, but I was able to confirm the vibration here as well.
    I've analyzed it a bit, but there may be something wrong with the input of the OPSIVE asset.
    Because when I stopped OPSIVE and performed a simple key input movement with FixedUpdate () here, vibration did not occur.
    (The same character and scene are used)
    Therefore, there may be something wrong with OPSIVE.
    I will analyze the details from now on.
    Please give me some time.
    As for the other problem of dressing up, I will investigate when the problem of vibration is found.
     
    eduroam and robintucker3d like this.
  27. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    The cause of the problem has been identified.
    This is due to a special character update process in Opsive assets.
    First, when UpdateLocation is set to [Fixed Update] in UltimateCharacterLocomotion, the character is basically moved using FixedUpdate().
    However, in Opsive, in order to synchronize the character with other characters and the camera, an offset is added in Update() to the character once moved by FixedUpdate(), forcing the character to shift its position.
    This is probably to synchronize the position with the character and camera moved by Update().
    Specifically, see the following source code.

    KinematicObjectManager.cs
    -Update()
    --m_Characters.SmoothMove(interpAmount);
    ---SmoothMove(float interpAmount); // I am adjusting the position of the character here

    In fact, without this process, the camera would not be able to focus on the character correctly.
    This particular move was causing MagicaCloth to malfunction.

    The solution to this problem is to update the other processes within a normal update, not a FixedUpdate.
    This applies to the Animator and MagicaCloth components.
    So try changing all settings to Update for the following components in your project

    - Animator Update Mode = Normal
    - MagicaCloth Update Mode = Normal
    - UltimateCharacterLocomotion UpdateLocation = Fixed Update

    This means that it should be executed as a normal Update process.
    This solves the problem here.
    Please test it.
     
    robintucker3d and Natoff like this.
  28. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Yes, it really does work. Thank you very much for your time:) You and your tool are awesome:)
     
  29. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    I was relieved that the problem was solved.
    I think the problem of chest movement can be solved for the same reason.
     
  30. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Yes. Chest problems were only when MagicaCloth Update Mode = Fixed Update.
    By the way, regarding the problem with the colliders in the script DressUpAPITest. I found that they are due to the current animation. If there is no animation, then the colliders are transferred correctly.
     
  31. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    I don't really understand this.
    What kind of problem are you having?
     
  32. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    I wrote about it above. When dressing a character, colliders do not transfer correctly. In the topic there are 2 images Before and After dressing.
    BeforeDressingUp.png AfterDressingUp.png
     
  33. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    As you pointed out, DressUpAPITest.cs turned out to have two problems.

    (1) Collider is not ported to the correct position when executed during animation
    The cause is that the local coordinates are not written back after changing the parent of the collider.

    (2) Forgot to change the root bone of SkinnedMeshRenderer
    In the case of SkinnedMeshRenderer, rootBone must also be replaced.
    If you don't do this, writing back to the mesh will be strange.

    We will publish DressUpAPITest.cs that fixes these two problems.
    This will probably solve the problem.
    (58-62,103-108 is the changed line.)

    Code (CSharp):
    1. using MagicaCloth;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class DressUpAPITest : MonoBehaviour
    6. {
    7.     /// <summary>
    8.     /// Top object of avatar to be dressed up
    9.     /// </summary>
    10.     public GameObject targetAvatar;
    11.  
    12.     void Start()
    13.     {
    14.         Equip();
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.     }
    20.  
    21.     void Equip()
    22.     {
    23.         Debug.Assert(targetAvatar);
    24.  
    25.         // Create all bone maps for the target avatar
    26.         var targetAvatarBoneMap = new Dictionary<string, Transform>();
    27.         foreach (Transform bone in targetAvatar.GetComponentsInChildren<Transform>())
    28.         {
    29.             if (targetAvatarBoneMap.ContainsKey(bone.name) == false)
    30.             {
    31.                 targetAvatarBoneMap.Add(bone.name, bone);
    32.             }
    33.         }
    34.  
    35.         // Moves this entire equipment under the target avatar.
    36.         transform.SetParent(targetAvatar.transform);
    37.         transform.localPosition = Vector3.zero;
    38.  
    39.         // Swap the bones of the SkinnedMeshRenderer.
    40.         // This is the same as Equipmentizer.cs
    41.         //var skinRendererBoneMap = new Dictionary<string, Transform>();
    42.         var skinRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();
    43.         foreach (var sren in skinRenderers)
    44.         {
    45.             Transform[] newBones = new Transform[sren.bones.Length];
    46.             var bones = sren.bones;
    47.  
    48.             for (int i = 0; i < bones.Length; ++i)
    49.             {
    50.                 Transform bone = bones[i];
    51.                 if (!targetAvatarBoneMap.TryGetValue(bone.name, out newBones[i]))
    52.                 {
    53.                     Debug.Log($"[SkinnedMeshRenderer({sren.name})] Unable to map bone [{bone.name}] to target skeleton.");
    54.                 }
    55.             }
    56.             sren.bones = newBones;
    57.  
    58.             // root bone
    59.             if (targetAvatarBoneMap.ContainsKey(sren.rootBone?.name))
    60.             {
    61.                 sren.rootBone = targetAvatarBoneMap[sren.rootBone.name];
    62.             }
    63.         }
    64.  
    65.         // This is the end of Skinned Mesh Renderer support.
    66.         // From here, replace the bones of the MagicaCloth component.
    67.  
    68.         // Loop all MagicaCloth components
    69.         foreach (var magicaClothComponent in GetComponentsInChildren<CoreComponent>())
    70.         {
    71.             // Get all the bones you are currently using
    72.             Dictionary<string, Transform> useBoneMap = magicaClothComponent.GetUsedComponentBones();
    73.  
    74.             // New bone map to change to
    75.             Dictionary<string, Transform> newBoneMap = new Dictionary<string, Transform>();
    76.  
    77.             foreach (var boneName in useBoneMap.Keys)
    78.             {
    79.                 Transform replaceBone;
    80.                 if (targetAvatarBoneMap.TryGetValue(boneName, out replaceBone))
    81.                 {
    82.                     newBoneMap.Add(boneName, replaceBone);
    83.                 }
    84.                 else if (boneName != magicaClothComponent.name)
    85.                 {
    86.                     Debug.Log($"[MagicaClothComponent({magicaClothComponent.name})] Unable to map bone [{boneName}] to target skeleton.");
    87.                 }
    88.             }
    89.  
    90.             // Swap the bones of the MagicaCloth component
    91.             magicaClothComponent.ReplaceComponentBone(newBoneMap);
    92.         }
    93.  
    94.         // Finally replace all colliders with new avatars
    95.         var colliders = GetComponentsInChildren<ColliderComponent>();
    96.         foreach (var collider in colliders)
    97.         {
    98.             Transform parent = collider.transform.parent;
    99.             if (parent && targetAvatarBoneMap.ContainsKey(parent.name))
    100.             {
    101.                 Transform newParent = targetAvatarBoneMap[parent.name];
    102.  
    103.                 // After changing the parent, you need to write back the local posture and align it.
    104.                 var localPosition = collider.transform.localPosition;
    105.                 var localRotation = collider.transform.localRotation;
    106.                 collider.transform.SetParent(newParent);
    107.                 collider.transform.localPosition = localPosition;
    108.                 collider.transform.localRotation = localRotation;
    109.             }
    110.         }
    111.     }
    112. }
    113.  
     
    robintucker3d and Natoff like this.
  34. robintucker3d

    robintucker3d

    Joined:
    Jul 4, 2022
    Posts:
    8
    Thank you very much for the work you have done. Everything works and works great:)
     
    hoshos likes this.
  35. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    robintucker3d and Natoff like this.
  36. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Natoff likes this.
  37. bluehawk36000

    bluehawk36000

    Joined:
    Nov 14, 2020
    Posts:
    1
    Hi there. So I'm having trouble with my model using a magica bone cloth where toggling on certain parameters - Clamp distance, Clamp rotation, Restore Rotation, and possibly some others is resulting in the mesh linked to the bone to go invisible. Here's an image showing what it looks like. Is this an error on my end? or is it something with magica cloth upload_2022-8-2_13-1-49.png
     
  38. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    I think this is probably a bug in MagicaCloth.
    However, it is not possible to determine the cause from this image alone.
    Can you answer the following questions?

    (1) MagicaCloth and Unity versions
    Currently MagicaCloth v1.12.8 is the latest

    (2) Is it running or editing?
    Does the problem only occur during execution?
    Or does it also happen when editing?

    (3) Transform Posture
    Maybe there is something wrong with the posture of Transform below TailRoot.
    Is there anything special about the Transform under TailRoot?
    For example, are the Transforms below TailRoot exactly overlapping at exactly the same position?
    In that case, will the problem be solved by moving the Transform slightly apart?
     
  39. alchemist_wurzelpurzel

    alchemist_wurzelpurzel

    Joined:
    Sep 4, 2018
    Posts:
    43
    I have finally come back around to this issue of ours and found an error on our end that would lead to this when randomizing the whole character. It is now fixed.

    Thank you for your support and keep up the good work!
     
  40. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    I'm relieved that the problem is solved!
     
  41. alexgg101

    alexgg101

    Joined:
    May 3, 2022
    Posts:
    14
    hi. please can i ask about network setup, if i am running remote server.
    should i have magica physics manager in client + server ?
    or just client?

    i have a player model with magic cloth mesh on it.
     
  42. ZiWord_soft

    ZiWord_soft

    Joined:
    Aug 25, 2021
    Posts:
    1
    When 2.0 is released, will it be compatible with UMA2 functions? I am now using the GameCreator plug-in, taking a while to make the GC plug-in compatible with UMA2, and doing in-game to allow players to customize their characters (excluding clothing), I am looking forward to 2.0 Further reduce workload.
     
  43. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    MagicaCloth is designed to work on the client only.
    Cloth simulations are treated like VFX.
    Therefore, it is not intended to be used to communicate simulation results.
     
    Natoff likes this.
  44. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    I'm not familiar with UMA, so I can't say for certain, but it's probably possible.
    Currently in development v2.0 will be able to build all components at runtime.
    This completely eliminates the work of pre-data construction in the editor.
    In runtime construction, we plan to use textures to specify particle attributes.
    If this isn't a problem, it's probably possible.
     
  45. alexgg101

    alexgg101

    Joined:
    May 3, 2022
    Posts:
    14
    hi. thanks for the info .
     
  46. frg_kova

    frg_kova

    Joined:
    Jul 16, 2015
    Posts:
    16
    Hello, I could use help with changing cloth sim at runtime.
    I have multiple sets of clothes, let's say 2 pair of pants for start. They are both on the same rig / skinned so I can just swap meshes to switch between. How can I change the cloth sim data at runtime? I tried a lot of things and the simulation underneaths seems to be changed skinned mesh renderer is getting borked or stuck.

    What I'm trying is something like this:

    Code (CSharp):
    1.  
    2. var renderDeformer = rendererGO.GetComponent<MagicaRenderDeformer>();
    3. var newRenderDeformer = definition.prefab.GetComponentInChildren<MagicaRenderDeformer>(true);
    4. renderDeformer.Deformer.MeshData = newRenderDeformer.Deformer.MeshData;
    5. ...
    6. var virtualDeformer = rendererGO.GetComponentInChildren<MagicaVirtualDeformer>(true);
    7. var newVirtualDeformer = definition.prefab.GetComponentInChildren<MagicaVirtualDeformer>(true);
    8. virtualDeformer.Deformer.MeshData = newVirtualDeformer.Deformer.MeshData;
    9. ...
    10. var meshCloth = rendererGO.GetComponentInChildren<MagicaMeshCloth>(true);
    11. var newMeshCloth = definition.prefab.GetComponentInChildren<MagicaMeshCloth>(true);
    12. meshCloth.Setup.ChangeData(newMeshCloth, newMeshCloth.Params, newMeshCloth.ClothData);
    13.  
    Appreciate your help!
     
  47. hoshos

    hoshos

    Joined:
    Mar 7, 2015
    Posts:
    922
    Hello.
    The technique of first copying the data of an existing cloth component to another cloth component does not work.
    This is because MagicaCloth does not support data construction at runtime.

    The method is to prepare the costume set up in the Unity editor in advance as a prefab and change it at runtime.
    This is the same as a general costume change method.

    If you port the SkinniedMeshRenderer to a different character, you will need to replace the bones contained in the renderer with the bones of the new character.
    Similarly, the cloth component also needs to replace the bones it holds internally with those of the new character.
    This process requires a little programming.

    The following past post is a sample of how this process is coded.
    https://forum.unity.com/threads/released-magica-cloth.813954/page-19#post-7850178

    First swap the SkinnedMeshRenderer's bones with the new character's bones, then swap the cloth component's bones.
    Consider this method.
     
  48. Natoff

    Natoff

    Joined:
    Feb 24, 2017
    Posts:
    17
    For your information,
    In Mirror or Similar network API you don't need network id or data synchronization for Magica.
    Let each client processes own physic processing.

    Following video shows the result.
     
    hoshos likes this.
  49. Squiver

    Squiver

    Joined:
    Jan 22, 2022
    Posts:
    2
    Hello, wonderful tool! I would also be really eager to see self collision as an option in the future. Currently, I'm having a problem I think would be solved by just that, and was curious to see if you had a suggestion for how to handle this in the meantime.

    I bought Magica Cloth in the hopes of using it on this model, but the geometry of the lightly pleated fabric causes it to clip into itself by way of gravity.
    upload_2022-9-1_2-9-0.png
    upload_2022-9-1_2-8-26.png

    Is there anything that can be done to remedy this using Magica Cloth?
     
  50. frg_kova

    frg_kova

    Joined:
    Jul 16, 2015
    Posts:
    16
    Thanks that helped. At the end we ended up making it work, providing code for anybody interested. The collider copy at the end is not needed if you have them fixed (and not set differently per each piece), but you need to clear and add register fixed colliders with cloth component. Our setup has all 3 cloth components (renderer, virtual, cloth) on one GameObject.

    Code (CSharp):
    1.         private void SetClothSimActive3(AppearanceDefinition definition, GameObject currentAvatarGo)
    2.         {
    3.             // create mapping from name to current bone of current skeleton
    4.             Dictionary<string, Transform> currentBoneMapping = new();
    5.             var currentBones = currentAvatarGo.GetComponentsInChildren<Transform>(true);
    6.             foreach (var bone in currentBones)
    7.             {
    8.                 currentBoneMapping[bone.name] = bone;
    9.             }
    10.  
    11.             // destroy the current renderer and MagicaCloth setup, all in one object
    12.             var originalSkinnedMeshRenderer = currentAvatarGo.GetComponentInChildren<SkinnedMeshRenderer>(true);
    13.             Destroy(originalSkinnedMeshRenderer.gameObject);
    14.  
    15.             // copy the new MagicaCloth components from prefab we're using as new setup
    16.             var originalToCopy = definition.prefab.GetComponentInChildren<MagicaRenderDeformer>(true).gameObject;
    17.             Transform parent = currentAvatarGo.transform;
    18.             var copy = Instantiate(originalToCopy, parent);
    19.  
    20.             // we copied the SkinnedMeshRenderer, it has mapping to bones in the prefab, fix it to map to current bones in instance
    21.             var skinRenderers = copy.GetComponentsInChildren<SkinnedMeshRenderer>();
    22.             foreach (var sren in skinRenderers)
    23.             {
    24.                 Transform[] newBones = new Transform[sren.bones.Length];
    25.  
    26.                 for (int i = 0; i < sren.bones.Length; ++i)
    27.                 {
    28.                     Transform bone = sren.bones[i];
    29.                     if (!currentBoneMapping.TryGetValue(bone.name, out newBones[i]))
    30.                     {
    31.                         Debug.Log($"[SkinnedMeshRenderer({sren.name})] Unable to map bone [{bone.name}] to target skeleton.");
    32.                     }
    33.                 }
    34.                 sren.bones = newBones;
    35.             }
    36.  
    37.             // go through all MagicaCloth components and fix the bone mapping
    38.             foreach (var clothComponent in copy.GetComponentsInChildren<CoreComponent>(true))
    39.             {
    40.                 // get all the bones you are currently using to go through
    41.                 Dictionary<string, Transform> useBoneMap = clothComponent.GetUsedComponentBones();
    42.                 Dictionary<string, Transform> newBoneMap = new();
    43.  
    44.                 foreach (var boneName in useBoneMap.Keys)
    45.                 {
    46.                     Transform replaceBone;
    47.                     if (currentBoneMapping.TryGetValue(boneName, out replaceBone))
    48.                     {
    49.                         newBoneMap.Add(boneName, replaceBone);
    50.                     }
    51.                     else if (boneName != clothComponent.name)
    52.                     {
    53.                         Debug.LogError($"[MagicaClothComponent({clothComponent.name})] Unable to map bone [{boneName}] to target skeleton.");
    54.                     }
    55.                 }
    56.  
    57.                 clothComponent.ReplaceComponentBone(newBoneMap);
    58.             }
    59.  
    60.             // destroy any existing colliders
    61.             // TODO this is bad it will destroy colliders for entire skeleton not just part specific ones
    62.             // We need a script that will track colliders maybe, like MagicaAvatar just ours
    63.             var existingColliders = currentAvatarGo.GetComponentsInChildren<ColliderComponent>();
    64.             foreach (var existingCollider in existingColliders)
    65.             {
    66.                 Destroy(existingCollider);
    67.             }
    68.             // add new colliders
    69.             // TODO it's hard to copy a component, instantiating new game object here, yuck
    70.             var meshCloth = copy.GetComponent<MagicaMeshCloth>();
    71.             var colliders = definition.prefab.GetComponentsInChildren<ColliderComponent>();
    72.             foreach (var collider in colliders)
    73.             {
    74.                 Transform newColliderTransform = collider.transform;
    75.                 if (newColliderTransform == null)
    76.                 {
    77.                     Debug.LogError($"Cannot read parent name of collider.transform is null, is it top in hierarchy?", this);
    78.                     continue;
    79.                 }
    80.                 if (!currentBoneMapping.TryGetValue(newColliderTransform.name, out Transform newParent))
    81.                 {
    82.                     Debug.LogError($"Could not find bone (transform) with name: [{newColliderTransform.name}]", this);
    83.                     continue;
    84.                 }
    85.  
    86.                 newParent.gameObject.SetActive(false);
    87.                 if (collider is MagicaCapsuleCollider capsule)
    88.                 {
    89.                     var componentData = capsule.ToData();
    90.                     var newCollider = newParent.gameObject.AddComponent<MagicaCapsuleCollider>();
    91.                     componentData.CopyValuesTo(newCollider);
    92.                     meshCloth.AddCollider(newCollider);
    93.                 }
    94.                 else if (collider is MagicaPlaneCollider plane)
    95.                 {
    96.                     var componentData = plane.ToData();
    97.                     var newCollider = newParent.gameObject.AddComponent<MagicaPlaneCollider>();
    98.                     componentData.CopyValuesTo(newCollider);
    99.                     meshCloth.AddCollider(newCollider);
    100.                 }
    101.                 else if (collider is MagicaSphereCollider sphere)
    102.                 {
    103.                     var componentData = sphere.ToData();
    104.                     var newCollider = newParent.gameObject.AddComponent<MagicaSphereCollider>();
    105.                     componentData.CopyValuesTo(newCollider);
    106.                     meshCloth.AddCollider(newCollider);
    107.                 }
    108.                 newParent.gameObject.SetActive(true);
    109.             }
    110.  
    111.             copy.SetActive(true);
    112.         }
     
    hoshos likes this.