2

当玩家进入房间时,我试图让游戏对象列表消失,我能想到的最好方法是逐帧更改材质 alpha。如果有比这种方法更高效的替代方法,请告诉!(并不是说我注意到任何糟糕的表现,因为这看起来很简单)

我希望玩家进入一个房间,并且该列表中的所有游戏对象会同时以相同的速度消失(就好像它们只是一个在运行时改变透明度的对象)但是会发生什么(我我制作了一个视频:https : //youtu.be/z1pz2Te_hDg )有些游戏对象比其他游戏对象更早发生变化,有些消失的速度比预期的要快,最后只是在其他游戏对象之后,这一切看起来都很奇怪。

一次只更改一个对象的 alpha 似乎很好,但由于我需要遍历所有材质,我不能简单地将所有对象作为一个游戏对象的子对象。

我试图通过访问默认“HDPR/Lit”着色器中的默认 alpha 来更改 alpha,而不使用 alpha 属性制作自定义着色器,并且它的行为相同。

这个问题似乎很简单,我觉得我做错了一些愚蠢的事情,但我已经做了几个星期了。

这是我的“RoomTransparencyController”脚本:

bool transparent = false;
public float enhance = 5;
private struct ShaderPropertyIDs {
    public int AlphaRef;
}
private ShaderPropertyIDs shaderProps;
public List<GameObject> gameObjectList;
public List<Material> materialList;

void Start() {
    foreach(GameObject obj in gameObjectList) {
        foreach(Material mat in obj.GetComponent<MeshRenderer>().materials) {
            materialList.Add(mat);
        }
    }

    // Cache property IDs
    shaderProps = new ShaderPropertyIDs() {
        AlphaRef = Shader.PropertyToID("AlphaRef"),
    };
}

void Update() {
    UpdateChildsAlpha3(transparent);
}
private void OnTriggerEnter(Collider col) {
    if(col.tag == "Player") {
        transparent = true;
    }
}

private void OnTriggerExit(Collider col) {
    if(col.tag == "Player") {
        transparent = false;
    }

}

void UpdateChildsAlpha3(bool transparent) {
    foreach(Material mat in materialList) {
        mat.SetFloat("AlphaRef", Mathf.Clamp(mat.GetFloat("AlphaRef") + Time.deltaTime * enhance * (transparent ? -1 : 1), 0, 1));

    }
}

PS:这个脚本应该主要包含一个房间的道具和特定的墙壁,所以每个房间都有一个脚本,里面有它的游戏对象列表,以便更好地组织。所以我认为每个房间都有自己的剧本是组织和复制的最佳方式。

4

2 回答 2

0

如果您希望对象消失,请在所有对象上使用 for 循环Destroy(),如果您希望它们停止可见,只需使用SetActive(). 如果您希望它们工作,但只是停止可见,您可以禁用渲染器组件。

于 2021-12-08T15:47:16.000 回答
0

如果你尝试使用一些补间来解决这个问题会更好。像doTweenLeanTween,他们有一些更好的优化方法来减少 alpha 或任何东西。试着玩弄它。

于 2021-12-08T15:57:29.710 回答