public override bool CanActivate(AIBrain ai)
        {
            safeInfo = ai.Memory.GetHighestOverall <InformationSafePosition>();
            if (safeInfo == null)
            {
                return(false);
            }

            safeInfo.isBeingUsed = true;

            if (base.CanActivate(ai))
            {
                return(true);
            }
            return(false);
        }
        private bool FindSafePositions(AIBrain ai)
        {
            if (!ai.HaveCurrentTarget())
            {
                return(false);
            }

            Transform transform = ai.Transform;

            List <Vector3> samplePositions = new List <Vector3>();

            samplePositions.Clear();

            float randDirAngle = Random.Range(0, 360);

            for (int randAngleCounter = 0; randAngleCounter < angleCheckCount; randAngleCounter++)
            {
                randDirAngle += 360 / angleCheckCount;
                float randStartDist = Random.Range(randomStartDistance.x, randomStartDistance.y);

                Vector3 startPos = transform.position + Quaternion.Euler(0, randDirAngle, 0) * transform.forward * randStartDist;
                Vector3 startDir = Quaternion.Euler(0, randDirAngle, 0) * transform.forward * Random.Range(randomStartDistance.x, randomStartDistance.y);

                NavMeshHit hit;

                Vector3 lastPoint = transform.position;
                for (int t = 0; t < checkAlongAngleCount; t++)
                {
                    startPos = startPos + startDir * t * stepSize;
                    startDir = (startPos - lastPoint).normalized;
                    if (NavMesh.SamplePosition(startPos, out hit, 10f, NavMesh.AllAreas))
                    {
                        samplePositions.Add(hit.position);
#if UNITY_EDITOR
                        if (showShapes)
                        {
                            Debug.DrawRay(hit.position, Vector3.up * 1f, Color.black);
                        }
#endif
                    }
                    lastPoint = hit.position;
                }
            }

            #region Check For Safe Position

            if (ai.InfoCurrentTarget.transform)
            {
                List <InformationSafePosition> infos = new List <InformationSafePosition>();

                rayCheckCountVertical = rayCheckCountVertical <= 0 ? 1 : rayCheckCountVertical;
                maxDistanceFromTargetForMaxConfidence = maxDistanceFromTargetForMaxConfidence <= 0 ? 1 : maxDistanceFromTargetForMaxConfidence;

                float yStep = (rayHeightMinMaxVertical.y - rayHeightMinMaxVertical.x) / (rayCheckCountVertical - 1);
                for (int i = 0; i < samplePositions.Count; i++)
                {
                    // Vertical Rays
                    Vector3 samplePosition    = samplePositions[i];
                    int     rayHitToSafeCount = 0;
                    for (int j = 0; j < rayCheckCountVertical; j++)
                    {
                        float      height = rayHeightMinMaxVertical.x + j * yStep;
                        RaycastHit hit;
#if UNITY_EDITOR
                        if (showShapes)
                        {
                            Debug.DrawLine(samplePosition + Vector3.up * height, ai.GetCurrentTargetPos() + Vector3.up * rayToTargetHeight, Color.red);
                            Debug.DrawRay(ai.GetCurrentTargetPos() + Vector3.up * rayToTargetHeight, Vector3.up * 15f, Color.gray);
                        }
#endif
                        if (Physics.Linecast(samplePosition + Vector3.up * height, ai.GetCurrentTargetPos() + Vector3.up * rayToTargetHeight, out hit, lineCastMask))
                        {
                            if (!Checkers.IsOneOfTags(hit.transform, fightableTags) && !Checkers.isChildOf(hit.transform, ai.Transform.GetComponentsInChildren <Transform>()) && hit.transform != transform)
                            {
                                rayHitToSafeCount++;
                            }
                        }
                    }
                    if (rayHitToSafeCount >= 1)
                    {
                        float distFromSelf = Vector3.Distance(ai.Transform.position, samplePosition);
                        float distSelfConf = 1 - Mathf.Clamp01(distFromSelf / maxDistanceFromSelfForMinConfidence);

                        float distFromTarget = Vector3.Distance(ai.GetCurrentTargetPos(), samplePosition);
                        float distTargetConf = Mathf.Clamp01(distFromTarget / maxDistanceFromTargetForMaxConfidence);

                        InformationSafePosition infoSafePos = new InformationSafePosition
                                                              (
                            samplePosition, (rayHitToSafeCount / (float)rayCheckCountVertical),
                            distFromSelf, distSelfConf,
                            distFromTarget, distTargetConf
                                                              );
                        infos.Add(infoSafePos);
                    }
                }

                infos = infos.OrderByDescending(x => x.OverallConfidence).ToList();
                for (int i = 0; i < infos.Count && i < maxMemoryAddPerUpdate; i++)
                {
                    ai.Memory.Add(infos[i]);
                }
            }

            #endregion Check For Safe Position

            return(true);
        }