ProjectVectorOnPlane() 공개 정적인 메소드

public static ProjectVectorOnPlane ( Vector3 planeNormal, Vector3 vector ) : Vector3
planeNormal Vector3
vector Vector3
리턴 Vector3
예제 #1
0
    public bool HeavyDamage(int damage, Vector3 origin)
    {
        if (status.Invincible())
        {
            return(false);
        }

        if (StateCompare(MarioStates.Knockback) || StateCompare(MarioStates.KnockbackForwards) || StateCompare(MarioStates.TeleportIn) || StateCompare(MarioStates.TeleportOut))
        {
            return(false);
        }

        Vector3 direction = Math3d.ProjectVectorOnPlane(controller.up, origin - transform.position).normalized;

        if (direction == Vector3.zero)
        {
            direction = lookDirection;
        }

        bool forward = Vector3.Angle(direction, lookDirection) < 90;

        if (Airborn())
        {
            if (forward)
            {
                moveSpeed    = -3.0f;
                currentState = MarioStates.AirKnockback;
            }
            else
            {
                moveSpeed    = 3.0f;
                currentState = MarioStates.AirKnockbackForwards;
            }
        }
        else
        {
            if (forward)
            {
                currentState = MarioStates.Knockback;
                moveSpeed    = -3.0f;
            }
            else
            {
                currentState = MarioStates.KnockbackForwards;
                moveSpeed    = 3.0f;
            }
        }

        lookDirection = forward ? direction : -direction;

        SmartCamera.Shake(1.6f, 25.0f, 0.5f);

        sound.PlayTakeDamage();

        Instantiate(TakeDamageEffect, transform.position + controller.up * controller.height * 0.6f, Quaternion.identity);

        status.TakeDamage(damage);

        return(true);
    }
예제 #2
0
    // Update is called once per frame
    void Update()
    {
        Vector3 direction = Math3d.ProjectVectorOnPlane(transform.up, (target.position - transform.position).normalized);

        if (Vector3.Distance(target.position, transform.position) < SightDistance && Vector3.Angle(direction, transform.forward) > SightAngle)
        {
            transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(direction), TurnSpeed * Time.deltaTime);

            if (!AnimatedMesh.GetComponent <Animation>().IsPlaying("turn"))
            {
                AnimatedMesh.GetComponent <Animation>().Play("turn");

                GetComponent <AudioSource>().Play();
            }
        }
        else
        {
            if (!AnimatedMesh.GetComponent <Animation>().isPlaying)
            {
                AnimatedMesh.GetComponent <Animation>().Play("idle");
            }
        }

        windRotation = SuperMath.ClampAngle(windRotation + 360.0f * Time.deltaTime);

        WindTransform.Rotation = Quaternion.Euler(new Vector3(0, 0, windRotation));
    }
예제 #3
0
    void Wander_SuperUpdate()
    {
        if (!IsGrounded(0.5f, true))
        {
            currentState = BobOmbStates.Fall;
            return;
        }

        Vector3 direction = target.position - transform.position;

        direction = Math3d.ProjectVectorOnPlane(controller.up, direction);

        float distance = Vector3.Distance(target.position, transform.position);

        if (Vector3.Angle(direction, lookDirection) < FieldOfView && distance < SightDistance)
        {
            currentState = BobOmbStates.Chase;
            return;
        }

        moveSpeed = Mathf.MoveTowards(moveSpeed, WanderSpeed, 3.0f * Time.deltaTime);

        lookDirection = Quaternion.AngleAxis(30.0f * Time.deltaTime, controller.up) * lookDirection;

        moveDirection = moveSpeed * lookDirection;
    }
