如何通过相机射线检测单独逐个修改区域对象颜色?
双相机扫描单区域渐变变红问题解决
问题根源
- 原
ChangeColour协程遍历所有zones材质数组,调用一次就会把所有区域变红,没有针对射线命中的单个对象处理 - 射线检测后未提取命中对象的对应材质,直接操作整个材质数组
Update每帧调用StartFadeToRed,重复启动多个协程导致颜色逻辑混乱- 第一人称相机的射线检测未判断命中对象是否为"Zone"标签,可能误触发非目标对象
修正后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ZoneController : MonoBehaviour { private Camera frontViewCamera; private Camera topDownCamera; public float speed = 0.05f; private Color startColor = Color.white; private Color endColor = Color.red; // 防止重复启动渐变协程 private bool isFading = false; void Start() { frontViewCamera = GameObject.FindGameObjectWithTag("FrontFaceCam").GetComponent<Camera>(); topDownCamera = GameObject.FindGameObjectWithTag("TopDownCam").GetComponent<Camera>(); // 初始化所有Zone对象为白色 foreach (var zoneRenderer in FindObjectsOfType<MeshRenderer>()) { if (zoneRenderer.CompareTag("Zone")) { zoneRenderer.material.color = startColor; } } } /// <summary> /// 仅对目标材质执行红变渐变 /// </summary> /// <param name="targetMaterial">要渐变的材质</param> private IEnumerator ChangeColour(Material targetMaterial) { isFading = true; float tick = 0f; // 重置目标材质初始颜色为白色 targetMaterial.color = startColor; // 用tick进度判断,避免浮点数精度导致循环无法终止 while (tick < 1f) { tick += Time.deltaTime * speed; targetMaterial.color = Color.Lerp(startColor, endColor, tick); yield return null; } // 确保最终颜色准确设置为红色 targetMaterial.color = endColor; isFading = false; } private void StartFadeToRed() { // 已有渐变在运行时直接返回,避免冲突 if (isFading) return; Camera activeCamera = frontViewCamera.enabled ? frontViewCamera : topDownCamera; Ray ray = activeCamera.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); if (Physics.Raycast(ray, out RaycastHit hit) && hit.collider.CompareTag("Zone")) { Debug.DrawRay(ray.origin, ray.direction * 10, Color.red); // 获取命中对象的MeshRenderer材质 Material targetMat = hit.collider.GetComponent<MeshRenderer>().material; StartCoroutine(ChangeColour(targetMat)); } } void Update() { StartFadeToRed(); } }
关键修改说明
- 移除静态材质数组:改为通过
Zone标签动态查找所有目标对象,无需手动维护数组,扩展性更强;如果需要固定目标集合,可保留zones数组但修改协程逻辑 - 协程改为单目标处理:
ChangeColour接收单个材质参数,只对射线命中的对象执行渐变,解决所有区域同时变红的问题 - 添加渐变锁:
isFading变量避免Update每帧重复启动协程,防止多个渐变逻辑冲突 - 统一相机处理逻辑:自动识别当前激活的相机,简化射线检测代码,同时确保两种相机都只响应
Zone标签对象 - 优化渐变终止条件:用
tick < 1f替代颜色相等判断,规避浮点数精度误差导致的循环死锁
内容的提问来源于stack exchange,提问作者Nnacheta Nnyagu
相关产品推荐
相关产品推荐

