Unity中静态变量inDamage值未改变的问题求助
问题分析与解决方案
核心问题
- 循环内重复覆盖变量值:在
RaycastWithReflection的while循环中,每一次迭代都会重新赋值Vampire.inDamage,最终变量值会被最后一次射线检测的结果覆盖。比如射线先命中Player,后续反射到镜子或空区域时,会把之前设为true的值又改成false。 - 空引用风险:当射线没有命中任何碰撞体时,
hitInfo.collider为null,直接调用CompareTag会触发NullReferenceException。
修复步骤
- 初始化局部bool变量,记录整个射线路径中是否命中过Player
- 仅在射线命中Player时将该局部变量设为true,其他情况保留原有值(不覆盖)
- 循环结束后,再将局部变量的值统一赋值给
Vampire.inDamage - 增加空引用判断,避免运行时报错
修改后的完整代码
public class Light : MonoBehaviour { public int DefaultLength = 10; // 修正拼写错误:Lenght → Length public int MaxReflectionCount = 5; // 最大反射次数 private List<Vector3> _hitPoints = new List<Vector3>(); private LineRenderer _lineRenderer; void Awake() { _lineRenderer = GetComponent<LineRenderer>(); } void FixedUpdate() { RaycastWithReflection(); } private void RaycastWithReflection() { _hitPoints.Clear(); _hitPoints.Add(transform.position); Ray2D ray2D = new Ray2D(transform.position, transform.right); // 初始化局部变量,记录是否命中Player bool isHitPlayer = false; while (_hitPoints.Count <= MaxReflectionCount) { RaycastHit2D hitInfo = Physics2D.Raycast(ray2D.origin, ray2D.direction, 10); // 先处理空引用情况 if (hitInfo.collider != null) { if (hitInfo.collider.CompareTag("Mirror")) { _hitPoints.Add(hitInfo.point); ray2D.origin = hitInfo.point - ray2D.direction * 0.01f; ray2D.direction = Vector2.Reflect(ray2D.direction, hitInfo.normal); } else if (hitInfo.collider.CompareTag("Untagged")) { _hitPoints.Add(hitInfo.point); } // 检测是否命中Player,只在命中时设为true,不覆盖之前的true if (hitInfo.collider.CompareTag("Player")) { isHitPlayer = true; } } else { // 未命中任何物体,添加默认长度的终点 _hitPoints.Add(ray2D.origin + ray2D.direction * DefaultLength); } } // 循环结束后统一赋值静态变量 Vampire.inDamage = isHitPlayer; _lineRenderer.positionCount = _hitPoints.Count; _lineRenderer.SetPositions(_hitPoints.ToArray()); } }
额外优化建议
- 如果
Vampire脚本不需要全局共享inDamage状态,建议改为非静态变量,通过FindObjectOfType<Vampire>()或在Inspector中引用的方式获取实例,避免静态变量带来的全局状态冲突问题。 - 代码中修正了拼写错误
DefaultLenght改为DefaultLength,避免潜在的逻辑错误。
内容的提问来源于stack exchange,提问作者Jrtq
相关产品推荐
相关产品推荐

