the corpse disappears if I get too close to it

JablDouble

New member
1685736380041.png1685736441013.png1685736403824.png

When I kill an AI, it falls down using Ragdoll and it works fine if I'm standing far away, but if I get close, the head disappears, and if I get even closer, the body and hands disappear
 

Attachments

  • 1685736239028.png
    1685736239028.png
    654.4 KB · Views: 1
  • 1685736342844.png
    1685736342844.png
    659.1 KB · Views: 1
I am having the same issue, its definitely the skinned mesh renderer bounds. You can enable Update When Offscreen on them, but this has a performance hit. Looking for a better solution, might just write a script to recalculate the bounds every few seconds while ragdolled.
 
This seems to have a bit better performance than setting Update When Offscreen always on. Just add it to gameobject with the skinned mesh renderers that are disappearing. It could probably be optimized further to only update if the position changed. If the ragdoll can't be interacted with and won't move you could just set it once instead of updating.

C#:
using Opsive.Shared.Events;
using System.Collections;
using UnityEngine;

public class RagdollSkinnedMeshUpdateBounds : MonoBehaviour
{
    [SerializeField]
    private GameObject characterGO;
    [SerializeField]
    private SkinnedMeshRenderer skinnedMeshRenderer;
    [SerializeField]
    private float boundsUpdateFrequency = 1;

    private float t;
    private bool updateBounds;
    private Bounds originalBounds;

    // Start is called before the first frame update
    void Start()
    {
        EventHandler.RegisterEvent<Vector3, Vector3, GameObject>(characterGO, "OnDeath", OnDeath);
        EventHandler.RegisterEvent(characterGO, "OnRespawn", OnRespawn);
    }
    private void OnDestroy()
    {
        EventHandler.UnregisterEvent<Vector3, Vector3, GameObject>(characterGO, "OnDeath", OnDeath);
        EventHandler.UnregisterEvent(characterGO, "OnRespawn", OnRespawn);
    }

    private void OnRespawn()
    {
        updateBounds = false;
        StopAllCoroutines();
        skinnedMeshRenderer.updateWhenOffscreen = false;
        skinnedMeshRenderer.localBounds = originalBounds;
        t = 0;
    }

    private void OnDeath(Vector3 arg1, Vector3 arg2, GameObject arg3)
    {
        originalBounds = skinnedMeshRenderer.localBounds;
        //Update the bounds immediately
        StartCoroutine(UpdateSkinnedMeshBounds());
        updateBounds = true;
    }

    // Update is called once per frame
    void Update()
    {
        if (updateBounds)
        {
            t += Time.deltaTime;
            if(t >= boundsUpdateFrequency)
            {
                StartCoroutine(UpdateSkinnedMeshBounds());
                t = 0;
            }
        } 
    }

    //Update the skinned mesh renderer bounds for a single frame to match the ragdolls mesh position
    private IEnumerator UpdateSkinnedMeshBounds()
    {
        if (skinnedMeshRenderer == null)
        {
            Debug.LogError("Skinned Mesh Renderer is null.");
            yield break;
        }
        skinnedMeshRenderer.updateWhenOffscreen = true;
        yield return null;
        var newBounds = skinnedMeshRenderer.localBounds;
        skinnedMeshRenderer.updateWhenOffscreen = false;
        skinnedMeshRenderer.localBounds = newBounds;
    }
}
 
You can just manually set the bounds on your character, no need to update it. Just be sure when tuning the bounds, that you have the correct root object for the bounds to move with, and also ensure that the bounds are just slightly larger than the largest extent of where any part of the mesh can be at its most extreme bone rotation.
 
Top