/// <summary> /// [CheckVisibility] /// 視界の当たり判定を行う /// </summary> void CheckVisibility(ref Vector3 position) { //処理負荷軽減 Vector3 forward = transform.forward; //判定用構造体 VisibilityContainer container = new VisibilityContainer(); //候補を保存するリスト List <VisibilityContainer> markPoints = new List <VisibilityContainer>(); //Overlap collisions var collisions = Physics.OverlapSphere(position, m_visibilityDistance, m_visibilityLayerMask); //Collision判定ループ for (int i = 0, length = collisions.Length; i < length; ++i) { //GetComponent var point = collisions[i].GetComponent <BaseMarkPoint>(); //Nullかリンクありでコンティニュー if (point == null || (point.isLinked & point.isPauseTimer)) { continue; } //Point格納 container.SetPoint(point); //リストに存在しなければforwardとのDotを計算してリスト追加 if (!markPoints.Contains(container)) { container.forwardToPositionDot = Vector3.Dot(forward, (point.transform.position - position).normalized); markPoints.Add(container); } } //視界判定ループ for (int i = 0; i < markPoints.Count;) { //視界判定trueなら++i if (markPoints[i].forwardToPositionDot > m_angleToCosine) { ++i; } //視界判定falseならRemove else { markPoints.RemoveAt(i); } } //この時点でCount0なら終了 if (markPoints.Count == 0) { EditVisibilityHitFlag(false); return; } //この時点でCount1ならヒット確定として終了 else if (markPoints.Count == 1) { hitVisibilityMarkPoint = markPoints[0].markPoint; EditVisibilityHitFlag(true); return; } //forwardとの角度差でソートを行う float minDot = 10000.0f; int minIndex = -1; for (int i = 0, count = markPoints.Count; i < count; ++i) { if (minDot < markPoints[i].forwardToPositionDot) { minDot = markPoints[i].forwardToPositionDot; minIndex = i; } } //もっとも角度差が小さいものを選択する hitVisibilityMarkPoint = markPoints[markPoints.Count - 1].markPoint; EditVisibilityHitFlag(true); }