예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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;
            }
        }