// Update is called once per frame void Update() { // regardless of state, enter DANGER state if Wanderer is in danger if (my_wanderer.inDanger) { state = Statetype.DANGER; } // call on handler for current state switch (state) { case Statetype.SAFE: handleSafe(); break; case Statetype.CAUTIOUS: handleCautious(); break; case Statetype.DANGER: handleDanger(); break; default: handleSafe(); break; } // count down timer for sound effects if (gruntCooldown >= 0f) { gruntCooldown -= Time.deltaTime; } }
// how to behave if player attacks void handleDanger() { // make sure to run into player and not stop short my_nav.stoppingDistance = 0f; // check if the Wanderer is out of danger and player is far enough away if (!my_wanderer.inDanger && distToPlayer() > CAUTION_RADIUS) { state = Statetype.CAUTIOUS; if (source.isPlaying) { source.Stop(); } my_nav.stoppingDistance = 0.5f; } // otherwise pursue player and play danger music else { if (source.clip != dangerClip) { source.clip = dangerClip; } if (!source.isPlaying) { source.Play(); } lookAt(player); moveTo(player); makeGrunt(0.01f); } }
// *************** Built-In Methods **************** // Use this for initialization protected void Start() { CoreAIStart(); state = Statetype.SAFE; wanderer = GameObject.FindWithTag("Wanderer"); my_wanderer = wanderer.GetComponent <WandererAI>(); source = GetComponent <AudioSource>(); gruntCooldown = 0f; }
// **************** Start and Update ******************** // Use this for initialization. If you want to use Start() method, it // must include the function call CoreAIStart() protected void Start() { CoreAIStart(); rend = (GameObject.Find("chr_janitor1")).GetComponent <Renderer>(); normal = Shader.Find("Diffuse"); glowing = Shader.Find("Self-Illumin/Diffuse"); this.setActive(false); state = Statetype.FOLLOWING; }
// behavior for SEEN state void handleStill() { // do not move my_nav.ResetPath(); // if the player is sufficiently far enough from the Stalker and not looking, switch state if (safeToGo()) { state = Statetype.STALKING; } }
// *** FSM states ******************************************** // behavior for STALKING state void handleStalking() { // move towards the player moveTo(player); // if too close or in view of player, switch state if (!(safeToGo())) { state = Statetype.STILL; } }
float CAUTION_RADIUS = 8f; // how close the player can get before Protector is cautious // ****************** FSM **************** // how to behave if player is far away and not attacking void handleSafe() { // look at and follow the Wanderer lookAt(wanderer); moveTo(wanderer); // transition states if player gets too close if (Vector3.Distance(player_transform.position, wanderer.transform.position) < CAUTION_RADIUS) { state = Statetype.CAUTIOUS; } }
// how to behave if player is too close void handleCautious() { // look at and block off the player with body lookAt(player); moveTo(blockOffPlayer()); // occasionally make a grunting noise makeGrunt(0.005f); // transition back to safe state if player is far enough away if (Vector3.Distance(player_transform.position, wanderer.transform.position) > CAUTION_RADIUS) { state = Statetype.SAFE; } }
// helper method to do stuff found in two states bool checkMouseButtons() { if (Input.GetMouseButtonDown(0)) { // stop acting / listening if right button pressed and start following if (getMouseObject().tag == "Companion") { // stop glowing rend.material.shader = normal; state = Statetype.FOLLOWING; return(true); } // change direction if left click is pressed state = Statetype.MOVING; mouse_position = findMouse(); return(true); } return(false); }
// moves Buddy to the mouse position, then returns to listening void handleMoving() { if (checkMouseButtons()) { return; } // if position reached, go back to listening if (Vector3.Distance(my_transform.position, mouse_position) < 0.1) { state = Statetype.LISTENING; return; } // default is to keep moving else { moveTo(mouse_position); } }
// how to behave if Buddy is not waiting for a command void handleFollowing() { // make him stop a little further away from you my_nav.stoppingDistance = 9f; // click on Buddy to make him wait and listen for commands if (Input.GetMouseButtonDown(0)) { if (getMouseObject().tag == "Companion") { state = Statetype.LISTENING; } } // default is follow player around else { lookAt(playerFront); moveTo(playerFront); } }
// *** initialization ************************************** protected void Start() { CoreAIStart(); // call parent's initializer state = Statetype.STILL; // set default state }
public bool HasState(Statetype statetype) { return (state & statetype) != Statetype.NONE; }
public void AddState(Statetype statetype) { state = state | statetype; }