private void ProcessTaskWander() { //Random wait at path end if (_endOfPathWaitTime > 0.0f) { _endOfPathWaitTime -= Time.deltaTime; _moverRef.Direction = Vector2.zero; return; } //Find a new path if (_currentPath == null || _currentPath.Count == 0) { if (!_waitingOnPathResult) { _waitingOnPathResult = _pathfinder.RequestPathfind(this.transform.position, _pathfinder.GetRandomPointInBounds(CurrentTask != AITask.Wander), this, cbPathResult); _moverRef.Direction = Vector2.zero; } } //We've done our current one else if (_currentNode >= _currentPath.Count) { _currentPath.Clear(); _currentNode = 0; _moverRef.Direction = Vector2.zero; if (CurrentTask == AITask.Wander) { _endOfPathWaitTime = Random.Range(0.5f, 3.0f); } } else { //Otherwise travel in the direction of the next node var direction = _currentPath[_currentNode].position - transform.position; var normal = transform.forward; Vector3.OrthoNormalize(ref normal, ref direction); _moverRef.Direction = direction; if ((transform.position - _currentPath[_currentNode].position).magnitude <= REACHED_NODE_DISTANCE) { _currentNode++; if (_currentNode >= _currentPath.Count) { _moverRef.Direction = Vector2.zero; } } } }
private void FixedUpdate() { // control crouching Height = Mathf.SmoothDamp(Height, targetHeight, ref heightVelocity, heightChangeSpeed); // 2d input vector Vector2 input = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); // moving diagonally isn't faster // not a good movement tech to make it faster since it's not intuitive and would complicate the movement for AI // since you would have to calculate speed based on direction of body relative to head, and their pathfinding // may not accomodate it (i.e. they may swing past the target by accident if they move diagonally at one point // while moving.) input = Vector2.ClampMagnitude(input, 1); if (grounded) { bool sliding = false; // See if surface immediately below should be slid down. We use this normally rather than a ControllerColliderHit point, // because that interferes with step climbing amongst other annoyances if (Physics.Raycast(m_Transform.position, -Vector3.up, out slideRaycastHit, rayDistance)) { if (Vector3.Angle(slideRaycastHit.normal, Vector3.up) > slideLimit) { sliding = true; } } // However, just raycasting straight down from the center can fail when on steep slopes // So if the above raycast didn't catch anything, raycast down from the stored ControllerColliderHit point instead else { Physics.Raycast(contactPoint + Vector3.up, -Vector3.up, out slideRaycastHit); if (Vector3.Angle(slideRaycastHit.normal, Vector3.up) > slideLimit) { sliding = true; } } // If we were falling, and we fell a vertical distance greater than the threshold, run a falling damage routine if (falling) { falling = false; // We just landed right? Do a short crouch-uncrouch to give a bounce to landing if (Input.GetButton("Crouch")) { height = crouchHeight - landRecoilHeightChange; } else { height = standHeight - landRecoilHeightChange; } } // If running isn't on a toggle, then use the appropriate speed depending on whether the run button is down if (!toggleRun) { if (Input.GetButton("Crouch") && grounded) { currentSpeed = crouchSpeed; } else { currentSpeed = Input.GetKey(KeyCode.LeftShift) ? walkSpeed : moveSpeed; } } // If sliding (and it's allowed), or if we're on an object tagged "Slide", get a vector pointing down the slope we're on if ((sliding && slideWhenOverSlopeLimit) || (slideOnTaggedObjects && slideRaycastHit.collider.CompareTag("Slide"))) { Vector3 hitNormal = slideRaycastHit.normal; moveDirection = new Vector3(hitNormal.x, -hitNormal.y, hitNormal.z); Vector3.OrthoNormalize(ref hitNormal, ref moveDirection); moveDirection *= slideSpeed; playerControl = false; } // Otherwise recalculate moveDirection directly from axes, adding a bit of -y to avoid bumping down inclines else { moveDirection = new Vector3(input.x, -antiBumpFactor, input.y); moveDirection = m_Transform.TransformDirection(moveDirection) * currentSpeed; playerControl = true; } // Jump! But only if the jump button has been released and player has been grounded for a given number of frames if (!Input.GetButton("Jump")) { jumpTimer++; } else if (jumpTimer >= antiBunnyHopFactor) { moveDirection.y = jumpSpeed; jumpTimer = 0; } } else { // TODO: Decide if we can get walljump working. Leaning no right now... // if (canWallJump) // { // // Jump! But only if the jump button has been released and player has been grounded for a given number of frames // if (!Input.GetButton("Jump")) // { // m_JumpTimer++; // } // else if (m_JumpTimer >= m_AntiBunnyHopFactor) // { // if(playerAnimation != null) // playerAnimation.jumpPoint = transform.position; // // m_MoveDirection.y = m_JumpSpeed; // m_JumpTimer = 0; // } // // canWallJump = false; // } // If we stepped over a cliff or something, set the height at which we started falling if (!falling) { falling = true; } // If air control is allowed, check movement but don't touch the y component if (airControl && playerControl) { moveDirection.x = input.x * currentSpeed; moveDirection.z = input.y * currentSpeed; moveDirection = m_Transform.TransformDirection(moveDirection); } } if (thrusting) { thrustDirection.x = thrustInputX * currentThrustSpeed; thrustDirection.y = 0; thrustDirection.z = thrustInputY * currentThrustSpeed; } else { thrustDirection = Vector3.zero; } thrustDirection = m_Transform.TransformDirection(thrustDirection); // Apply gravity moveDirection.y -= gravity * Time.deltaTime; // Move the controller, and set grounded true or false depending on whether we're standing on something grounded = (controller.Move((moveDirection + thrustDirection) * Time.deltaTime) & CollisionFlags.Below) != 0; }
private void ProcessTaskAttackTarget() { _moverRef.Direction = Vector2.zero; if (_taskTarget == null) { _taskTarget = FindSuitableTargetToAttack(); _moverRef.Direction = Vector2.zero; if (_taskTarget == null) { _targetFindAttempts++; if (_targetFindAttempts >= 4) { CurrentTask = AITask.Wander; _targetFindAttempts = 0; } return; } _targetFindAttempts = 0; } //Retarget if our target has begun being infected, and not by me if (!_waitingOnPathResult && _statsRef.BeingInfectedBy != null && !_statsRef.Infected) { if (_statsRef.BeingInfectedBy != this.gameObject) { ClearTarget(); return; } } if (_taskTarget.GetComponent <KillActor>()) { ClearTarget(); return; } //TODO Maybe retarget if we see something else is right next to us //Retarget if the target is now infected if (!_waitingOnPathResult && _statsRef.Infected && _taskTarget.GetComponent <ActorStats>().Infected) { ClearTarget(); return; } _timeSinceLastAttackAction += Time.deltaTime; if (_timeSinceLastAttackAction >= 7.5f) { if (((Vector2)_taskTarget.transform.position - (Vector2)this.transform.position).magnitude > _statsRef.AttackRange * 2.0f) { ClearTarget(); return; } } Vector2 customMovetoPoint = Vector2.zero; if (_statsRef.UsesAoeAttack) { if (_actionRef.CanAttack) { _actionRef.DoAction(ActionManager.ActionType.Attack); _actionRef.TargetLocationForAction = this.transform.position; _timeSinceLastAttackAction = 0.0f; } } //If we're close enough, attack the target else if (((Vector2)_taskTarget.transform.position - (Vector2)this.transform.position).magnitude < _statsRef.AttackRange) { if (_actionRef.CanAttack) { _actionRef.DoAction(ActionManager.ActionType.Attack); _actionRef.TargetLocationForAction = _taskTarget.transform.position; _timeSinceLastAttackAction = 0.0f; } //TODO maybe reintroduce this - atm enemies can just sit inside their target //customMovetoPoint = _taskTarget.transform.position; } if (_currentPath == null || _currentPath.Count == 0) { _moverRef.Direction = Vector2.zero; if (!_waitingOnPathResult) { if (_pathfinder.RequestPathfind(this.transform.position, _taskTarget.transform.position, this, cbPathResult)) { _originalTargetPlace = _taskTarget.transform.position; _waitingOnPathResult = true; } } } //We've done our current one else if (_currentNode >= _currentPath.Count) { _currentPath.Clear(); _currentNode = 0; } //Recalculate if the target has moved else if (((Vector2)_taskTarget.transform.position - _originalTargetPlace).magnitude >= REEVALUATE_DIST_FOR_TARGET_HAVING_MOVED) { if (!_waitingOnPathResult) { if (_pathfinder.RequestPathfind(this.transform.position, _taskTarget.transform.position, this, cbPathResult)) { _originalTargetPlace = _taskTarget.transform.position; _waitingOnPathResult = true; } } } else { //Otherwise travel in the direction of the next node var direction = (Vector2)_currentPath[_currentNode].position - (Vector2)transform.position; var orthDir = new Vector3(direction.x, direction.y, 0); var normal = transform.forward; Vector3.OrthoNormalize(ref normal, ref orthDir); _moverRef.Direction = orthDir; if ((transform.position - _currentPath[_currentNode].position).magnitude <= REACHED_NODE_DISTANCE) { _currentNode++; if (_currentNode >= _currentPath.Count) { _moverRef.Direction = Vector2.zero; } } } }