public void DrawMotionSpheres() { // We estimate how much we should correct our curve time by with a guess step for (int i = 0; i < m_MotionSphereCount; ++i) { var t = i / (float)m_MotionSphereCount + m_MotionSphereOffset; var motionSphere = m_MotionSpheres[i]; motionSphere.position = MathUtilsExt.CalculateCubicBezierPoint(t, m_BezierControlPoints); var motionSphereScale = visible ? (validTarget ? m_MotionSphereOriginalScale.x : 0.05f) : 0f; var smoothVelocity = 0f; const float scaleCoefficient = 4f; motionSphereScale = MathUtilsExt.SmoothDamp(motionSphere.localScale.x, motionSphereScale, ref smoothVelocity, 3f, Mathf.Infinity, Time.unscaledDeltaTime) * Mathf.Min((m_Transform.position - motionSphere.position).magnitude * scaleCoefficient / viewerScale, 1f); motionSphere.localScale = Vector3.one * motionSphereScale; motionSphere.localRotation = Quaternion.identity; // If we're not at the starting point, we apply a correction factor if (t > 0.0f) { // We have how long we *think* the curve should be var lengthEstimate = m_CurveLengthEstimate * t; // We compare that to how long our distance actually is var correctionFactor = lengthEstimate / (motionSphere.position - m_BezierControlPoints[0]).magnitude; // We then scale our time value by this correction factor var correctedTime = Mathf.Clamp01(t * correctionFactor); motionSphere.position = MathUtilsExt.CalculateCubicBezierPoint(correctedTime, m_BezierControlPoints); } } }
public void DrawArc() { m_LocatorRoot.rotation = Quaternion.identity; // prevent rendering line when pointing to high or low if (outOfMaxRange) { validTarget = false; if (m_State != State.Inactive) { StopAllCoroutines(); StartCoroutine(AnimateHideVisuals()); } return; } // start point m_BezierControlPoints[0] = m_ToolPoint.position; // first handle -- determines how steep the first part will be m_BezierControlPoints[1] = m_ToolPoint.position + m_ToolPoint.forward * pointerStrength * m_Range * viewerScale; const float kArcEndHeight = 0f; m_FinalPosition = new Vector3(m_BezierControlPoints[1].x, kArcEndHeight, m_BezierControlPoints[1].z); // end point m_BezierControlPoints[3] = m_FinalPosition; // second handle -- determines how steep the intersection with the ground will be m_BezierControlPoints[2] = m_FinalPosition; // set the position of the locator m_LocatorRoot.position = m_DetachedWorldArcPosition == null ? m_FinalPosition + k_GroundOffset : (Vector3)m_DetachedWorldArcPosition; validTarget = false; var colliders = Physics.OverlapSphere(m_FinalPosition, m_Radius, m_LayerMask.value); validTarget = colliders != null && colliders.Length > 0; SetColors(!showValidTargetIndicator || validTarget ? m_ValidLocationColor : m_InvalidLocationColor); // calculate and send points to the line renderer m_SegmentPositions = new Vector3[m_LineSegmentCount]; for (int i = 0; i < m_LineSegmentCount; i++) { var t = i / (float)Mathf.Max((m_LineSegmentCount - 1), 1); var q = MathUtilsExt.CalculateCubicBezierPoint(t, m_BezierControlPoints); m_SegmentPositions[i] = q; } m_LineRenderer.SetPositions(m_SegmentPositions); // The curve length will be somewhere between a straight line between the points // and a path that directly follows the control points. So we estimate this by just averaging the two. m_CurveLengthEstimate = ((m_BezierControlPoints[3] - m_BezierControlPoints[0]).magnitude + ((m_BezierControlPoints[1] - m_BezierControlPoints[0]).magnitude + (m_BezierControlPoints[1] - m_BezierControlPoints[2]).magnitude)) * 0.5f; }