c# - Unity 将网格缝合在一起

标签 c# unity-game-engine mesh

我已经思考这个问题几天了,尝试了一些不同的方法,并且在谷歌上搜索了很多。我专门仔细看了这个帖子

http://forum.unity3d.com/threads/stitch-multiple-body-parts-into-one-character.16485/

但我很困惑,不确定这是否 100% 是我想要的。

我只是想用自己的网格向已有的游戏对象添加一个新的网格。运行相同的骨骼结构或动画师,被添加的对象具有其粘贴位置所需的骨骼。

https://gyazo.com/19778b3c73ef9a749c8cc338f7e49d79

这就是我试图添加到我的播放器上的对象。我尝试直接将网格体从其上取下,然后将其链接到与动画播放器相同的骨骼结构

当使用fuse/mixamo创建并导入对象时,它会将该对象作为单独的网格对象添加到父播放器上

https://gyazo.com/55ce7442dc186756da4ff149ac3543e5

所以如果我要禁用装甲网格ID,就留下这个

https://gyazo.com/09ffd7c7721f46e6980f895a1a873749

但我尝试导入没有盔甲的角色。然后我在 blender 中打开带有玩家和盔甲的角色,删除玩家并留下骨骼结构和盔甲,然后将其保存为单独的FBX并将其导入到Unity中,并将新的盔甲FBX粘贴到原始玩家上尝试让它变得动画化,就像它最初来自 mixmo 对象一样。但它没有,甚至无法将其导入到 Tpose 中。当我自己配置​​它时,它不会保存配置,只是继续返回到原来的位置。

我想我应该......只有盔甲所需的骨头。然后执行某种类型的游戏逻辑来找出盔甲对象上哪些骨骼与添加到玩家的骨骼同名,并用盔甲的骨骼替换玩家骨骼?但我觉得如果我想这样做,那么我需要将播放器分成几部分,以便它知道要替换播放器的哪些部分。或者有没有一种方法可以让玩家保持在一起并让盔甲跟随玩家的骨骼,我想这将是最简单的事情

我很确定我发布的链接正是我想要的。我想我只是不完全理解它,希望有人帮助我更好地理解它

最佳答案

好吧,这篇文章不会解释代码如何工作,而是解释如何让代码正常工作。 Masterprompt 很好地解释了代码 here 。如果您想了解代码的工作原理,请点击该链接。

无论如何,讨论如何将 2 个对象合并在一起以创建一个运行基础对象动画的对象。

示例用途可能是

  • 从肢体创建人肢体。
  • 为基础玩家添加护甲

在没有图形艺术家为我创建资源的情况下,我如何实现这一点的主要方法是使用 fusion 和 mixamo。我强烈推荐这些计划。如果没有这些程序,您仍然可以轻松地完成此操作,但我将解释如何做到这一点,就好像您正在使用它一样。

好的,下载 Adob​​e fusion 并创建您的基础播放器。 (最好是裸体) 现在将该播放器保存为您想要的任何内容(我使用 Main_Player_Naked) 将此播放器上传到 mixamo 进行 Autowiring ,从 mixamo 下载模型后将其导入到 unity 中。 (此时我假设您知道如何将模型设置为统一的人形机器人)

现在您的玩家已创建并导入到 Unity 中,可以继续为他设置动画或对他做任何您想做的事情。无论你对他做什么,无论你为你的玩家添加什么,都会与新的盔甲/头发/ mustache 配合良好。

好的,现在是时候创建我们要添加的盔甲了。继续并在 fusion 中重新打开您的裸体玩家,并使用您希望他拥有的新 Assets 重新创建他(不要更改任何 body 形状尺寸,只需添加新对象)。 (别担心,我们不会切换整个模型,这只是为了让我们不必自己装备新 Assets )既然新 Assets 看起来不错,请继续执行以下第一步:创造裸体演奏。因此,请保存新创建的角色并导入 mixamo 进行 Autowiring 。现在下载新播放器并将其导入到 Unity 中。删除播放器上除新资源之外的所有对象(新资源位于对象下方的裸玩家的单独网格上)

现在我们将使用 Masterprompts 帖子中的代码

我已经重写了它,所以这是我的新代码

using UnityEngine;
using System.Collections;

public class CreatePlayer : MonoBehaviour
{

    public GameObject objPlayer;
    public GameObject objLimb;
    public GameObject objAdded;


    // Use this for initialization
    void Start()
    {
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.H))
            AddLimb(objLimb, objPlayer);
        if (Input.GetKeyDown(KeyCode.J))
            Destroy(objAdded);
    }

    // 

    void AddLimb(GameObject BonedObj, GameObject RootObj)
    {
        var BonedObjects = BonedObj.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
        foreach (SkinnedMeshRenderer SkinnedRenderer in BonedObjects)
        {
            ProcessBonedObject(SkinnedRenderer, RootObj);
        }
    }

    private void ProcessBonedObject(SkinnedMeshRenderer ThisRenderer, GameObject RootObj)
    {
        /*      Create the SubObject        */
        var NewObj = new GameObject(ThisRenderer.gameObject.name);
        NewObj.transform.parent = RootObj.transform;
        /*      Add the renderer        */
        NewObj.AddComponent<SkinnedMeshRenderer>();
        var NewRenderer = NewObj.GetComponent<SkinnedMeshRenderer>();
        /*      Assemble Bone Structure     */
        var MyBones = new Transform[ThisRenderer.bones.Length];
        for (var i = 0; i < ThisRenderer.bones.Length; i++)
            MyBones[i] = FindChildByName(ThisRenderer.bones[i].name, RootObj.transform);
        /*      Assemble Renderer       */
        NewRenderer.bones = MyBones;
        NewRenderer.sharedMesh = ThisRenderer.sharedMesh;
        NewRenderer.materials = ThisRenderer.materials;
        objAdded = NewObj;
    }


    private Transform FindChildByName(string ThisName,Transform ThisGObj)
    {
        Transform ReturnObj;
        if( ThisGObj.name==ThisName )
            return ThisGObj.transform;
        foreach (Transform child in ThisGObj)
        {
            ReturnObj = FindChildByName( ThisName, child );
            if( ReturnObj )
                return ReturnObj;
        }
        return null;
    }
}

这很快就被拼凑起来了。我建议让它变得更好。

但只需添加裸播放器 objPlayer 和要添加到 objLimb 的资源即可。

运行游戏并按“H”创建 Assets ,按“J”删除 Assets 。

关于c# - Unity 将网格缝合在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38407911/

相关文章:

c++ - directX 中的网格动画

C# "Enum"序列化 - 反序列化为静态实例

c# - 在C#中产生两个列表项的集合差异

c# - 无法使用 keyboard.sendkeys 发送逗号

mysql - 跟踪玩家何时进入/离开游戏中的区域

python - 将网格导入 Fipy 后如何从 python 访问 gmsh 代码?

c# - 使用 html 敏捷包访问 2nd TR 的 2nd TD 的内部文本?

ios - UnityEditor.BuildPlayerWindow+BuildMethodException : when building Unity project for iOS

c# - 淡入/淡出游戏对象

c# - Unity C# 生成的网格是偏移的,为什么它不在正确的位置?