c# - UNITY-仅更改 3D 模型颜色的某些部分

标签 c# unity3d 3d modeling 3d-modelling

我真的是 unity3D 的新手,我想问一个问题 我有一个 3D 人体模型(默认的统一模型),它具有分层骨骼结构。

我想在这里实现的是,当我按下某个触发器时,我想用不同的颜色给它的一个肢体上色(只是它的一个肢体)。这是我想要实现的目标的说明

enter image description here

我对此真的一无所知,因为我大约 3 个月前才开始学习 Unity,所以我真的需要你的帮助,如果有帮助的话,这是我的渲染器的属性

enter image description here

最佳答案

我只是想补充一点,使用 projectors 可能有更简单的方法来实现您想要的效果.这是unity中常用的工具,用来实时在mesh表面绘制各种效果,比如弹孔。使用相同的原理,您可以突出显示网格的某些区域。你可以把投影仪想象成手电筒,它的光照射到的所有东西都会改变它的质地。 Standard Assets/Effects 下有一些示例投影仪。您可能想从这里开始。

要创建投影仪,请创建一个空游戏对象 => 添加组件 => 投影仪。

编辑

您可能想尝试的另一个想法是使用 vertex colors .除了坐标之外,网格的每个顶点还包含一个颜色参数,该参数可通过着色器访问。因此,您可以更改特定顶点集的颜色以突出显示它们。这里有两点需要注意:

1) 大多数着色器选择忽略顶点颜色, Sprite 着色器除外。您将需要一个自定义着色器,例如 this one .

2) 你需要以某种方式知道你想要突出显示哪些顶点。你可以做的是遍历 Mesh.boneWeights .例如,如果你想选择一个 ARM ,你需要的是 ARM 骨骼索引的权重 > 1 的所有顶点。你如何找到 ARM 骨指数?该索引对应于SkinnedMeshRenderer.bones中的索引.或者只是选择一些您确定属于 ARM 的顶点并查看其骨骼权重以找到索引。

这里是一个示例脚本,它根据选定的骨骼索引更改顶点颜色。将它附加到您的 SkinnedMeshRenderer(通常是二级层次结构对象):

using UnityEngine;
using System.Collections;

public class BoneHiglighter : MonoBehaviour {

    public Color32 highlightColor = Color.red;
    public Color32 regularColor = Color.white;

    public SkinnedMeshRenderer smr;

    // Just for sake of demonstration
    public Transform bone;
    private Transform prevBone;


    // Find bone index given bone transform
    int GetBoneIndex(Transform bone) {
        Debug.Assert(smr != null);
        var bones = smr.bones;

        for (int i = 0; i < bones.Length; ++i) {
            if (bones[i] == bone) return i;
        }

        return -1;
    }

    // Change vertex colors highlighting given bone
    void Highlight(Transform bone) {
        Debug.Assert(smr != null);
        var idx = GetBoneIndex(bone);
        var mesh = smr.sharedMesh;
        var weights = mesh.boneWeights;
        var colors = new Color32[weights.Length];

        for (int i = 0; i < colors.Length; ++i) {
            float sum = 0;
            if (weights[i].boneIndex0 == idx && weights[i].weight0 > 0)
                sum += weights[i].weight0;
            if (weights[i].boneIndex1 == idx && weights[i].weight1 > 0)
                sum += weights[i].weight1;
            if (weights[i].boneIndex2 == idx && weights[i].weight2 > 0)
                sum += weights[i].weight2;
            if (weights[i].boneIndex3 == idx && weights[i].weight3 > 0)
                sum += weights[i].weight3;

            colors[i] = Color32.Lerp(regularColor, highlightColor, sum);
        }

        mesh.colors32 = colors;

    }

    void Start() {
        // If not explicitly specified SkinnedMeshRenderer try to find one
        if (smr == null) smr = GetComponent<SkinnedMeshRenderer>();
        // SkinnedMeshRenderer has only shared mesh. We should not modify it.
        // So we make a copy on startup, and work with it.
        smr.sharedMesh = (Mesh)Instantiate(smr.sharedMesh);

        Highlight(bone);
    }

    void Update() {
        if (prevBone != bone) {
            // User selected different bone
            prevBone = bone;
            Highlight(bone);
        }
    }
}

查看示例项目:https://www.dropbox.com/s/yfoqo44bubcr48s/HighlightBone.zip?dl=0

演示:http://jolly-squirrel.droppages.com/bones/index.html - 单击 body 部位以查看突出显示的部分。

关于c# - UNITY-仅更改 3D 模型颜色的某些部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34460587/

相关文章:

c# - 在 .NET (C#) web 服务中本地返回 XML?

macos - 协同设计/打包后 OSX Mac 商店应用程序联网失败

c# - Unity3d - 在播放模式下加载特定场景

python - 如何在 matplotlib 中为 3D 散点图上的数据点着色

javascript - 产品库 - 该网站如何为每种可能的组合生成图像

c# - 使用 ValidateSet 为强制 Cmdlet 参数提供默认值

需要 C# 正则表达式

c# - Sitecore:使用 LINQ 与 ID 进行比较的有效方法

android - 设置安卓 :launchmode for UnityPlayerActivity

Java LWJGL - 3D 模型上的碰撞检测?