コード例 #1
0
        /// <summary>
        /// Retrieve the list of interactables that this interactor could possibly interact with this frame.
        /// This list is sorted by priority (in this case distance).
        /// </summary>
        /// <param name="validTargets">Populated List of interactables that are valid for selection or hover.</param>
        public override void GetValidTargets(List <XRBaseInteractable> validTargets)
        {
            // pointers used to sample the curve and check colliders between points
            Vector3 m_PreviousPoint;
            Vector3 m_NextPoint;

            validTargets.Clear();

            // we havent init'd cleanly. bail out.
            if (m_SamplePoints == null || m_SamplePoints.Length < 2)
            {
                return;
            }

            m_NoSamplePoints  = 1;
            m_SamplePoints[0] = m_StartTransform.position;

            m_PreviousPoint     = m_StartTransform.position;
            m_HitCount          = 0;
            m_HitPositionInLine = 0;
            int accumulatedHits = 0;

            int maxSamplePoints;

            switch (m_LineType)
            {
            case LineType.StraightLine:
                m_NextPoint = m_PreviousPoint + m_StartTransform.forward * maxRaycastDistance;
                m_HitCount  = CheckCollidersBetweenPoints(m_PreviousPoint, m_NextPoint);

                if (m_HitCount != 0)
                {
                    m_HitPositionInLine = 1;     // hit position is between point 0 and point 1
                }
                // save the "virtual" end point of the line
                m_SamplePoints[m_NoSamplePoints] = m_NextPoint;
                m_NoSamplePoints++;
                break;

            case LineType.ProjectileCurve:

                float   flightTime         = 2.0f * m_Velocity * Mathf.Sin(Mathf.Abs(Angle) * Mathf.Deg2Rad) / m_Acceleration + m_AdditionalFlightTime;
                Vector3 velocityVector     = m_StartTransform.forward * m_Velocity;
                Vector3 accelerationVector = m_ReferenceFrame.up * -1.0f * m_Acceleration;

                maxSamplePoints = m_SamplePoints.Length;
                accumulatedHits = 0;
                for (int i = 1; i < m_SampleFrequency && m_NoSamplePoints < maxSamplePoints; i++)
                {
                    float t = (float)i / (float)(m_SampleFrequency - 1) * flightTime;

                    m_NextPoint = CalculateProjectilePoint(t, m_StartTransform.position, velocityVector, accelerationVector);

                    // check collider only when there has not been a hit point
                    if (accumulatedHits == 0)
                    {
                        accumulatedHits += CheckCollidersBetweenPoints(m_PreviousPoint, m_NextPoint);
                        if (accumulatedHits != 0)
                        {
                            m_HitPositionInLine = i;
                        }
                    }

                    // keep sampling
                    m_SamplePoints[m_NoSamplePoints] = m_NextPoint;
                    m_NoSamplePoints++;
                    m_PreviousPoint = m_NextPoint;
                }
                m_HitCount = accumulatedHits;

                break;

            case LineType.BezierCurve:

                // update control points for bezier curve
                UpdateControlPoints();

                maxSamplePoints = m_SamplePoints.Length;

                for (int i = 1; i < m_SampleFrequency && m_NoSamplePoints < maxSamplePoints; i++)
                {
                    float t = (float)i / (float)(m_SampleFrequency - 1);
                    m_NextPoint = CalculateBezierPoint(t, m_ControlPoints[0], m_ControlPoints[1], m_ControlPoints[2]);

                    // check collider only when there has not been a hit point
                    if (accumulatedHits == 0)
                    {
                        accumulatedHits += CheckCollidersBetweenPoints(m_PreviousPoint, m_NextPoint);
                        if (accumulatedHits != 0)
                        {
                            m_HitPositionInLine = i;
                        }
                    }

                    // keep sampling
                    m_SamplePoints[m_NoSamplePoints] = m_NextPoint;
                    m_NoSamplePoints++;
                    m_PreviousPoint = m_NextPoint;
                }

                m_HitCount = accumulatedHits;
                break;
            }

            // sort all the hits by distance to the controller
            if (m_HitCount > 0)
            {
                SortingHelpers.Sort(m_RaycastHits, m_RaycastHitComparer);
                for (var i = 0; i < Math.Min(m_HitCount, kMaxRaycastHits); ++i)
                {
                    var interactable = interactionManager.TryGetInteractableForCollider(m_RaycastHits[i].collider);
                    if (interactable && !validTargets.Contains(interactable))
                    {
                        validTargets.Add(interactable);
                    }
                    else
                    {
                        break; // blocker
                    }
                }
            }
        }
 /// <inheritdoc />
 public override void GetValidTargets(List <XRBaseInteractable> targets)
 {
     SortingHelpers.SortByDistanceToInteractor(this, m_ValidTargets, targets);
 }