Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Other questions about Obi Cloth
#2
Hi! I'll answer here so that others can benefit from the info, if you don't mind Sonrisa

1) This is a very difficult problem, because using kinect you can't limit the user's motion speed in any way to keep tunneling under control. Also, there's no easy way to know when the cloth has passed trough the leg, as colliders only have a notion of "inside the collider" or "outside the collider". However this does not give you any info regarding which side of the collider is considered valid and which one is undesirable.

Things I'd try:

- Make sure Obi's CCD can do its work. For this, all character limbs need to report linear and angular velocity vectors back to Obi so that the movement of the colliders can be predicted during collision detection. The ObiKinematicVelocities component should do a fine job at this, improving tunneling prevention. Add it to all limb colliders.

- Reduce the physics timestep, as well as kinect's refresh ratio (if possible). Making sure the character moves less from one simulation step to the next will greatly reduce the chances of tunneling.

2) Try appending the new particle groups after saving the blueprint as an asset. Particle groups are sub-assets, so they will not be saved if there's no physical file to save them to yet.

3) First and more importantly: you can't call any Unity API methods from outside the main thread, except for a few ones such as Debug.Log(). This is a basic limitation of Unity, and the reason why you can't generally use multithreading unless you're very careful.

Generate() is a coroutine, as evidenced by its return type: IEnumerator. As such, its purpose is to "spread" work over multiple frames so that the main thread is not blocked for too long. You can even show a progress bar if needed, this is what it's done in editor to inform the user of the generation progress. However you can't call a coroutine that uses the Unity API from a thread other than the main thread. Coroutines are designed to allow for easy concurrency without parallelism, so no need to use threads if all you need is concurrency. If you're unfamiliar with coroutines, see: https://docs.unity3d.com/Manual/Coroutines.html

The IEnumerator.MoveNext() method is an internal C# method. It's used to move to the next enumerator element. In the case of coroutines, it advances the coroutine until the next yield instruction. Calling MoveNext() in a loop basically ensures the coroutine is completed before continuing execution. If any exception happens before reaching the next yield (in this case, the exception is caused by a call to a Unity API method from outside the main thread), it will be thrown by MoveNext(). See: https://docs.microsoft.com/es-es/dotnet/...etcore-3.1

So in short, use coroutines as they're intended to be used Guiño:

Code:
yield return StartCoroutine(blueprint.Generate());

If you capture the return value of the coroutine and advance it yourself instead of yielding, you can do:

Code:
IEnumerator coroutine = blueprint.Generate();
CoroutineJob.ProgressInfo progressInfo;

do{
    if (!coroutine.MoveNext())
        progressInfo = null;
    else
        progressInfo = coroutine.Current as CoroutineJob.ProgressInfo;
            
        // write your own method to update or show a progress bar: userReadableInfo contains info about what the coroutine is currently doing,
        // progress is a float ranging from 0 to 1 that represent the percentage of completion.
    ShowProgressBar(progressInfo.userReadableInfo, progressInfo.progress);
}while (progressInfo != null);

best regards!
Reply


Messages In This Thread
Other questions about Obi Cloth - by nexar - 03-09-2020, 05:50 AM
RE: Other questions about Obi Cloth - by josemendez - 03-09-2020, 07:35 AM