当存在多个相同的对象时,如何使用 OnCollisionEnter 对对象进行更改?

问题描述 投票:0回答:1

所以我正在练习Unity的脚本并尝试构建Pachinko游戏的原型。 我想要实现的是,当球撞到障碍物时,它会改变颜色(材质) - 我已经实现了。但我想要两秒后把材料改回来,这是我不知道如何进行的地方。

问题在于,当球在 2 秒标记之前撞到另一个障碍物时,OnCollisionEnter(Collision other) 中的另一个被分配给新障碍物,因此将新障碍物的材质更改回来。

这是我的简单代码,使用函数来更改材质,并在 2 秒内调用它。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CollisionBehavior : MonoBehaviour
{
    [SerializeField] Material mats;
    [SerializeField] Material defaultMats;
    Renderer meshRenderer;

    void OnCollisionEnter(Collision other) {
        if (other.gameObject.tag == "Obstacle") {
            meshRenderer = other.gameObject.GetComponent<Renderer>(); 
            meshRenderer.material = mats;

            Invoke("ChangeMatBack", 2);
        }
    }
    void ChangeMatBack() {
        meshRenderer.material = defaultMats;
    }

}

我也尝试过使用Coroutine,但问题是一样的。

void OnCollisionEnter(Collision other) {
        if (other.gameObject.tag == "Obstacle") {
            meshRenderer = other.gameObject.GetComponent<Renderer>(); 
            meshRenderer.material = mats;

            // Invoke("ChangeMatBack", 2);
            StartCoroutine(waiting());
        }
    }
    // void ChangeMatBack() {
    //     meshRenderer.material = defaultMats;
    // }
    IEnumerator waiting() {
        yield return new WaitForSeconds(2f);
            meshRenderer.material = defaultMats;
    }

所以 TLDR,OnCollisionEnter 函数应该使材质变得像 初始 -> 因点击而更改 -> 等待两秒 -> 初始。

c# unity-game-engine collision monodevelop unityscript
1个回答
0
投票

如果我理解正确的话,您需要做的就是传递您想要重置的相应

Renderer
的参考:

[SerializeField] private Material mat;

private void OnCollisionEnter(Collision other) 
{
    if (!other.gameObject.CompareTag("Obstacle")) return;
    
    var meshRenderer = other.gameObject.GetComponent<Renderer>(); 
    var defaultMaterial = meshRenderer.material;
    meshRenderer.material = mat;

    StartCoroutine(meshRenderer, defaultMaterial); 
}

private IEnumerator ResetRoutine(Renderer renderer, Material[] defaultMaterials)
{
     yield return new WaitForSeconds(2f);

     meshRenderer.material = defaultMaterial;
}

OnCollisionEnter
甚至可以是一个协程本身,你甚至可以简单地这样做:

[SerializeField] private Material mat;

private IEnumerator OnCollisionEnter(Collision other) 
{
    if (!other.gameObject.CompareTag("Obstacle")) yield break;
    
    var meshRenderer = other.gameObject.GetComponent<Renderer>(); 
    var defaultMaterial = meshRenderer.material;
    meshRenderer.material = mat;

    yield return new WaitForSeconds(2f);

    meshRenderer.material = defaultMaterial;
}
© www.soinside.com 2019 - 2024. All rights reserved.