private void UpdateRay() { for (int i = 0; i < Rays.Count; i++) { RayPool.Instance.Disable(Rays[i]); } Rays.Clear(); _waitRay.Clear(); for (int i = 0; i < Emiters.Count; i++) { EnqueueWaitRay(Emiters[i].Emit()); } while (_waitRay.Count > 0) { LineRay ray = _waitRay.Dequeue(); ray.CastTrigger = null; for (int i = 0; i < Triggers.Count; i++) { Triggers[i].FastCast(ray); } if (ray.CastTrigger != null) { LineRay[] newRays; ray.CastTrigger.Cast(ray, out newRays); EnqueueWaitRay(newRays); } Rays.Add(ray); } }
public LineRay[] Emit() { LineRay ray = RayPool.Instance.Get(); ray.RayColor = EmitColor; ray.StartPoint = transform.position; ray.Angle = transform.eulerAngles.z; ray.ReflectionLife = ReflectionLife; ray.RefractionLife = RefractionLife; return(new LineRay[] { ray }); }
//反射 private void Reflect(LineRay ray, List <LineRay> outRays) { Vector3 outDir = Vector3.Reflect(ray.transform.right, (transform.position - ray.EndPoint).normalized); LineRay newRay = RayPool.Instance.Get(); newRay.Angle = Vector3.SignedAngle(outDir, Vector3.right, Vector3.back); newRay.StartPoint = ray.EndPoint + newRay.transform.right * 0.001f; newRay.ReflectionLife = ray.ReflectionLife; newRay.RefractionLife = ray.RefractionLife; newRay.RayColor = ray.RayColor; newRay.RayColor *= Transmitter.ReflectMultColor; newRay.RayColor += Transmitter.ReflectAddColor; outRays.Add(newRay); }
public override void FastCast(LineRay ray) { float sqrRadius = Radius * Radius; Vector3 pos = (ray.StartPoint - transform.position); Vector3 dir = ray.transform.right; if (Vector3.Dot(pos, pos) >= sqrRadius && Vector3.Dot(pos, dir) >= 0) { return; } float a = dir.sqrMagnitude; float b = Vector3.Dot(dir, pos) * 2f; float c = pos.sqrMagnitude - sqrRadius; float deta = b * b - 4f * a * c; if (deta < float.Epsilon) { return; } else { float t1 = (-b + Mathf.Sqrt(deta)) / 2 / a; float t2 = (-b - Mathf.Sqrt(deta)) / 2 / a; if (t1 > 0f && ray.Length > t1) { ray.Length = t1; ray.CastTrigger = this; } if (t2 > 0f && ray.Length > t2) { ray.Length = t2; ray.CastTrigger = this; } } }
//折射 private void Refract(LineRay ray, List <LineRay> outRays) { Vector3 normal = (transform.position - ray.EndPoint).normalized; float input = Vector3.Angle(ray.transform.right, normal); float signInput = Vector3.SignedAngle(ray.transform.right, normal, Vector3.back); if (input >= Mathf.Asin(Transmitter.RefractiveIndex) * Mathf.Rad2Deg) { return; } LineRay newRay = RayPool.Instance.Get(); float output; if (Vector3.Dot(ray.transform.right, normal) > 0f) { output = Mathf.Asin(1f / Transmitter.RefractiveIndex * Mathf.Sin(input * Mathf.Deg2Rad)) * Mathf.Rad2Deg; newRay.Angle = (normal).ToAngle() + Mathf.Sign(signInput) * output; } else { output = Mathf.Asin(Transmitter.RefractiveIndex * Mathf.Sin(input * Mathf.Deg2Rad)) * Mathf.Rad2Deg; newRay.Angle = (-normal).ToAngle() - Mathf.Sign(signInput) * output; } newRay.StartPoint = ray.EndPoint + newRay.transform.right * 0.001f; newRay.ReflectionLife = ray.ReflectionLife; newRay.RefractionLife = ray.RefractionLife; newRay.RayColor = ray.RayColor; newRay.RayColor *= Transmitter.RefractMultColor; newRay.RayColor += Transmitter.RefractAddColor; outRays.Add(newRay); }
public override void Cast(LineRay ray, out LineRay[] outRays) { outRays = null; List <LineRay> rays = new List <LineRay>(); if (Transmitter.Reflect) { if (ray.ReflectionLife > 0) { ray.ReflectionLife--; Reflect(ray, rays); } } if (Transmitter.Refract) { if (ray.RefractionLife > 0) { ray.RefractionLife--; Refract(ray, rays); } } outRays = rays.ToArray(); }
public virtual void FastCast(LineRay ray) { }
public virtual void Cast(LineRay ray, out LineRay[] outRays) { outRays = null; }
public void Disable(LineRay ray) { _unactiveList.Add(ray); ray.gameObject.SetActive(false); }