// -----------------------------------------------------------------------------------------------------// // Update is called once per frame void Update() { /* * STATE, holdFire, HardTarget, and SoftTarget are all already set for us * * This means just decide what to do based on the state and targets given * * */ // SET UP DEFAULT VALUES FOR STATE-BASED VARIABLES Vector2 moveDirection = new Vector2(0, 0); // what direction to move in (normalized later) bool shouldMove = false; // whether or not we should move bool shouldAttack = false; // whether or not we should attack bool shouldSprint = false; // whether or not to sprint bool shouldReload = false; // whether or not we should reload (if possible) bool shouldLoot = false; // whether or not to pick up items (if possible) float targetDistance = 0f; if (hardTarget != null) { targetDistance = Vector2.Distance(hardTarget.transform.position, transform.position); // value of distance to hard target } // determine what to do based on what state we are in // STATES DO NOT CHANGE HERE! switch (BehState) { case BehaviorState.Fighting: if (holdFire == false) { shouldAttack = true; } // hardTarget = enemies?? TODO: will this be somewhere else? if (targetDistance < minSafeDist) { shouldMove = true; moveDirection = GAMESTATE.findFleeDirection(gameObject); } shouldReload = true; break; case BehaviorState.Fleeing: shouldMove = true; shouldSprint = true; moveDirection = GAMESTATE.findFleeDirection(gameObject); // TODO set move target break; case BehaviorState.Looting: shouldMove = true; shouldReload = true; shouldLoot = true; // hard target will hold the closest item to go get, so move towards it... // TODO: hard pathfinding! moveDirection = hardTarget.transform.position - transform.position; break; case BehaviorState.Following: shouldReload = true; // TODO: dont move perfectly towards the player, Pathfinding if (targetDistance > minSafeDist) { shouldMove = true; moveDirection = hardTarget.transform.position - transform.position; } break; default: // just dont change anything, leave values the preset above break; } // PROCESS ACTIONS BASED ON ABOVE VARIABLES // if the character was busy doing something, can't perform the below actions if (character.busyState <= Time.time) { // the following get set below Vector2 newPos = transform.position; float movespeed = 0.0f; bool enableAttack = true; // reload weapons if (shouldReload && character.hasLowAmmo()) // TODO what if no ammo? { character.reload(); character.State = Character_BS.AnimState.Reload; } // pick up items else if (shouldLoot && (targetDistance < GAMESTATE.minLootDist)) // TODO: should we pickup items? { character.State = Character_BS.AnimState.Loot; character.busyState = Time.time + character.lootTime; // technically this should be done in character class // TODO: Now we need to go try for another item } // should we be moving? else if (shouldMove) { // Sprint or walk if (character.canSprint == true && (shouldSprint)) // are we going to sprint? { character.State = Character_BS.AnimState.Run; movespeed = character.runSpeed; character.SetFacing(moveDirection); enableAttack = false; } else { character.State = Character_BS.AnimState.Walk; movespeed = character.walkSpeed; character.SetFacing(moveDirection); // look in the direction we are moving unless interrupted by shooting later } // actually set new position Vector3 movDir = moveDirection.normalized; newPos = transform.position + (movDir * movespeed * Time.deltaTime); // actually move to the new location character.rigidbod.MovePosition(newPos); } // be idle else { character.State = Character_BS.AnimState.Idle; movespeed = 0.0f; if (hardTarget != null) { character.SetFacing(hardTarget); } } // HANDLE SHOOTING/ATTACKING if (enableAttack && shouldAttack && (hardTarget != null)) { bool is_moving = false; if (movespeed > 0.0f) { is_moving = true; } // TODO: Handle when hard target dies, or is behind a barrier (and a new target should be found) // aim at your target character.SetFacing(hardTarget); // attack with LEFT weapon if (character.meleeWeapon != null) { if (character.meleeWeapon.canAttack(is_moving) == true) { Vector2 direction = hardTarget.transform.position - character.meleeWeapon.shotspawn.position; GAMESTATE.MakeAttack(gameObject, direction, character.meleeWeapon); } } // attack with RIGHT weapon if (character.missileWeapon != null) { if (character.missileWeapon.canAttack(is_moving) == true) { Vector2 direction = hardTarget.transform.position - character.missileWeapon.shotspawn.position; GAMESTATE.MakeAttack(gameObject, direction, character.missileWeapon); } } } // ---- END MOVING ---- // } // if busy, like mid reload, we just face the target else { if (hardTarget != null) { character.SetFacing(hardTarget); } } }
// Update is called once per frame void Update() { Vector2 newPos = transform.position; // default bool is_moving = false; bool canSeeTarg = false; // NOW: lose % of intensity every X seconds float TimeMult = 1f; // The ratio of delta time into X seconds if (Time.deltaTime < forgetNoiseRate) { TimeMult = (forgetNoiseRate - Time.deltaTime) / forgetNoiseRate; } // drop intensity by a certain % each frame, drops quickly, stays nonzero for a long time if (targetIntensity > 0f) { targetIntensity = targetIntensity * TimeMult; } // lose intensity if we reach destination if (Vector2.Distance(transform.position, softTarget) < minForgetDistance) { targetIntensity = 0; } // only do logic every delayTime seconds if (Time.time > nextSyncTime) { nextSyncTime = Time.time + delayTime; // control which target mode we are in if (hardTarget != null) { targetmode = TargetMode.HardTarget; canSeeTarg = GAMESTATE.canSee(gameObject, hardTarget); // if the hard target gets too far away, switch to soft target float dist = Vector2.Distance(hardTarget.transform.position, transform.position); // if we cant see the hard target, set soft target and create a path if (canSeeTarg == false) { targetmode = TargetMode.FollowPath; softTarget = hardTarget.transform.position; pathDestinationTarget = softTarget; hardTarget = null; if (path == null) { //print("Find path1 at " + Time.time); path = GAMESTATE.findPath(transform.position, pathDestinationTarget); if (null == path) { targetmode = TargetMode.SoftTarget; } else { pathTarget = path[0]; pathDestinationTarget = softTarget; } } } // if hard target moves out of range, go back to soft else if (dist > hardDetectRange) { targetmode = TargetMode.SoftTarget; softTarget = hardTarget.transform.position; // set the soft target to the old pos targetIntensity = maxIntensity; hardTarget = null; path = null; } } // is the intensity great enough to follow? if so, set soft target else if (targetIntensity > minIntensity) { // there already is a soft target canSeeTarg = GAMESTATE.canSeeIgnoreCharacters(transform.position, softTarget); if (canSeeTarg == false) { // follow path if we cant see where the sound came from // if we dont yet have a path, get one, or if this is a new soft target, generate a new path targetmode = TargetMode.FollowPath; if (path == null || (pathDestinationTarget != softTarget)) { path = GAMESTATE.findPath(transform.position, pathDestinationTarget); // there is no path if (null == path) { targetmode = TargetMode.SoftTarget; } else { pathTarget = path[0]; pathDestinationTarget = softTarget; } } } else { // otherwise just go towards it targetmode = TargetMode.SoftTarget; path = null; } } else { targetmode = TargetMode.NoTarget; softTarget = transform.position; targetIntensity = 0; path = null; } //print(Vector3.Magnitude(character.rigidbod.velocity) + " " + Time.time); } // handle behavior based off of the target mode switch (targetmode) { case (TargetMode.NoTarget): { character.State = Character_BS.AnimState.Idle; break; } case (TargetMode.SoftTarget): { is_moving = true; character.SetFacing(softTarget); // face the soft target VECTOR character.State = Character_BS.AnimState.Walk; Vector2 dir = new Vector2(softTarget.x, softTarget.y); dir -= new Vector2(transform.position.x, transform.position.y); dir.Normalize(); character.rigidbod.velocity = dir * character.walkSpeed; break; } case (TargetMode.HardTarget): { is_moving = true; character.SetFacing(hardTarget); // face the target game object character.State = Character_BS.AnimState.Run; Vector2 dir = hardTarget.transform.position - transform.position; float dist = dir.magnitude; dir.Normalize(); character.rigidbod.velocity = dir * character.runSpeed; if (dist < meleeDist) { // makes melee attack if (character.meleeWeapon.canAttack(is_moving) == true) { GAMESTATE.MakeAttack(gameObject, dir, character.meleeWeapon); } } break; } case (TargetMode.FollowPath): { // If we can see the next pathTarget, also just choose it (instead of walking too far the wrong way) float dist = Vector2.Distance(transform.position, pathTarget.transform.position); int i = path.IndexOf(pathTarget); is_moving = true; if (i + 1 < path.Count) { bool skipNode = GAMESTATE.canSeeIgnoreCharacters(transform.position, path[i + 1].transform.position); if (dist <= minPathNodeDist || skipNode == true) { // get the next path target pathTarget = path[i + 1]; //print("going to next node " + Time.time); } } // if too close to last path else if (dist <= minPathNodeDist) { targetIntensity = 0; is_moving = false; } if (is_moving == true) { Vector2 pathvector = pathTarget.transform.position; character.SetFacing(pathvector); // face the soft target VECTOR character.State = Character_BS.AnimState.Walk; Vector2 dir = pathvector; dir -= new Vector2(transform.position.x, transform.position.y); dir.Normalize(); character.rigidbod.velocity = Vector2.Lerp(character.rigidbod.velocity, dir * character.walkSpeed, 0.5f); } break; } default: { break; } } }
// Update is called once per frame void Update() { // always face target // // enable user to play/pause game with escape if (Input.GetKeyDown(KeyCode.Escape)) { GAMESTATE.togglePaused(); } if ((character.freezeChar == false) && (character.busyState <= Time.time)) { Vector2 newPos = transform.position; // ---- MOVING ---- // // DIRECTION // bool move_forward = Input.GetKey(KeyCode.W); bool move_right = Input.GetKey(KeyCode.D); bool move_left = Input.GetKey(KeyCode.A); bool move_back = Input.GetKey(KeyCode.S); float movespeed = 0.0f; bool enableAttack = true; bool is_moving = false; bool RightAttack = false; bool LeftAttack = false; // reload weapons if (Input.GetKeyDown(KeyCode.R)) { character.reload(); character.State = Character_BS.AnimState.Reload; } // pick up items else if (Input.GetKey(KeyCode.E)) { character.State = Character_BS.AnimState.Loot; character.busyState = Time.time + character.lootTime; // TODO: technically this should be done in character class } else if (move_forward || move_left || move_right || move_back) { is_moving = true; if (character.canSprint == true && Input.GetKey(KeyCode.LeftShift)) { character.State = Character_BS.AnimState.Run; movespeed = character.runSpeed; enableAttack = false; } else { movespeed = character.walkSpeed; character.State = Character_BS.AnimState.Walk; } } else { // be idle character.State = Character_BS.AnimState.Idle; movespeed = 0.0f; } // attack with melee weapon if (character.meleeWeapon != null) { if (character.meleeWeapon.isFullAuto == true) { if (enableAttack && Input.GetKey(KeyCode.Mouse1)) { LeftAttack = true; } } else { if (enableAttack && Input.GetKeyDown(KeyCode.Mouse1)) { LeftAttack = true; } } if (LeftAttack == true) { if (character.meleeWeapon.canAttack(is_moving) == true) { Vector2 direction = target.transform.position - character.meleeWeapon.shotspawn.position; GAMESTATE.MakeAttack(gameObject, direction, character.meleeWeapon); } } } // attack with missile weapon if (character.missileWeapon != null) { if (character.missileWeapon.isFullAuto == true) { if (enableAttack && Input.GetKey(KeyCode.Mouse0)) { RightAttack = true; } } else { if (enableAttack && Input.GetKeyDown(KeyCode.Mouse0)) { RightAttack = true; } } if (RightAttack == true) { if (character.missileWeapon.canAttack(is_moving) == true) { Vector2 direction = target.transform.position - character.missileWeapon.shotspawn.position; GAMESTATE.MakeAttack(gameObject, direction, character.missileWeapon); } } } //TODO: interrupt other weapon firing! if (Input.GetKeyDown(KeyCode.G)) { if (character.tertiaryWeapon != null) { if (is_moving == false) { Vector2 direction = target.transform.position - transform.position; GAMESTATE.MakeTertiaryAttack(gameObject, direction, character.tertiaryWeapon); } } } // ACTUALLY MOVE AND SCALE VALUE Vector3 forwardDirection = target.transform.position - transform.position; forwardDirection.Normalize(); Vector3 finalDirection = forwardDirection; switch (moveControls) { case MoveControls.MouseRotate: if (move_forward && move_right) { finalDirection = Quaternion.Euler(0, 0, -45) * forwardDirection; } else if (move_forward && move_left) { finalDirection = Quaternion.Euler(0, 0, 45) * forwardDirection; } else if (move_back && move_right) { movespeed = character.walkSpeed; movespeed = movespeed * character.strafeRate; finalDirection = Quaternion.Euler(0, 0, -135) * forwardDirection; } else if (move_back && move_left) { movespeed = character.walkSpeed; movespeed = movespeed * character.strafeRate; finalDirection = Quaternion.Euler(0, 0, 135) * forwardDirection; } else if (move_back) { movespeed = character.walkSpeed; finalDirection = Quaternion.Euler(0, 0, 180) * forwardDirection; movespeed = movespeed * character.strafeRate; } else if (move_left) { movespeed = character.walkSpeed; finalDirection = Quaternion.Euler(0, 0, 90) * forwardDirection; movespeed = movespeed * character.strafeRate; } else if (move_right) { movespeed = character.walkSpeed; finalDirection = Quaternion.Euler(0, 0, -90) * forwardDirection; movespeed = movespeed * character.strafeRate; } break; case MoveControls.Fixed8Ways: character.SetFacing(target); if (move_forward && move_right) { finalDirection = new Vector3(0.707f, 0.707f, 0); } else if (move_forward && move_left) { finalDirection = new Vector3(-0.707f, 0.707f, 0); } else if (move_back && move_right) { finalDirection = new Vector3(0.707f, -0.707f, 0); } else if (move_back && move_left) { finalDirection = new Vector3(-0.707f, -0.707f, 0); } else if (move_back) { finalDirection = new Vector3(0, -1, 0); } else if (move_left) { finalDirection = new Vector3(-1, 0, 0); } else if (move_right) { finalDirection = new Vector3(1, 0, 0); } else { finalDirection = new Vector3(0, 1, 0); } break; default: break; } if (is_moving) { //print("Speed: " + Vector3.Magnitude(finalDirection * movespeed * Time.deltaTime)); Vector3 scaledDir = (finalDirection * movespeed * Time.deltaTime); newPos = transform.position + scaledDir; character.rigidbod.AddForce(scaledDir * 5000); } // ---- END MOVING ---- // } }