/// <summary> /// /// </summary> void Follow() { Agent.stoppingDistance = 3; lookToDirection = false; SetCrouch(false); Speed = defaultSpeed; Agent.destination = TargetPosition; if (Agent.remainingDistance <= 3) { if (Cover(false, true)) { AgentState = AIAgentState.Covering; } else { Look(); } AIWeapon.Fire(bl_AIShooterWeapon.FireReason.Forced); SetDebug = 20; } else { AgentState = AIAgentState.Following; AIWeapon.Fire(); } }
/// <summary> /// If player not in range then the AI patrol in map /// </summary> void RandomPatrol(bool precision) { if (death) { return; } float pre = PatrolRadius; if (precision) { if (TargetDistance < LookRange) { if (Target == null) { Target = GetNearestPlayer; } AgentState = AIAgentState.Looking; SetDebug = 23; } else { AgentState = AIAgentState.Searching; SetDebug = 16; } pre = 8; } else { AgentState = AIAgentState.Patroling; ForceCoverFire = false; SetDebug = 22; } lookToDirection = false; AIWeapon.isFiring = false; if (!Agent.hasPath || TargetDistance <= 5.2f || (time - lastPathTime) > 7) { bool toAnCover = (Random.Range(0, 20) >= 18);//probability of get a cover point as random destination Vector3 randomDirection = TargetPosition + (Random.insideUnitSphere * pre); if (toAnCover) { randomDirection = CoverManager.GetCoverOnRadius(transform, 20).transform.position; } if (Target == null && m_GameMode == GameMode.FFA) { randomDirection += m_Transform.localPosition; } NavMeshHit hit; NavMesh.SamplePosition(randomDirection, out hit, pre, 1); finalPosition = hit.position; lastPathTime = time + Random.Range(0, 5); Speed = (Random.Range(0, 5) == 3) ? 4 : 6; SetCrouch(false); } else { SetDebug = 17; } Agent.SetDestination(finalPosition); }
/// <summary> /// /// </summary> void OnTargetInSight(bool overrideCover) { if (AgentState == AIAgentState.Following || AIHealth.Health <= 50) { if (!Cover(overrideCover) || CanCover(17) || AllOrNothing) { Follow(); AgentState = AIAgentState.Following; SetDebug = 11; } else { if (Target != null) { AIWeapon.Fire(bl_AIShooterWeapon.FireReason.OnMove); } if (!strafing) { strafingTime += delta; if (strafingTime >= 5) { strafing = true; Invoke("ResetStrafing", 4); } SetCrouch(true); SetDebug = 12; } else { if (strafingTime > 0) { strafingPosition = m_Transform.localPosition + m_Transform.TransformDirection(m_Transform.localPosition + (Vector3.right * Random.Range(-3, 3))); strafingTime = 0; } Agent.destination = strafingPosition; SetCrouch(false); SetDebug = 18; } } } else if (AgentState == AIAgentState.Covering) { if (CanCover(5) && TargetDistance >= 7) { Cover(true); SetDebug = 13; } else { SetDebug = 14; } } else { Look(); SetDebug = 15; } }
/// <summary> /// /// </summary> bool Cover(bool overridePoint, bool toTarget = false) { Transform t = (!toTarget) ? transform : Target; if (overridePoint) { if (Agent.pathStatus == NavMeshPathStatus.PathComplete) { //look for another cover point CoverPoint = CoverManager.GetCloseCover(t, CoverPoint); } } else { //look for a near cover point CoverPoint = CoverManager.GetCloseCover(t); } if (CoverPoint != null) { Agent.stoppingDistance = 0.1f; Speed = playerInFront ? defaultSpeed : 6; Agent.SetDestination(CoverPoint.transform.position); AgentState = AIAgentState.Covering; CoverTime = time; AIWeapon.Fire(bl_AIShooterWeapon.FireReason.OnMove); return(true); } else { //if there are not a near cover point if (Target != null) { //follow target Agent.SetDestination(Target.position); Speed = playerInFront ? defaultSpeed : 7; personal = true; AgentState = AIAgentState.Searching; } else { CoverPoint = CoverManager.GetCloseCoverForced(transform); Agent.SetDestination(CoverPoint.transform.position); Speed = defaultSpeed; } return(false); } }
/// <summary> /// /// </summary> void TargetControll() { float Distance = bl_UtilityHelper.Distance(Target.position, m_Transform.localPosition); if (Distance >= LosseRange) { if (AgentState == AIAgentState.Following || personal || AgentState == AIAgentState.Searching) { RandomPatrol(true); SetDebug = 7; } else { photonView.RPC("ResetTarget", RpcTarget.All); RandomPatrol(false); AgentState = AIAgentState.Patroling; SetDebug = 8; } Speed = defaultSpeed; if (!AIWeapon.isFiring) { Anim.SetInteger("UpperState", 4); } } else if (Distance > FollowRange && Distance < LookRange)//look range { OnTargetInSight(false); } else if (Distance <= FollowRange) { Follow(); } else if (Distance < LosseRange) { OnTargetInSight(true); } else { Debug.Log("Unknown state: " + Distance); SetDebug = 10; } }
/// <summary> /// /// </summary> void SwichCover() { if (Agent.pathStatus != NavMeshPathStatus.PathComplete) { return; } if (SwitchCoverTimes <= 3) { Cover(true, true); SwitchCoverTimes++; } else { AgentState = AIAgentState.Following; Agent.SetDestination(TargetPosition); SwitchCoverTimes = 0; AllOrNothing = true; } }
/// <summary> /// Force AI to look the target /// </summary> void Look() { if (AgentState != AIAgentState.Covering) { if (lookTime >= 5) { AgentState = AIAgentState.Following; lookTime = 0; return; } lookTime += delta; AgentState = AIAgentState.Looking; } Quaternion rotation = Quaternion.LookRotation(TargetPosition - m_Transform.localPosition); m_Transform.rotation = Quaternion.Slerp(m_Transform.rotation, rotation, delta * RotationLerp); AIWeapon.Fire(); SetCrouch(playerInFront); Speed = playerInFront ? defaultSpeed : 5.5f; lookToDirection = false; }
/// <summary> /// /// </summary> void OnCovering() { if (Target != null) { float Distance = TargetDistance; if (Distance <= LookRange && playerInFront)//if in look range and in front, start follow him and shot { if (!strafing) { AgentState = AIAgentState.Following; Agent.SetDestination(Target.position); SetDebug = 1; } else { AgentState = AIAgentState.Covering; Agent.SetDestination(strafingPosition); SetDebug = 19; } AIWeapon.Fire(); } else if (Distance > LosseRange && (time - CoverTime) >= 7)// if out of line of sight, start searching him { AgentState = AIAgentState.Searching; SetCrouch(false); AIWeapon.Fire(bl_AIShooterWeapon.FireReason.OnMove); SetDebug = 2; } else if (ForceCoverFire && !ObstacleBetweenTarget)//if in cover and still get damage, start shoot at him { AIWeapon.Fire(bl_AIShooterWeapon.FireReason.Forced); if (CanCover(10)) { SwichCover(); } SetDebug = 3; } else if (CanCover(10) && Distance >= 7) { SwichCover(); AIWeapon.Fire(bl_AIShooterWeapon.FireReason.OnMove); SetDebug = 4; } else { if (playerInFront) { AIWeapon.Fire(); SetDebug = 5; } else { AIWeapon.Fire(bl_AIShooterWeapon.FireReason.Forced); Look(); SetCrouch(false); SetDebug = 6; } } } if (Agent.pathStatus == NavMeshPathStatus.PathComplete) { if (CoverPoint != null && CoverPoint.Crouch) { SetCrouch(true); } } if (lookToDirection) { LookToHitDirection(); } else { Quaternion rotation = Quaternion.LookRotation(Target.position - m_Transform.localPosition); m_Transform.rotation = Quaternion.Slerp(m_Transform.rotation, rotation, delta * RotationLerp); } }