private List <InformationNMCanFirePosition> GetMovePositionS(AIBrain ai)
        {
            if (!ai.HaveCurrentTarget())
            {
                return(new List <InformationNMCanFirePosition>());
            }

            angleCheckCount = angleCheckCount <= 2 ? 1 : angleCheckCount;
            float[] checkAngles = new float[angleCheckCount * 2];
            if (angleCheckCount == 1)
            {
                checkAngles[0] = (dodgeAnimAnglesInBetween.y - dodgeAnimAnglesInBetween.x) / 2;
                checkAngles[1] = -checkAngles[0];
            }
            else
            {
                float step = (dodgeAnimAnglesInBetween.y - dodgeAnimAnglesInBetween.x) / (float)(angleCheckCount - 1);
                for (int i = 0; i < angleCheckCount; i++)
                {
                    checkAngles[i] = dodgeAnimAnglesInBetween.x + step * i;
                    checkAngles[angleCheckCount * 2 - i - 1] = -checkAngles[i];
                }
            }

            UnityEngine.AI.NavMeshHit hit;
            RaycastHit hitRc = new RaycastHit();
            List <InformationNMCanFirePosition> list = new List <InformationNMCanFirePosition>();

            foreach (float angle in checkAngles)
            {
                Vector3 startPos = ai.Transform.position + ai.Transform.TransformDirection(Quaternion.AngleAxis(angle, Vector3.up) * Vector3.forward) * dodgeEstimateDistance;

#if UNITY_EDITOR
                if (showShapes)
                {
                    bool hitb = UnityEngine.AI.NavMesh.SamplePosition(startPos, out hit, .1f, UnityEngine.AI.NavMesh.AllAreas);
                    hitb = !hitb; // dont give me warning
                    Debug.DrawLine(hit.position + Vector3.up * lineCastHeightY, ai.GetCurrentTargetPos() + Vector3.up * lineCastHeightY, Color.black);
                }
#endif

                if (UnityEngine.AI.NavMesh.SamplePosition(startPos, out hit, .1f, UnityEngine.AI.NavMesh.AllAreas) && hit.hit &&
                    Vector3.Distance(hit.position, ai.Transform.position) < (dodgeEstimateDistance + _delta) &&
                    Physics.Linecast(hit.position + Vector3.up * lineCastHeightY, ai.GetCurrentTargetPos() + Vector3.up * lineCastHeightY, out hitRc, lineCastMask) &&
                    hitRc.transform == ai.InfoCurrentTarget.transform // need to be able to keep shooting
                    )
                {
#if UNITY_EDITOR
                    if (showShapes)
                    {
                        Debug.DrawRay(hit.position, Vector3.up, Color.green);
                    }
#endif
                    list.Add(new InformationNMCanFirePosition(angle, 1, hit.position, 1));
                }
            }

            return(list);
        }
        public void SolveLookIKUpdate(AIBrain ai)
        {
            LookIKProps.headAim = Mathf.Lerp(CheckEpsilon(LookIKProps.headAim, headIKTarget), headIKTarget, (headIKTarget == 1 ? LookIKProps.headIKSmooth : LookIKProps.headIKBackSmooth) * Time.deltaTime);

            Vector3 lookPos = Vector3.zero;

            switch (lookAtType)
            {
            case ET.LookAtType.ToCurrentTarget:
                lookPos = ai.GetCurrentTargetPos();
                break;

            case ET.LookAtType.ToPosition:
                lookPos = lookAtPosition;
                break;

            case ET.LookAtType.Forward:
                lookPos = ai.Transform.position + ai.Transform.forward * 5f;
                break;

            default:
                break;
            }

            LookIKProps.midPos = ai.Transform.position + Vector3.up * LookIKProps.lookStartHeight;
            Vector3 mPosToTDir = -LookIKProps.midPos + new Vector3(lookPos.x, LookIKProps.midPos.y, lookPos.z);
            Vector3 mPosToCDir = LookIKProps.midPos.y * (Quaternion.AngleAxis(LookIKProps.tAngle, Vector3.up) * ai.Transform.TransformDirection(Vector3.forward));

            Vector3 mPosToZeroDir = LookIKProps.midPos.y * (Quaternion.AngleAxis(0, Vector3.up) * ai.Transform.TransformDirection(Vector3.forward));

            //Debug.DrawRay(LookIKProps.midPos, mPosToCDir * LookIKProps.fwSize, Color.red);
            float cAngleBw = Vector3.Angle(mPosToTDir, mPosToZeroDir);

            cAngleBw = cAngleBw * Mathf.Sign(Vector3.Dot(Quaternion.AngleAxis(90, Vector3.up) * mPosToZeroDir, mPosToTDir));

            float aimingAnglePlus = 0f, weaponBodyBob = 0;

            if (ai.GetStateSystem <AIShooterStateSystemWeapon>() != null /*&& ai.WorldState.GetValue(DictionaryStrings.weaponAimed) == true.ToString()*/ && ai.HaveCurrentWeapon())
            {
                aimingAnglePlus = ai.GetCurrentWeaponScript().bodyFixRight *LookIKProps.aimingWeaponHorFixMultiplier;
                weaponBodyBob   = ai.GetStateSystem <AIShooterStateSystemWeapon>().weaponBodyBob;
            }
            if (headIKTarget == 0)
            {
                LookIKProps.tAngle = Mathf.Lerp(LookIKProps.tAngle, 0, Time.deltaTime * LookIKProps.tAngleLerpBackSpeed);
            }
            else
            {
                LookIKProps.tAngle = Mathf.Lerp(LookIKProps.tAngle, cAngleBw + aimingAnglePlus + weaponBodyBob * LookIKProps.aiWeaponBodyBobMultiplier, Time.deltaTime * LookIKProps.tAngleLerpSpeed);
            }
            LookIKProps.tAngle = Mathf.Clamp(LookIKProps.tAngle, -LookIKProps.maxLookTAngle, LookIKProps.maxLookTAngle);

            LookIKProps.realLookPos = LookIKProps.midPos + mPosToCDir.normalized * LookIKProps.fwSize;
        }
