示例#1
0
        public override void BeforeCharacterUpdate(float deltaTime)
        {
            Vector3 cast_direction;
            Vector3 cast_postion = machine.Motor.TransientPosition;

            if (machine.climbing_surface == null)
            {
                if (hanging)
                {
                    cast_direction = machine.Motor.CharacterUp;
                }
                else
                {
                    cast_direction = machine.Motor.CharacterForward;
                }
            }
            else
            {
                cast_direction = -machine.surface_normal;
            }

            //This is likely totally unnecessary (as a method for retrieving the normal vector)
            int hits = machine.Motor.CharacterSweep(cast_postion, machine.Motor.TransientRotation,
                                                    cast_direction, 0.05f, out RaycastHit closestHit, machine._raycastHits,
                                                    machine.ClimbingLayer, QueryTriggerInteraction.Collide);

            if (hits < 1)
            {
                //Need a mechanism to clamp to our surface
                lost_surface = true;
                Debug.Log("No surface");
            }
            else
            {
                lost_surface             = false;
                machine.climbing_surface = closestHit.collider;
                machine.surface_normal   = closestHit.normal;
                machine.surface_point    = closestHit.point;
                capsule_point            = machine.GetComponent <CapsuleCollider>().ClosestPointOnBounds(machine.surface_point);
            }

            /*if (hits > 0)
             * {
             *  for (int i = 0; i < hits; i++)
             *  {
             *      Debug.DrawRay(machine._raycastHits[i].point, machine._raycastHits[i].normal, Color.red, 30f);
             *
             *  }
             *  Debug.DrawRay(machine.Motor.TransientPosition + machine.Motor.CharacterTransformToCapsuleCenter,
             *      machine.surface_normal, Color.white, 30f);
             * }
             * else
             *  Debug.Log(machine.climbing_surface);*/

            float nivellationAngle = Vector3.Angle(Vector3.up, machine.surface_normal);

            Debug.Log(nivellationAngle);
            if (nivellationAngle > 0)
            {
                if (nivellationAngle < machine.Motor.MaxStableDenivelationAngle)
                {
                    standing_transition = true;
                }
                else if (nivellationAngle > 180 - machine.Motor.MaxStableDenivelationAngle)
                {
                    Debug.Log("Climbing to hang");
                    hanging = true;
                    machine.GetComponentInChildren <Animator>().SetBool("hanging", true);
                }
                else if (hanging)
                {
                    Debug.Log("Hanging to climb");
                    hanging            = false;
                    hanging_transition = true;

                    machine.GetComponentInChildren <Animator>().SetBool("hanging", false);
                    Debug.DrawRay(machine.climbing_surface.ClosestPoint(machine.Motor.TransientPosition), machine.surface_normal, Color.gray, 10f);
                    //Debug.Break();
                }
                else if (hanging_transition)
                {
                    if (nivellationAngle < 90 + machine.Motor.MaxStableDenivelationAngle)
                    {
                        hanging_transition = false;
                    }
                }

                Debug.DrawRay(machine.climbing_surface.transform.position, machine.surface_normal, Color.gray, 15f);
            }
            else    //Typically this means we've exited the surface, which we need to prevent
            {
            }
        }
示例#2
0
        public override void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
        {
            if (machine._jumpRequested)
            {
                if (!machine._jumpConsumed)
                {
                    // Add to the return velocity and reset jump state
                    currentVelocity         += (jump_direction * machine.JumpUpSpeed * machine.PressureSensitiveJumpPower) - Vector3.Project(currentVelocity, machine.Motor.CharacterUp);
                    currentVelocity         += (machine._moveInputVector * machine.JumpScalableForwardSpeed);
                    machine._jumpRequested   = false;
                    machine._jumpConsumed    = true;
                    machine._jumpedThisFrame = true;
                }
                else if (!machine._doubleJumpConsumed)
                {
                    machine.GetComponentInChildren <Animator>().SetTrigger("double_jump");
                    Vector3 jumpDirection = machine.Motor.CharacterUp;
                    currentVelocity += (jump_direction * machine.JumpUpSpeed * machine.PressureSensitiveJumpPower) - Vector3.Project(currentVelocity, machine.Motor.CharacterUp);
                    currentVelocity += (machine._moveInputVector * machine.JumpScalableForwardSpeed);

                    machine._jumpRequested      = false;
                    machine._doubleJumpConsumed = true;
                    machine._jumpedThisFrame    = true;

                    peak_vertical_velocity     = currentVelocity.y;
                    double_jump_rotation_angle = 360f;// / (peak_vertical_velocity / (machine.Drag * machine.Gravity.y));
                    start_euler_y = machine.Motor.TransientRotation.eulerAngles.y;

                    //Invoke the double jump event with the total time before the character peaks
                    machine.DoubleJump.Invoke(peak_vertical_velocity);
                }
                else
                {
                    // Handle jumping
                    machine._jumpedThisFrame         = false;
                    machine._timeSinceJumpRequested += deltaTime;
                }
            }

            // Add move input
            if (machine._moveInputVector.sqrMagnitude > 0f)
            {
                Vector3 addedVelocity = machine._moveInputVector * machine.AirAccelerationSpeed * deltaTime;

                // Prevent air movement from making you move up steep sloped walls
                if (machine.Motor.GroundingStatus.FoundAnyGround)
                {
                    Vector3 perpenticularObstructionNormal = Vector3.Cross(Vector3.Cross(machine.Motor.CharacterUp, machine.Motor.GroundingStatus.GroundNormal), machine.Motor.CharacterUp).normalized;
                    addedVelocity = Vector3.ProjectOnPlane(addedVelocity, perpenticularObstructionNormal);
                }

                // Limit air movement from inputs to a certain maximum, without limiting the total air move speed from momentum, gravity or other forces
                Vector3 resultingVelOnInputsPlane = Vector3.ProjectOnPlane(currentVelocity + addedVelocity, machine.Motor.CharacterUp);
                if (resultingVelOnInputsPlane.magnitude > machine.MaxAirMoveSpeed && Vector3.Dot(machine._moveInputVector, resultingVelOnInputsPlane) >= 0f)
                {
                    addedVelocity = Vector3.zero;
                }
                else
                {
                    Vector3 velOnInputsPlane = Vector3.ProjectOnPlane(currentVelocity, machine.Motor.CharacterUp);
                    Vector3 clampedResultingVelOnInputsPlane = Vector3.ClampMagnitude(resultingVelOnInputsPlane, machine.MaxAirMoveSpeed);
                    addedVelocity = clampedResultingVelOnInputsPlane - velOnInputsPlane;
                }

                currentVelocity += addedVelocity;
            }

            // Gravity
            currentVelocity += machine.Gravity * deltaTime;

            // Drag
            currentVelocity *= (1f / (1f + (machine.Drag * deltaTime)));
            machine.GetComponentInChildren <Animator>().SetBool("falling", currentVelocity.y <= 0);
            machine.GetComponent <Animator>().SetFloat("vertical", currentVelocity.y / peak_vertical_velocity);
        }