示例#1
0
    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;
                }
            }
        }
    }
示例#2
0
    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;
    }
示例#3
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;
                }
            }
        }
    }