I’m currently developing a 3D fighter with my friends and we’re having the AI act against the player depending on their moves, such as attacking when he isn’t blocking, blocking when he’s attacking, etc. My first step was to make the AI a little slower, because right now, as soon as the AI gets close he just lets loose on his sword like there’s no tomorrow, and he can never check in time if the player is blocking, making him both an effective AI and a fairly stupid one. So, I read up on the “Invoke()” command and I thought this would work fine with my game, so I put it in, and everything still functions the way it would. I put a two second delay, for testing purposes, and the AI follows these rules when first, but after the first go, he does the exact same thing as before. Here’s my code
using UnityEngine;
using System.Collections;
public class AIPlayerController : MonoBehaviour {
//Created on September 07, 2015 by
//Purpose: Enables the AI to move, rotate, and make decisions
//Edited on September 21, 2015 by
//Purpose: Overhauled code to simplify it, cleaned up comments, added comments
//Edited on September 23, 2015 by
//Purpose: Allowing AI to attack, attempted to delay decision making, setup foundation for further additions
//Edited on September 24, 2015 by
//Purpose: Allowing AI to block, added comments, attempted to delay decision making, adjusted comments to edited sections
//Bugs
// - 1. AI only has "Delay" at the beginning of the script
// -- Suspects it has something to do with the Invoke() command
//NOTE "Player" refers to the actual Player and NOT the AI, AI is referred to as either Bot or AI.
//BLOCK 0: Defines any variables/classes used in the script
//Classes Used
public CharacterController CC; //Referencings the CharacterController component for movement
public CharacterAnimator PlayerCA; //References the CharacterAnimator script to check what animation's Player is using
public Transform Player; //References the Transform component of the Player for rotations
//Reguarding Movements
public float JumpHeight = 10f; //(Currently Not In Use) Allows player to jump with a certain strength
public float Speed = 1f; //Multiplied with the CC.Move() to make movement quicker
public float Gravity = 1f; //Simulates gravity so falling occurs
public Vector3 MoveDirection; //Direction used in Move() which is decided by the AI
//Reguarding Rotations
Vector3 Target; //Finds the "Target" to use in the LookRotation function
Quaternion NewRotation; //New rotation to rotate to
//Reguarding Decision Making
public bool PromptAttack; //Bool used to prompt the AICharacterAnimator to attack
public bool PromptBlock; //Bool used to prompt the AICharacterAnimator to block
int MoveX = 0; //(Currently Not In Use) Tells the AI when to move side to side
int MoveY = 0; //(Currently Not In Use) Tells the AI when to move up or down, aka jump
int MoveZ = 0; //Tells the AI when to move forwards or backwards
float PlayerDistance; //Tells the AI how far away the Player is
void Update(){
//BLOCK 1: This block of code manages the object rotation
//Finds position between Player and self
Target = Player.position - transform.position;
//Finds Rotation to rotate to using LookRotation, modifies NewRotation to only rotate along the Y-axis
NewRotation = Quaternion.LookRotation (Target);
NewRotation.eulerAngles = new Vector3(0,NewRotation.eulerAngles.y,0);
//Sets the rotation
transform.rotation = NewRotation;
//Invoke meant to delay the AI in decision making
//Reference the DecideStuff() function for explanation
Invoke ("AIMain",2f * Time.deltaTime);
//Compiles all data gathered into a Vector3
MoveDirection = new Vector3(MoveX,MoveY,MoveZ);
//Makes MoveDirection relative to world cordinates rather than local
MoveDirection = transform.TransformDirection(MoveDirection);
//Multiplies the X, Y, and Z of MoveDirection by Speed to give the player more speed
MoveDirection *= Speed;
//Applies Gravity to the MoveDirection variable
MoveDirection.y -= Gravity;
} //Closes Update
void FixedUpdate(){
//BLOCK 3: Puts the compliled data of BLOCK 2 to use and moves player
//Moves Player
CC.Move(MoveDirection * Time.deltaTime);
} //Closes FixedUpdate
//Function meant to act as the centeralized function of all the decision making functions
void AIMain(){
//BLOCK 2: This block of code manages the decision making of the AI
//Resets Prompt variables to "clear"
PromptAttack = false;
PromptBlock = false;
//Invokes AIMove to delay decision making
Invoke ("AIMove",2f * Time.deltaTime);
} //Closes AIMain function
//Function tests whether or not the player is attacking/blocking and acts accordingly
void AICombat(){
//If Player is blocking, do not attack
if(PlayerCA.Blocking == true){
//Sets PromptAttack to true to tell AICharacterAnimator not to attack
PromptAttack = false;
}
//Checks to see if player is attacking, if true, stops AI and blocks
else if(PlayerCA.Attacking == true){
//Doesn't allow AI to move
MoveZ = 0;
}
//If Player isn't blocking, attack
else{
//Sets PromptAttack to true to tell AICharacterAnimator to attack
PromptAttack = true;
}
} //Closes AICombat function
//Function adjusts the variables used in deciding what to do based on distance
void AIMove(){
//Calculates distance, stores in a float
PlayerDistance = Vector3.Distance(transform.position,Player.position);
//Resets MoveZ so AI doesn't continually walk if no conditions are met
MoveZ = 0;
//If player is too far away to attack, move forward
if(PlayerDistance > 3){
MoveZ = 1;
}
//If player is too close, move away
else if(PlayerDistance < 2){
MoveZ = -1;
}
//If either conditions aren't met, Invoke the AICombat Function
else{
//Check the function for comments
Invoke("AICombat",2f * Time.deltaTime);
}
} //Closes AIMove function
} //Closes Class
Sorry if the excessive comments get in the way. Any help would be greatly appreciated! This game is only going to be played by a single player, so the AI is fairly important. Lol