예제 #4
0
    private float WallCollisionAngle(Vector3 wallNormal, Vector3 direction)
    {
        Vector3 planarDirection = Math3d.ProjectVectorOnPlane(controller.up, direction);
        Vector3 planarWall      = Math3d.ProjectVectorOnPlane(controller.up, wallNormal);

        return(Vector3.Angle(planarWall, planarDirection));
    }
    /// <summary>
    ///     Provides raycast data based on where a SphereCast would contact the specified normal
    ///     Raycasting downwards from a point along the controller's bottom sphere, based on the provided
    ///     normal
    /// </summary>
    /// <param name="groundNormal">Normal of a triangle assumed to be directly below the controller</param>
    /// <param name="hit">Simulated SphereCast data</param>
    /// <returns>True if the raycast is successful</returns>
    private bool SimulateSphereCast(Vector3 groundNormal, out RaycastHit hit)
    {
        var groundAngle = Vector3.Angle(groundNormal, up) * Mathf.Deg2Rad;

        var secondaryOrigin = transform.position + up * Tolerance;

        if (!Mathf.Approximately(groundAngle, 0))
        {
            var horizontal = Mathf.Sin(groundAngle) * radius;
            var vertical   = (1.0f - Mathf.Cos(groundAngle)) * radius;

            // Retrieve a vector pointing up the slope
            var r2 = Vector3.Cross(groundNormal, down);
            var v2 = -Vector3.Cross(r2, groundNormal);

            secondaryOrigin += Math3d.ProjectVectorOnPlane(up, v2).normalized *horizontal + up * vertical;
        }

        if (Physics.Raycast(secondaryOrigin, down, out hit, Mathf.Infinity, Walkable))
        {
            // Remove the tolerance from the distance travelled
            hit.distance -= Tolerance;

            return(true);
        }
        return(false);
    }
예제 #6
0
    public void SetTargetWithAngle(Vector3 point, float angle)
    {
        currentRadian = angle * Mathf.Deg2Rad;

        targetPoint = point;
        //GizmosHelper.DrawBox(point, Vector3.one * 0.2f, Color.yellow);
        Vector3 direction = point - firePoint.position;

        //if (Vector3.Angle(direction, transform.forward) > 10)
        //{
        //    // Haven't face the right direction.
        //    projectileArc.gameObject.SetActive(false);
        //    return;
        //}
        //else
        //{
        //    projectileArc.gameObject.SetActive(true);
        //}

        float yOffset = direction.y;

        direction = Math3d.ProjectVectorOnPlane(Vector3.up, direction);
        float distance = direction.magnitude;

        currentSpeed = ProjectileMath.CalculateLaunchSpeed(distance, yOffset, Physics.gravity.magnitude, angle * Mathf.Deg2Rad);

        projectileArc.UpdateArc(currentSpeed, distance, Physics.gravity.magnitude, currentRadian, direction, true);
        SetThrowPoint(direction, currentRadian * Mathf.Rad2Deg);
    }
예제 #7
0
    void Fall_SuperUpdate()
    {
        if (AcquiringGround())
        {
            moveDirection = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
            currentState  = PlayerStates.Idle;
            return;
        }

        if (input.Current.JumpInput && doubleJump == false)
        {
            currentState = PlayerStates.DoubleJump;
            return;
        }

        if (input.Current.JumpInput && doubleJump == true)
        {
            currentState = PlayerStates.Glide;
            return;
        }

        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        planarMoveDirection     = Vector3.MoveTowards(planarMoveDirection, LocalMovement() * WalkSpeed, JumpAcceleration * controller.deltaTime);
        verticalMoveDirection  -= controller.up * Gravity * controller.deltaTime;
        verticalMoveDirection.y = Mathf.Max(verticalMoveDirection.y, -7f);

        moveDirection = planarMoveDirection + verticalMoveDirection;
    }
예제 #8
0
    private bool GoldBodySlam()
    {
        float radius = controller.radius * 1.5f;

        Collider[] colliders = Physics.OverlapSphere(transform.position + controller.up * controller.height * 0.5f, radius);

        foreach (var col in colliders)
        {
            EnemyMachine machine = col.GetComponent <EnemyMachine>();

            if (machine != null)
            {
                if (machine.GetStruck(Math3d.ProjectVectorOnPlane(controller.up, machine.transform.position - transform.position).normalized, 7.0f, 15.0f))
                {
                    sound.PlayImpact();

                    machine.MakeGold();
                }
            }

            RollingBallGoldDestroy ball = col.GetComponent <RollingBallGoldDestroy>();

            if (ball)
            {
                ball.BlowUp();
            }
        }

        return(false);
    }
