简体   繁体   中英

How to get only GameObjects that have BlendShapes in Unity

In Unity, if a GameObject has a BlendShape, that GameObject always has a SkinnedMeshRenderer.

So I'm using code like the following to determine if the attached GameObject has BlendShapes.

Test.cs

using UnityEngine;
using System;

public class Test : MonoBehaviour
{
    SkinnedMeshRenderer testSkin;

    // Start is called before the first frame update
    void Start()
    {
        testSkin = GetComponent<SkinnedMeshRenderer>();
        if (testSkin != null)
        {
            Debug.Log("this object have blendShapes");
        }
        else
        {
            Debug.Log("this object don't have blendShapes");
        }
    }
}

However, there are cases that a GameObject has a SkinnedMeshRenderer but not BlendShapes. All objects affected by bone skinning have a SkinnedMeshRenderer.

Is there a way to get only GameObjects that have BlendShape?

You can get the amount of blendshapes via the Mesh.blendShapeCount

so you can filter like

public bool HasBlendShapes()
{
    if(!TryGetComponent<SkinnedMeshRenderer>(out var skinnedMeshRenderer))
    {
        Debug.LogWarning("This object doesn't even have a SkinnedMeshRenderer!", this);
        return false;
    }

    if(!skinnedMeshRenderer.sharedMesh)
    {
        Debug.LogWarning("There is no Mesh attached to this SkinnedMeshRenderer!", this);
        return false;
    }

    if(skinnedMeshRenderer.sharedMesh.blendShapeCount <= 0)
    {
        Debug.Log("this SkinnedMeshRenderer doesn't have blendShapes", this);
        return false;
    }

    Debug.Log($"this SkinnedMeshRenderer has {skinnedMeshRenderer.sharedMesh.blendShapeCount} blendShapes", this);
    return true;
}

Note: Typed on smartphone but I hope the idea gets clear

You can use BlendShape API provided by for Meshes: Mesh Scripting API

As you can see, Unity provides you a blendShapeCount property, or GetBlendShapeName function which returns the name of the blendshape at a specific index. So solutions like this can be helpful for you:

first, get the skinned mesh renderer reference on the gameObject:

var skinnedMesh = gobject.GetComponent<SkinnedMeshRenderer>();
if (!skinnedMesh || !skinnedMesh.sharedMesh) 
{
   Debug.LogError("the game object does not include any mesh on it");
} 

then, check the number of blendShapes on the mesh

if (skinnedMesh.sharedMesh.blendShapeCount > 0) 
{
   Debug.Log("This mesh has blendShapes");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM