public override LineData GeneratingLineData(Vector3 origin, Vector3 direction) { float timePrecision = 0.1f; int maxIteration = 200; List <Vector3> lineData = new List <Vector3>(); lineData.Add(origin); Vector3 p = origin; Vector3 q = origin; Vector3 v = direction.normalized * velo; HittingStatus hittingStatus = HittingStatus.NoHitting; Collider hitCollider = null; for (int i = 0; i < maxIteration; i++) { q = p + v * timePrecision; RaycastHit hitInfo = new RaycastHit(); //Hit something if (Physics.Raycast(p, q - p, out hitInfo, (q - p).magnitude, ~hittingIgnoreLayer)) { if (((1 << hitInfo.collider.gameObject.layer) & hittingTargetLayer.value) != 0) { var up = Vector3.Dot(hitInfo.normal, Vector3.up); if (up < Mathf.Cos(maxSlopAngle * 3.14159f / 180f))//slop is too steep { hittingStatus = HittingStatus.HitNonTeleportingArea; } else { hittingStatus = HittingStatus.HitTeleportingArea; } } else { hittingStatus = HittingStatus.HitNonTeleportingArea; } lineData.Add(hitInfo.point); hitCollider = hitInfo.collider; break; } lineData.Add(q); p = q; v += Vector3.down * timePrecision; } //foreach (var u in lineData) //{ // Debug.Log(u); //} return(new LineData(hittingStatus, hitCollider, lineData.ToArray())); }
// Update is called once per frame void LateUpdate() { if (drawLine) { LineData data = lineDataProvider.GeneratingLineData(emittingPoint.position, emittingPoint.forward); lineRenderer.positionCount = data.lineData.Length; Vector3[] lineData = null; if (modifiedTargetPoint == null) { lineData = data.lineData; } else { lineData = new Vector3[data.lineData.Length]; Vector3 beginPoint = data.lineData[0]; Vector3 endPoint = modifiedTargetPoint.Value; for (int i = 0; i < data.lineData.Length; i++) { Vector3 interplote = ((float)i * endPoint + (float)(data.lineData.Length - 1 - i) * beginPoint) / ((float)data.lineData.Length - 1); lineData[i] = ((float)i * interplote + (float)(data.lineData.Length - 1 - i) * data.lineData[i]) / ((float)data.lineData.Length - 1); } } anticipateHitPoint = data.lineData[data.lineData.Length - 1]; hitPoint = lineData[lineData.Length - 1]; lineRenderer.SetPositions(lineData); if (modifiedTargetPoint != null) { hitCollider = null;//No hit collider when hit the modified target status = HittingStatus.HitModifiedTarget; lineRenderer.colorGradient = normalColor; if (hittingTargetGameObject) { hittingTargetGameObject.SetActive(false); } if (hittingObstacleGameObject) { hittingObstacleGameObject.SetActive(false); } } else { hitCollider = data.hitCollider; status = data.hittingStatus; switch (data.hittingStatus) { case HittingStatus.NoHitting: if (hittingTargetGameObject) { hittingTargetGameObject.SetActive(false); } if (hittingObstacleGameObject) { hittingObstacleGameObject.SetActive(false); } lineRenderer.colorGradient = hitObstacleColor; break; case HittingStatus.HitTeleportingArea: lineRenderer.colorGradient = normalColor; if (hittingObstacleGameObject) { hittingObstacleGameObject.SetActive(false); } if (hittingTargetGameObject) { hittingTargetGameObject.SetActive(true); hittingTargetGameObject.transform.position = data.lineData[data.lineData.Length - 1]; } break; case HittingStatus.HitNonTeleportingArea: lineRenderer.colorGradient = hitObstacleColor; if (hittingTargetGameObject) { hittingTargetGameObject.SetActive(false); } if (hittingObstacleGameObject) { hittingObstacleGameObject.SetActive(true); hittingObstacleGameObject.transform.position = data.lineData[data.lineData.Length - 1]; } break; default: break; } } } else { lineRenderer.positionCount = 0; if (hittingTargetGameObject) { hittingTargetGameObject.SetActive(false); } if (hittingObstacleGameObject) { hittingObstacleGameObject.SetActive(false); } } }
public LineData(HittingStatus hittingStatus, Collider hitCollider, Vector3[] lineData) { this.hittingStatus = hittingStatus; this.hitCollider = hitCollider; this.lineData = lineData; }