예제 #9
0
        /*
         * Provides raycast data based on where a SphereCast would have contacted
         * the specified normal.
         * Raycasting downwards from a point along the controller's bottom sphere,
         * based on the provided normal.
         */
        private bool SimulateSphereCast(CollisionSphere collisionSphere, Vector3 groundNormal, out RaycastHit hit)
        {
            float groundAngle = Vector3.Angle(groundNormal, playerView.Up) * Mathf.Deg2Rad;

            Vector3 secondaryOrigin = playerView.Position + (playerView.Up * settings.tolerance);

            if (!Mathf.Approximately(groundAngle, 0))
            {
                float horizontal = Mathf.Sin(groundAngle) * collisionSphere.Radius;
                float vertical   = (1f - Mathf.Cos(groundAngle)) * collisionSphere.Radius;

                Vector3 upslopeDirection = -CollisionMath.DownslopeDirection(groundNormal, playerView.Down);

                Vector3 horizontalDirection = Math3d.ProjectVectorOnPlane(playerView.Up, upslopeDirection).normalized;
                secondaryOrigin += horizontalDirection * horizontal + playerView.Up * vertical;
            }

            if (SphereCast(secondaryOrigin, settings.epsilon, playerView.Down, out hit))
            {
                hit.distance -= settings.tolerance;
                return(true);
            }

            return(false);
        }
예제 #10
0
    bool SlopeLimit()
    {
        //Calculate the angle with the current ground first to see if it is greater than slope limit
        Vector3 n = _currentGround.normal;
        float   a = Vector3.Angle(n, transform.up);

        if (a > slopeLimit)
        {
            //Grab the direction that the controller is moving in
            Vector3 absoluteMoveDirection = Math3d.ProjectVectorOnPlane(n, transform.position - initialPosition);

            // Retrieve a vector pointing down the slope
            Vector3 r = Vector3.Cross(n, -transform.up);
            Vector3 v = Vector3.Cross(r, n);

            //Check the angle between the move direction of the controller and a vector down the slope. If less than 90 degrees then the player is moving down the slope return false
            float angle = Vector3.Angle(absoluteMoveDirection, v);

            if (angle <= 90.0f)
            {
                return(false);
            }

            // Calculate where to place the controller on the slope, or at the bottom, based on the desired movement distance
            Vector3 resolvedPosition = Math3d.ProjectPointOnLine(initialPosition, r, transform.position);
            Vector3 direction        = Math3d.ProjectVectorOnPlane(n, resolvedPosition - transform.position);

            transform.position += direction;

            return(true);
        }

        return(false);
    }
