c# - 更改许多相同游戏对象之一的颜色

标签 c# unity3d

我有一个太空射击游戏,玩家可以在其中为他们的飞船选择一种颜色,这也适用于飞船发射的子弹。这些船使用相同的子弹预制件,所以我想在游戏中创建子弹后更改它的颜色。我最初使用以下代码来更改颜色。

Material bulletMat = this.GetComponent<MeshRenderer>().sharedMaterial;
if (bulletMat != null)
{
   bulletMat.SetColor("_TintColor", color);
}

但是,我发现这会改变 Material 的颜色,并且每创建一个子弹,子弹就会在颜色之间切换。在做了更多研究之后,我遇到了 MaterialPropertyBlock 变量和以下教程 http://thomasmountainborn.com/2016/05/25/materialpropertyblocks/ .所以我按照本教程设置了以下代码。

public Renderer renderer;
public MaterialPropertyBlock matBlock;
public Color color;
public bool colorSet = false;
void Awake()
{
    renderer = this.GetComponent<Renderer>();
    matBlock = new MaterialPropertyBlock();
}
public void ColorSet(Color color)
{
    this.color = color;
    this.colorSet = true;           

}

void Update()
{
    if (this.colorSet)
    {
        renderer.GetPropertyBlock(matBlock);
        matBlock.SetColor("_Color", this.color);
        renderer.SetPropertyBlock(matBlock);
    }
}

然而,与之前解决方案相同的问题发生了....

谁能帮我弄清楚如何为每个项目符号设置颜色?

最佳答案

只有在您真正想要更改使用此 Material 的每个对象的 Material 时,您才可以使用sharedMaterial。那正是你不想做的。相反,您必须使用 material,这样您只需更改 Material 的“克隆”实例。


如果您这样做,Unity 实际上会仅为该对象自动实例化当前 Material 的本地副本:

public class ColorChanger : MonoBehavior
{
    private MeshRenderer meshRenderer;

    private void OnEnable()
    {
        meshRenderer = GetComponent<MeshRenderer>();
    }

    public void SetColor(Color newColor)
    {
        renderer.material.color = newColor;
    }
}

或者使用 SetColor 我猜应该也能达到同样的效果

public void SetColor(Color newColor)
{
    renderer.material.SetColor("_TintColor", newColor);
}

我个人觉得前面提到的那个更容易。但是第二个给你更多的控制权,因为你可以,例如还可以更改 emitColor,这在其他方面是不可能的。


现在,当你实例化你的子弹时,确保你首先实例化预制件,然后使用上面的组件更改颜色:

public GameObject bulletPrefab;
public Color myColor;
public GameObject Hand;

private void Shoot()
{
    // There are various ways for Instantiate e.g. providing start position and rotation or also the parent object
    // Since it shall be fired from the player I'll assume here there is a "Hand" object from which you want to fire
    // and that you want to add the bullet directly to the hierarchy without a parrent
    GameObject newBullet = Instantiate(bulletPrefab, Hand.position, Hand.rotation);
    // Now we get the color change component
    ColorChanger colorChanger = newBullet.GetComponent<ColorChanger>();
    // And set the color
    colorChanger.SetColor(myColor);
}

注意:
如果这是一个多人游戏,子弹应该只在服务器上实例化,所以你必须首先让服务器知道子弹应该是哪种颜色,然后在 Network 之后将此信息提供给所有玩家。生成它们。

关于c# - 更改许多相同游戏对象之一的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51868648/

相关文章:

c# - Mono MVC5 - View 不起作用

c# - 统一: Detect if the Return or Done key was pressed in the native iOS keyboard

android - Unity Android 构建时出错 - 此构建中使用了已弃用的 Gradle 功能,使其与 Gradle 6.0 不兼容

unity3d - 如何让游戏音频在某一点循环播放

c# - 如何在 xamarin.forms 中获取 ListView 的子级?

c# - 在同一 App.Config 中使用 ConnectionStrings 和自定义 ConfigSections

c# - JwtToken - 声明名称 JwtTokenTypes.Subject 解析为 ClaimTypes.NameIdentifier,这是为什么以及如何防止?

c# - 使用 Moq 和 xUnit 模拟和测试 LogError 消息

c# - 在 C# 中用另一个对象实例替换对象实例

android - 使用Unity编译后是否可以读取apk文件脚本?