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; }
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; } }
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; } } } }
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))); } }