/// <summary> /// Maneuver in combat with target /// </summary> void CombatMove(Vector3 direction, float moveSpeed, bool backAway = false) { if (!backAway) { pursuing = true; retreating = false; } else { retreating = true; pursuing = false; } if (!senses.TargetIsWithinYawAngle(5.625f, targetPos)) { TurnToTarget(direction.normalized); // Classic always turns in place. Enhanced only does so if enemy is not in sight. if (!DaggerfallUnity.Settings.EnhancedCombatAI || !senses.TargetInSight) { return; } } Vector3 motion = transform.forward * moveSpeed; if (backAway) { motion *= -1; } // If using enhanced combat, avoid moving directly below targets if (!backAway && DaggerfallUnity.Settings.EnhancedCombatAI && avoidObstaclesTimer == 0 && !lookingForDetour) { bool withinPitch = senses.TargetIsWithinPitchAngle(45.0f); if (!pausePursuit && !withinPitch) { if (flies || isLevitating || swims) { if (!senses.TargetIsAbove()) { motion = -transform.up * moveSpeed; } else { motion = transform.up * moveSpeed; } } // Causes a random delay after being out of pitch range else if (senses.TargetIsAbove() && changeStateTimer <= 0) { SetChangeStateTimer(); pausePursuit = true; } } else if (pausePursuit && withinPitch) { pausePursuit = false; } if (pausePursuit) { if (senses.TargetIsAbove() && !senses.TargetIsWithinPitchAngle(55.0f) && changeStateTimer <= 0) { // Back away from target motion = -transform.forward * moveSpeed * 0.75f; } else { // Stop moving return; } } } // Avoid other enemies, and stop enemies from moving on top of shorter enemies //AvoidEnemies(ref motion); // Return if AvoidEnemies set change timer //if (changeStateTimer > 0 && !pursuing && !retreating) //return; SetChangeStateTimer(); if (swims) { WaterMove(motion); } else if (flies || isLevitating) { controller.Move(motion * Time.deltaTime); } else { MoveIfNoFallDetected(motion); } }
/// <summary> /// Try to move in given direction /// </summary> void AttemptMove(Vector3 direction, float moveSpeed, bool backAway = false) { // Set whether pursuing or retreating, for bypassing changeStateTimer delay when continuing these actions if (!backAway) { pursuing = true; retreating = false; } else { retreating = true; pursuing = false; } if (!senses.TargetIsWithinYawAngle(5.625f, targetPos)) { TurnToTarget(direction.normalized); // Classic always turns in place. Enhanced only does so if enemy is not in sight, // for more natural-looking movement while pursuing. if (!DaggerfallUnity.Settings.EnhancedCombatAI || !senses.TargetInSight) { return; } } if (backAway) { direction *= -1; } // Move downward some to eliminate bouncing down inclines if (!flies && !swims && !isLevitating && controller.isGrounded) { direction.y = -2f; } Vector3 motion = direction * moveSpeed; // If using enhanced combat, avoid moving directly below targets if (!backAway && DaggerfallUnity.Settings.EnhancedCombatAI && avoidObstaclesTimer == 0) { bool withinPitch = senses.TargetIsWithinPitchAngle(45.0f); if (!pausePursuit && !withinPitch) { if (flies || isLevitating || swims) { if (!senses.TargetIsAbove()) { motion = -transform.up * moveSpeed; } else { motion = transform.up * moveSpeed; } } // Causes a random delay after being out of pitch range else if (senses.TargetIsAbove() && changeStateTimer <= 0) { SetChangeStateTimer(); pausePursuit = true; } } else if (pausePursuit && withinPitch) { pausePursuit = false; } if (pausePursuit) { if (senses.TargetIsAbove() && !senses.TargetIsWithinPitchAngle(55.0f) && changeStateTimer <= 0) { // Back away from target motion = -transform.forward * moveSpeed * 0.75f; } else { // Stop moving return; } } } SetChangeStateTimer(); // Check if there is something to collide with directly in movement direction, such as upward sloping ground. Vector3 motion2d = motion.normalized; motion2d.y = 0; RayCheckForObstacle(motion2d); RayCheckForFall(motion2d); if (fallDetected || obstacleDetected) { FindDetour(motion2d); } else // Clear to move { if (swims) { WaterMove(motion); } else if (flies || isLevitating) { controller.Move(motion * Time.deltaTime); } else { controller.Move(motion * Time.deltaTime); } } // Reset clockwise check if we've been clear of obstacles/falls for a while if (Time.time - lastTimeWasStuck > 2f) { checkingClockwiseTimer = 0; didClockwiseCheck = false; } }