Пример #3
0
 public override void OnUpdate(ref bool needToReplan, ref bool needToReevaluateGoals, AIBrain ai)
 {
     if (Vector3.Distance(ai.GetCurrentTargetPos(), ai.Transform.position) > 1f)
     {
         ai.WorldState.SetKey(DS.isNearCurrentTarget, false);
     }
     else
     {
         if (ai.WorldState.CompareKey(DS.isNearCurrentTarget, false))
         {
             needToReplan = true;
         }
         ai.WorldState.SetKey(DS.isNearCurrentTarget, true);
     }
 }
 public override void CalculateCost(AIBrain ai)
 {
     if (ai.HaveCurrentTarget())
     {
         float distance = Vector3.Distance(ai.Transform.position, ai.GetCurrentTargetPos());
         if (distance < distanceToSetLowCost)
         {
             Cost = lowCost;
         }
         else
         {
             Cost = 10f;
         }
     }
     else
     {
         Cost = 10f;
     }
 }
Пример #5
0
        private void GetMovePos(AIBrain ai)
        {
            List <InformationNMCanFirePosition> infos = ai.GetSensor <SensorCanFireNMPositionFinder>().RequestAllInfo(ai);

            if (infos != null && infos.Count > 0)
            {
                float maxConf = -1;
                foreach (var info in infos)
                {
                    float distFromSelf = Vector3.Distance(ai.Transform.position, info.positionEstimated.Value);
                    float distSelfConf = 1 - Mathf.Clamp01(distFromSelf / 10);

                    float distFromTarget = Vector3.Distance(ai.GetCurrentTargetPos(), info.positionEstimated.Value);
                    float distTargetConf = Mathf.Clamp01(distFromTarget / 10);

                    float tempOveralConf = (distSelfConf + distTargetConf) / 2;
                    if (tempOveralConf > maxConf)
                    {
                        infoMovePos = info;
                        maxConf     = tempOveralConf;
                    }
                }
            }
        }