예제 #11
0
    void WallSlide_SuperUpdate()
    {
        if (input.Current.MoveInput == Vector3.zero || Vector3.Dot(collisionVector, LocalMovement()) > 0)
        {
            currentState = PlayerStates.Fall;
            return;
        }

        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        if (Vector3.Angle(verticalMoveDirection, controller.up) > 90 && AcquiringGround())
        {
            moveDirection = planarMoveDirection;
            currentState  = PlayerStates.Idle;
            return;
        }

        if (input.Current.JumpInput)
        {
            moveDirection = collisionVector * 8;
            currentState  = PlayerStates.Jump;
            return;
        }

        moveDirection -= controller.up * Gravity * 0.1f * Time.deltaTime;
    }
        /// <summary>
        /// Provides raycast data based on where a SphereCast would contact the specified normal
        /// Raycasting downwards from a point along the controller's bottom sphere, based on the provided
        /// normal
        /// </summary>
        /// <param name="groundNormal">Normal of a triangle assumed to be directly below the controller</param>
        /// <param name="hit">Simulated SphereCast data</param>
        /// <returns>True if the raycast is successful</returns>
        private bool SimulateSphereCast(Vector3 groundNormal, out RaycastHit hit)
        {
            float groundAngle = Vector3.Angle(groundNormal, controller.up) * Mathf.Deg2Rad;

            Vector3 secondaryOrigin = controller.transform.position + controller.up * Tolerance;

            if (!Mathf.Approximately(groundAngle, 0))
            {
                float horizontal = Mathf.Sin(groundAngle) * controller.radius;
                float vertical   = (1.0f - Mathf.Cos(groundAngle)) * controller.radius;

                // Retrieve a vector pointing up the slope
                Vector3 r2 = Vector3.Cross(groundNormal, controller.down);
                Vector3 v2 = -Vector3.Cross(r2, groundNormal);

                secondaryOrigin += Math3d.ProjectVectorOnPlane(controller.up, v2).normalized *horizontal + controller.up * vertical;
            }

            if (Physics.Raycast(secondaryOrigin, controller.down, out hit, Mathf.Infinity, walkable, triggerInteraction))
            {
                // Remove the tolerance from the distance travelled
                hit.distance -= Tolerance + TinyTolerance;

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #13
0
        private void HandleEdgeCollision(CollisionSphere collisionSphere, RaycastHit hit)
        {
            Vector3 towardCenter = Math3d.ProjectVectorOnPlane(
                playerView.Up,
                (playerView.Position - hit.point).normalized * settings.epsilon
                );

            Quaternion planeAwayRotation = Quaternion.AngleAxis(
                settings.edgeCollisionRotateDegree,
                Vector3.Cross(towardCenter, playerView.Up)
                );

            Vector3 awayCenter = planeAwayRotation * -towardCenter;

            Vector3 nearPoint = hit.point + towardCenter + (playerView.Up * settings.epsilon);
            Vector3 farPoint  = hit.point + (awayCenter * settings.edgeCollisionFarPointMultiplier);

            RaycastHit nearHit;
            RaycastHit farHit;

            Raycast(nearPoint, playerView.Down, out nearHit);
            Raycast(farPoint, playerView.Down, out farHit);

            nearGround = new GroundHit(nearHit);
            farGround  = new GroundHit(farHit);

            // If we are standing on surface that should be counted as a
            // wall, attempt to flush against it on the ground
            if (Vector3.Angle(hit.normal, playerView.Up) > collidable.StandAngle)
            {
                FlushGround(collisionSphere, hit);
            }

            // If we are standing on a ledge then face the nearest center of
            // the player view, which should be steep enough to be counted as
            // a wall. Retrieve the ground it is connected to at its base, if
            // there is one.
            if ((Vector3.Angle(nearHit.normal, playerView.Up) > collidable.StandAngle) || (nearHit.distance > settings.tolerance))
            {
                Collidable nearCollidable = GetCollidable(nearHit);

                if (Vector3.Angle(nearHit.normal, playerView.Up) > nearCollidable.StandAngle)
                {
                    Vector3 downslopeDirection = CollisionMath.DownslopeDirection(nearHit.normal, playerView.Down);

                    RaycastHit stepHit;

                    if (Raycast(nearPoint, downslopeDirection, out stepHit))
                    {
                        stepGround = new GroundHit(stepHit);
                    }
                }
                else
                {
                    stepGround = new GroundHit(nearHit);
                }
            }
        }
예제 #14
0
    void DoubleJump_EnterState()
    {
        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        jumpCount      = 2;
        moveDirection -= verticalMoveDirection;
        moveDirection += controller.up * CalculateJumpSpeed(JumpHeight, Gravity);
    }
예제 #15
0
 void Float_SuperUpdate()
 {
     if (AcquiringGround())
     {
         moveDirection = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
         currentState  = PlayerStates.Idle;
         return;
     }
 }
예제 #16
0
 private void DiveRoll_SuperUpdate()
 {
     if (rpgCharacterController.CanStartAction("Idle"))
     {
         currentVelocity = Math3d.ProjectVectorOnPlane(superCharacterController.up, currentVelocity);
         rpgCharacterController.StartAction("Idle");
         return;
     }
     currentVelocity -= superCharacterController.up * (fallGravity / 2) * superCharacterController.deltaTime;
 }
예제 #17
0
    void Fall_SuperUpdate()
    {
        if (AcquiringGround())
        {
            moveDirection = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
            currentState  = PlayerStates.Idle;
            return;
        }

        moveDirection -= controller.up * Gravity * controller.deltaTime;
    }
예제 #18
0
    void OnTriggerStay(Collider col)
    {
        if (col.gameObject.tag == "Player" && SuperMath.Timer(lastSpawnTime, ReloadTime))
        {
            Vector3 targetPosition = col.transform.position + Math3d.ProjectVectorOnPlane(Vector3.up, col.GetComponent <MarioMachine>().Velocity());

            Instantiate(WaterBomb, targetPosition + Height * Vector3.up, Quaternion.identity);

            lastSpawnTime = Time.time;
        }
    }
예제 #19
0
    public float GetRequiredSpeed(Vector3 point, float angle)
    {
        Vector3 direction = point - firePoint.position;

        float yOffset = direction.y;

        direction = Math3d.ProjectVectorOnPlane(Vector3.up, direction);
        float distance = direction.magnitude;

        return(ProjectileMath.CalculateLaunchSpeed(distance, yOffset, Physics.gravity.magnitude, angle * Mathf.Deg2Rad));
    }
 private void Fall_SuperUpdate()
 {
     if (AcquiringGround())
     {
         currentVelocity = Math3d.ProjectVectorOnPlane(superCharacterController.up, currentVelocity);
         currentState    = WarriorState.Idle;
         warriorState    = WarriorState.Idle;
         return;
     }
     //Normal gravity.
     currentVelocity -= superCharacterController.up * gravity * superCharacterController.deltaTime;
 }
예제 #21
0
    void Spawned_EnterState()
    {
        ClampToGround();

        spawnTarget = iTweenPath.GetPath(PathName)[0];

        Vector3 direction = Math3d.ProjectVectorOnPlane(Vector3.up, spawnTarget - transform.position).normalized;

        transform.rotation = Quaternion.LookRotation(direction, Vector3.up);

        moveDirection = direction * 4.0f;
    }
 private void Fall_SuperUpdate()
 {
     if (AcquiringGround())
     {
         currentVelocity   = Math3d.ProjectVectorOnPlane(superCharacterController.up, currentVelocity);
         currentState      = RPGCharacterState.Idle;
         rpgCharacterState = RPGCharacterState.Idle;
         return;
     }
     DoubleJump();
     currentVelocity -= superCharacterController.up * gravity * superCharacterController.deltaTime;
 }
예제 #23
0
    private void GrabLedge(Vector3 ledgePosition)
    {
        Vector3 ledgeDirection = Math3d.ProjectVectorOnPlane(controller.up, transform.position - ledgePosition);

        lookDirection = -ledgeDirection.normalized;

        transform.position  = ledgePosition + controller.radius * ledgeDirection.normalized;
        transform.position += controller.down * (controller.height + controller.radius + 0.05f);

        moveSpeed         = 0;
        verticalMoveSpeed = 0;
    }
예제 #24
0
    public void MegaSpring(Vector3 direction, float velocity, float lift)
    {
        lookDirection = Math3d.ProjectVectorOnPlane(controller.up, direction.normalized);

        moveSpeed         = velocity;
        verticalMoveSpeed = lift;

        moveDirection = Math3d.SetVectorLength(lookDirection, moveSpeed) + controller.up * verticalMoveSpeed;

        currentState = MarioStates.MegaSpring;
        return;
    }
예제 #25
0
    void Jump_SuperUpdate()
    {
        Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(controller.up, moveDirection);
        Vector3 verticalMoveDirection = moveDirection - planarMoveDirection;

        planarMoveDirection = Vector3.MoveTowards(planarMoveDirection, LocalMovement() * WalkSpeed, JumpAcceleration * JumpControl * controller.deltaTime);

        if (Vector3.Angle(verticalMoveDirection, controller.up) > 90 && AcquiringGround())
        {
            moveDirection = planarMoveDirection;
            currentState  = PlayerStates.Idle;
            return;
        }

        foreach (var c in controller.collisionData)
        {
            if (c.normal == -controller.up)
            {
                verticalMoveDirection.y = 0;
                break;
            }
        }

        if (moveDirection.y <= 0)
        {
            currentState = PlayerStates.Fall;
            return;
        }

        if (input.Current.JumpInput)
        {
            currentState = PlayerStates.DoubleJump;
            return;
        }

        collisionVector = controller.IsOnTheWall(LocalMovement());
        if (collisionVector != Vector3.zero)
        {
            currentState = PlayerStates.WallSlide;
            return;
        }

        if (IsOnEdge())
        {
            currentState = PlayerStates.Climb;
            return;
        }

        verticalMoveDirection -= controller.up * Gravity * controller.deltaTime;
        moveDirection          = planarMoveDirection + verticalMoveDirection;
    }
예제 #26
0
    public void SetTargetWithBothAngleAndSpeed(Vector3 point, float angle, float speed)
    {
        currentRadian = angle * Mathf.Deg2Rad;
        currentSpeed  = speed;

        Vector3 direction = point - firePoint.position;
        float   yOffset   = direction.y;

        direction = Math3d.ProjectVectorOnPlane(Vector3.up, direction);
        float distance = ProjectileMath.CalculateLandDistance(firePoint.position.y, Physics.gravity.magnitude, angle, speed);

        projectileArc.UpdateArc(speed, distance, Physics.gravity.magnitude, currentRadian, direction, true);
        SetThrowPoint(direction, currentRadian * Mathf.Rad2Deg);
    }
예제 #27
0
        public override void Update()
        {
            base.Update();

            Vector3 planarMoveDirection   = Math3d.ProjectVectorOnPlane(playerView.Up, stateMachine.MoveDirection);
            Vector3 verticalMoveDirection = stateMachine.MoveDirection - planarMoveDirection;

            if (Vector3.Angle(verticalMoveDirection, playerView.Up) > 90f)
            {
                if (!playerView.Animator.GetBool("IsLanding") &&
                    playerController.FallAcquiringGround())
                {
                    playerView.Animator.SetBool("IsLanding", true);
                }

                if (playerController.AcquiringGround())
                {
                    stateMachine.MoveDirection = planarMoveDirection;

                    if (!stateMachine.Enabled || input.Mapping.Direction.Vector == Vector2.zero)
                    {
                        JumpHalt();
                        stateMachine.ChangeState(PlayerStateType.Halt);
                    }
                    else
                    {
                        stateMachine.ChangeState(PlayerStateType.Walk);
                    }
                    return;
                }
            }

            if (stateMachine.Enabled)
            {
                planarMoveDirection = Vector3.MoveTowards(
                    planarMoveDirection,
                    planarMoveDirection + (stateMachine.LookDirection * player.CurrentJumpSpeed * input.Mapping.Direction.Vector.magnitude),
                    player.CurrentJumpAcceleration * playerController.DeltaTime
                    );

                planarMoveDirection = Vector3.ClampMagnitude(
                    planarMoveDirection,
                    player.CurrentJumpSpeedLimit
                    );
            }

            verticalMoveDirection -= playerView.Up * player.CurrentGravity * playerController.DeltaTime;

            stateMachine.MoveDirection = planarMoveDirection + verticalMoveDirection;
        }
예제 #28
0
        private void SlopeLimit(Vector3 initialPosition)
        {
            Vector3 groundNormal = grounding.PrimaryNormal;
            float   groundAngle  = Vector3.Angle(groundNormal, playerView.Up);

            if (groundAngle > grounding.Collidable.SlopeLimit)
            {
                Vector3 absoluteMoveDirection = Math3d.ProjectVectorOnPlane(
                    groundNormal,
                    playerView.Position - initialPosition
                    );

                Vector3 downslopeDirection = CollisionMath.DownslopeDirection(groundNormal, playerView.Down);
                float   slopeAngle         = Vector3.Angle(absoluteMoveDirection, downslopeDirection);

                if (slopeAngle <= settings.slopeLimitUpperBoundAngle)
                {
                    return;
                }

                Vector3 resolvedPosition = Math3d.ProjectPointOnLine(
                    initialPosition,
                    Vector3.Cross(groundNormal, playerView.Down),
                    playerView.Position
                    );
                Vector3 direction = Math3d.ProjectVectorOnPlane(
                    groundNormal,
                    resolvedPosition - playerView.Position
                    );

                RaycastHit hit;

                if (Physics.CapsuleCast(
                        feetSphere.Position,
                        headSphere.Position,
                        maxCollisionSphereRadius,
                        direction.normalized,
                        out hit,
                        direction.magnitude,
                        settings.walkableLayerMask
                        ))
                {
                    playerView.Position += downslopeDirection * hit.distance;
                }
                else
                {
                    playerView.Position += direction;
                }
            }
        }
예제 #29
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private bool SlopeLimit()
        {
            Vector3 groundNormal = currentGround.GetNormal();
            float   angle        = Vector3.Angle(groundNormal, up);

            float standAngle = GroundCollisionAttribute.DEFAULT_STAND_ANGLE;
            float slopeLimit = GroundCollisionAttribute.DEFAULT_SLOPE_LIMIT;

            if (currentGround.collisionAttribute != null)
            {
                standAngle = currentGround.collisionAttribute.StandAngle;
                slopeLimit = currentGround.collisionAttribute.SlopeLimit;
            }

            if (angle >= slopeLimit)
            {
                Vector3 absoluteMoveDirection = Math3d.ProjectVectorOnPlane(groundNormal, transform.position - _posBeforeCorrection);

                // Retrieve a vector pointing down the slope
                Vector3 r = Vector3.Cross(groundNormal, down);
                Vector3 v = Vector3.Cross(r, groundNormal);

                float absoluteAngle = Vector3.Angle(absoluteMoveDirection, v);

                if (absoluteAngle <= 90.0f)
                {
                    return(false);
                }

                // Calculate where to place the controller on the slope, or at the bottom, based on the desired movement distance
                Vector3 resolvedPosition = Math3d.ProjectPointOnLine(_posBeforeCorrection, r, transform.position);
                Vector3 direction        = Math3d.ProjectVectorOnPlane(groundNormal, resolvedPosition - transform.position);

                RaycastHit hit;

                // Check if our path to our resolved position is blocked by any colliders
                if (Physics.CapsuleCast(SpherePosition(feet), SpherePosition(head), radius, direction.normalized, out hit, direction.magnitude, Walkable, triggerInteraction))
                {
                    transform.position += v.normalized * hit.distance;
                }
                else
                {
                    transform.position += direction;
                }

                return(true);
            }
            return(false);
        }
    public void SetTargetWithAngle(Vector3 point, float angle)
    {
        currentAngle = angle;

        Vector3 direction = point - firePoint.position;
        float   yOffset   = -direction.y;

        direction = Math3d.ProjectVectorOnPlane(Vector3.up, direction);
        float distance = direction.magnitude;

        currentSpeed = ProjectileMath.LaunchSpeed(distance, yOffset, Physics.gravity.magnitude, angle * Mathf.Deg2Rad);

        projectileArc.UpdateArc(currentSpeed, distance, Physics.gravity.magnitude, currentAngle * Mathf.Deg2Rad, direction, true);
        SetTurret(direction, currentAngle);
    }