Monster AI Behavior Script in Godot
Monster AI Behavior Script in Godot
The script manages animations using an `AnimationPlayer`. It selects animations based on the character's state, such as playing "ZombieAttack" during an attack, "Running(1)" while chasing, and "MutantIdle" during idling. These are changed conditionally in the state-specific functions `attack_player()`, `chase_player()`, and `idle()` respectively. The script checks the current animation status before switching, ensuring smooth transitions by avoiding unnecessary animation changes. This system creates a coherent visual experience that aligns with the character's actions .
The `freeze_player` function toggles `is_player_frozen`, which could control the player's ability to act or move. Although not fully implemented, it holds potential for future features such as immobilizing the player temporarily, adding strategic depth or simulating effects like stun or crowd control. This functionality could enhance combat mechanics or add new layers of challenge by freezing the player during certain interactions, thus broadening tactical gameplay options and enriching the interactive complexity of the game environment .
The `_process(delta)` function manages state transitions by assessing the player’s distance and determining behavior: attacking if within range, chasing if further away, and idle otherwise. Delta represents the frame time, ensuring that movements and animations occur consistently across hardware with varying frame rates. By decrementing `attack_timer` by delta, the script maintains appropriately timed events, making gameplay experiences smooth and robust under different processing loads. This timing precision is crucial for seamless state transitions and reliable character behavior .
The `NavigationAgent3D` node in the script is crucial for directing the character's movement by setting a target position with `set_target_position()`. It computes a navigation path to this position, which can be the player's current location during a chase. The script checks if navigation is finished with `is_navigation_finished()`, and if not, the next path position is retrieved using `get_next_path_position()`. The character then adjusts its orientation and velocity to face and move towards this position. This allows the script to manage dynamic chasing behavior, tying into the larger game mechanic of pursuing the player .
The chasing logic enriches gameplay dynamics by providing a persistent threat that encourages strategic movement by the player. It activates when the player is within `chase_range` but not `attack_range`, prompting the character to pursue dynamically. This risks keeping players engaged, as they must navigate terrain while being pursued, deciding when to confront or evade the character. The logic adds tension and urgency, enhancing player experience through continuous interaction opportunities and requiring skillful management of distance and environment .
Exported variables such as `speed`, `attack_range`, `chase_range`, `attack_damage`, and `attack_cooldown` allow for easy gameplay customization directly within the game engine, without modifying the script. This flexibility enables developers to quickly adjust character behavior, such as how far the character can detect the player or how fast it moves, facilitating testing and balancing of difficulty to enhance the gameplay experience. By making these parameters readily adjustable, the script supports more tailored and responsive game design .
The script incorporates gravity in the movement mechanics by applying a gravitational force when the character is not on the floor. This is handled within the `chase_player()` function, where the velocity on the y-axis is decreased by `gravity * delta` when the character is airborne. This affects chasing behavior by making sure that while in pursuit, the character naturally descends if not grounded, adding realism to the movement as it adjusts for vertical positioning. This dynamic ensures more realistic pathfinding and motion during chase sequences .
The script manages attacking behaviors by checking various conditions: it calculates the distance to the player and compares it with the specified attack range. Attacking is initiated only when the player is within this range and the monster is not already attacking. To ensure timing, the script uses a cooldown timer (`attack_timer`) to prevent immediate successive attacks. The function `is_player_in_attack_range()` checks if the player is not only within attack range but also in front of the monster by computing the dot product of the forward vector of the monster and the vector pointing to the player, ensuring the player is positioned properly to receive an attack .
The script determines the player's position relative to the character by calculating the Euclidean distance between the two and comparing it to a predefined `attack_range`. Additionally, it evaluates whether the player is directly in front using vector arithmetic, specifically by computing the dot product between the monster's forward vector (negative of `global_transform.basis.z`) and the normalized vector pointing from the monster to the player (`to_player_vector`). A dot product greater than 0.5 confirms the player is in front, combining range and positional checks to confirm eligibility for an attack .
During an attack, the script ensures that actions such as moving and chasing are halted by setting `navigation_agent.set_target_position(global_transform.origin)` and zeroing out velocity (`velocity = Vector3.ZERO`). This prevents the character from changing position during an attack. This interruption is important to maintain realism and effectiveness, as moving during an attack could interfere with animation integrity, reduce attack accuracy, and potentially allow the player to escape or visually glitch through inaccurate collision detections .