Пример #6
0
 public override bool IsCompleted(AIBrain ai)
 {
     return(Vector3.Distance(ai.Transform.position, ai.GetCurrentTargetPos()) > preferredGetAwayDistance);
 }
        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);
        }
        public void Move(AIBrain ai)
        {
            NavMeshAgent agent = ai.Agent;

            if (agent)
            {
                Transform transform = ai.Transform;
                Animator  animator  = ai.Animator;
                if (!usePath)
                {
                    switch (moveToType)
                    {
                    case ET.MoveToType.ToCurrentTarget:
                        agent.destination = ai.GetCurrentTargetPos();
                        break;

                    case ET.MoveToType.ToPosition:
                        agent.destination = moveToPosition;
                        break;

                    default:
                        break;
                    }
                }
                bool turnedMovement = false;
                if (shouldTurnToPosition)
                {
                    agent.updateRotation = false; turnedMovement = true;

                    switch (turnToType)
                    {
                    case ET.TurnToType.ToCurrentTarget:
                        turnToPosition = ai.GetCurrentTargetPos();
                        break;

                    case ET.TurnToType.ToPosition:
                        // already set in function
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    agent.updateRotation = true;
                    turnedMovement       = false;
                }

                #region Unity Manual Code

                Vector3 worldDeltaPosition = agent.nextPosition - transform.position;

                // Map 'worldDeltaPosition' to local space
                float   dx            = Vector3.Dot(transform.right, worldDeltaPosition);
                float   dy            = Vector3.Dot(transform.forward, worldDeltaPosition);
                Vector2 deltaPosition = new Vector2(dx, dy);

                // Low-pass filter the deltaMove
                float smooth = Mathf.Min(1.0f, Time.deltaTime / 0.15f);
                smoothDeltaPosition = Vector2.Lerp(smoothDeltaPosition, deltaPosition, smooth);

                // Update velocity if delta time is safe
                if (Time.deltaTime > 1e-5f)
                {
                    velocity = smoothDeltaPosition / Time.deltaTime;
                }

                bool shouldMove = velocity.magnitude > 0.5f && agent.remainingDistance > agent.radius;

                // Pull agent towards character[Modded pull multiplier]
                if (worldDeltaPosition.magnitude > agent.radius)
                {
                    agent.nextPosition = transform.position + .01f * worldDeltaPosition;
                }

                // Set transform's y to agent
                transform.position = new Vector3(transform.position.x, agent.nextPosition.y, transform.position.z);

                #endregion Unity Manual Code

                Vector3 desiredDir = (-transform.position + new Vector3(agent.nextPosition.x, transform.position.y, agent.nextPosition.z)).normalized * 2;

                float angle = 0;
                if (turnedMovement)
                {
                    angle = Vector3.Angle(transform.forward, (turnToPosition - transform.position).normalized);
                    angle = angle * Mathf.Abs(Vector3.Dot(transform.right, (turnToPosition - transform.position).normalized));
                    transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(-transform.position + new Vector3(turnToPosition.x, transform.position.y, turnToPosition.z)), Time.deltaTime * moveProps.idleTurnToSmooth);
                }

                float speedAnim = Vector2.SqrMagnitude(new Vector2(ai.Animator.GetFloat("VelX"), ai.Animator.GetFloat("VelY")));
                if (turnedMovement)
                {
                    if (speedAnim < moveProps.legsStopTurnAtSqrM && Mathf.Abs(angle) > moveProps.legsStartTurnAtAngle)
                    {
                        ai.Animator.SetFloat("LegsAngle", angle * moveProps.legsTurnAngleMult, moveProps.legsTurnAngleDamp, Time.deltaTime);
                        ai.Animator.SetBool("LegTurn", true);
                        ai.GetStateSystem <AIStateSystemAnimator>().EnableLayer(ai, 3, true, true);
                    }
                    else
                    {
                        ai.Animator.SetFloat("LegsAngle", 0, moveProps.legsTurnAngleDamp, Time.deltaTime);
                        ai.Animator.SetBool("LegTurn", false);
                        ai.GetStateSystem <AIStateSystemAnimator>().DisableLayer(ai, 3, true, true);
                    }
                }
                else
                {
                    ai.Animator.SetFloat("LegsAngle", 0, moveProps.legsTurnAngleDamp, Time.deltaTime);
                    ai.Animator.SetBool("LegTurn", false);
                    ai.GetStateSystem <AIStateSystemAnimator>().DisableLayer(ai, 3, true, true);
                }

                Quaternion refShift      = new Quaternion(transform.rotation.x, transform.rotation.y * -1f, transform.rotation.z, transform.rotation.w);
                Vector3    moveDirection = refShift * desiredDir;

                float locomotionDamp = moveProps.velocityAnimDamp;
                float velocityLimit  = moveProps.animatorWalkSpeed;

                switch (moveType)
                {
                case ET.MoveType.Walk:
                    velocityLimit      = moveProps.animatorWalkSpeed;
                    agent.speed        = moveProps.agentWalkSpeed;
                    agent.angularSpeed = moveProps.agentAngularSpeedWalk;
                    break;

                case ET.MoveType.Run:
                    velocityLimit      = moveProps.animatorRunSpeed;
                    agent.speed        = moveProps.agentRunSpeed;
                    agent.angularSpeed = moveProps.agentAngularSpeedRun;
                    break;

                case ET.MoveType.Sprint:
                    velocityLimit      = moveProps.animatorSprintSpeed;
                    agent.speed        = moveProps.agentSprintSpeed;
                    agent.angularSpeed = moveProps.agentAngularSpeedSprint;
                    break;

                default:
                    break;
                }
                float xVelocity = moveDirection.x, yVelocity = moveDirection.z;
                // Limit velocity
                if (xVelocity > 0)
                {
                    xVelocity = xVelocity > velocityLimit ? velocityLimit : xVelocity;
                }
                else if (xVelocity < 0)
                {
                    xVelocity = -xVelocity > velocityLimit ? -velocityLimit : xVelocity;
                }
                if (yVelocity > 0)
                {
                    yVelocity = yVelocity > velocityLimit ? velocityLimit : yVelocity;
                }
                else if (yVelocity < 0)
                {
                    yVelocity = -yVelocity > velocityLimit ? -velocityLimit : yVelocity;
                }
                if (!shouldMove)
                {
                    xVelocity = 0;
                    yVelocity = 0;
                }

                animator.SetFloat("VelX", xVelocity, locomotionDamp, Time.deltaTime);
                animator.SetFloat("VelY", yVelocity, locomotionDamp, Time.deltaTime);
                animator.SetFloat("CrouchStand", Mathf.Clamp01(Mathf.Lerp(animator.GetFloat("CrouchStand"), crouching ? 0 : 1, Time.deltaTime * moveProps.crouchStandSmooth)));
            }
        }