Ejemplo n.º 1
0
        private void UpdateGeneral()
        {
            if (Input.GetKeyDown(KeyCode.LeftShift))
            {
                m_locomotionSpeedRamp.BeginSprint();
                m_trajectoryGenerator.MaxSpeed      = 6.7f;
                m_trajectoryGenerator.PositionBias  = 6f;
                m_trajectoryGenerator.DirectionBias = 6f;
                m_mxmAnimator.SetCalibrationData("Sprint");
                m_trajectoryGenerator.InputProfile = m_sprintLocomotion;
            }
            else if (Input.GetKeyUp(KeyCode.LeftShift))
            {
                m_locomotionSpeedRamp.ResetFromSprint();
                m_trajectoryGenerator.MaxSpeed      = 4.3f;
                m_trajectoryGenerator.PositionBias  = 10f;
                m_trajectoryGenerator.DirectionBias = 10f;
                m_mxmAnimator.SetCalibrationData("General");
                m_trajectoryGenerator.InputProfile = m_generalLocomotion;
            }

            if (Input.GetMouseButtonDown(1))
            {
                m_mxmAnimator.AddRequiredTag("Strafe");
                m_mxmAnimator.SetCalibrationData("Strafe");
                m_mxmAnimator.AngularErrorWarpRate      = 360f;
                m_mxmAnimator.AngularErrorWarpThreshold = 270f;
                m_mxmAnimator.AngularErrorWarpMethod    = EAngularErrorWarpMethod.TrajectoryFacing;
                m_trajectoryGenerator.TrajectoryMode    = ETrajectoryMoveMode.Strafe;
                m_mxmAnimator.PastTrajectoryMode        = EPastTrajectoryMode.CopyFromCurrentPose;
            }
            else if (Input.GetMouseButtonUp(1))
            {
                m_mxmAnimator.RemoveRequiredTag("Strafe");
                m_mxmAnimator.SetCalibrationData(0);
                m_mxmAnimator.AngularErrorWarpRate      = 60.0f;
                m_mxmAnimator.AngularErrorWarpThreshold = 90f;
                m_mxmAnimator.AngularErrorWarpMethod    = EAngularErrorWarpMethod.CurrentHeading;
                m_trajectoryGenerator.TrajectoryMode    = ETrajectoryMoveMode.Normal;
                m_mxmAnimator.PastTrajectoryMode        = EPastTrajectoryMode.ActualHistory;
            }

            if (Input.GetKeyDown(KeyCode.LeftControl))
            {
                m_mxmAnimator.BeginEvent(m_slideDefinition);
                BeginSliding();
            }
            else if (Input.GetKeyDown(KeyCode.Space))
            {
                if (m_jumpDefinition != null)
                {
                    m_jumpDefinition.ClearContacts();
                    m_jumpDefinition.AddDummyContacts(1);
                    m_mxmAnimator.BeginEvent(m_jumpDefinition);

                    ref readonly EventContact eventContact = ref m_mxmAnimator.NextEventContact_Actual_World;
Ejemplo n.º 2
0
    public void Jump()
    {
        m_jumpDefinition.ClearContacts();
        m_jumpDefinition.AddDummyContacts(1);
        m_mxmAnimator.BeginEvent(m_jumpDefinition);

        ref readonly EventContact eventContact = ref m_mxmAnimator.NextEventContact_Actual_World;
Ejemplo n.º 3
0
    protected void toggleSit()
    {
        if (!sit)   //SIT
        {
            sitDefinition.ClearContacts();
            sitDefinition.AddEventContact(sitPoint.position, this.transform.rotation.y);
            m_animator.BeginEvent(sitDefinition);

            //m_animator.ClearRequiredTags();
            //m_animator.SetRequiredTag("Sitting");

            sit = true;
        }
        else        //STAND-UP
        {
            m_animator.BeginEvent(standUpDefinition);

            m_animator.ClearRequiredTags();
            //m_animator.RemoveRequiredTag("Sitting");

            sit     = false;
            oneTime = false;
        }
    }
Ejemplo n.º 4
0
        public void Update()
        {
            //Check if we are already vaulting
            if (m_isVaulting)
            {
                HandleCurrentVault();
                return;
            }

            if (!CanVault())
            {
                return;
            }

            //We are going to use the transformposition and forward direction a lot. Caching it here for perf
            Vector3 charPos       = transform.position;
            Vector3 charForward   = transform.forward;
            float   approachAngle = 0f;

            //First we must fire a ray forward from the character, slightly above the minimum vault rise (aka the character controller minimum step
            Vector3 probeStart = new Vector3(charPos.x, charPos.y +
                                             m_curConfig.DetectProbeRadius + m_minVaultRise,
                                             charPos.z);

            Ray        forwardRay = new Ray(probeStart, charForward);
            RaycastHit forwardRayHit;

            if (Physics.SphereCast(forwardRay, m_curConfig.DetectProbeRadius, out forwardRayHit,
                                   Advance, m_layerMask, QueryTriggerInteraction.Ignore))
            {
                //If we hit something closer than the current advance, then we shorten the advance since we want the
                //First downward sphere case to hit the edge.
                if (forwardRayHit.distance < Advance)
                {
                    Advance = forwardRayHit.distance;
                }

                Vector3 obstacleOrient = Vector3.ProjectOnPlane(forwardRayHit.normal, Vector3.up) * -1f;

                approachAngle = Vector3.SignedAngle(transform.forward, obstacleOrient, Vector3.up);

                //If we encounter an obstacle but at an angle above our max, we don't want to vault so return here.
                //QUESTION: What if the actual vault point (i.e. at the top of the obstacle is within the correct angle?
                if (Mathf.Abs(approachAngle) > m_maxApproachAngle)
                {
                    return;
                }
            }

            //Next we fire a ray vertically downward from the maximum vault rise to the maximum vault drop
            //NOTE: This does not take into consideration a roof or an overhang
            probeStart    = transform.TransformPoint(new Vector3(0f, 0f, Advance));
            probeStart.y += m_maxVaultRise;

            Ray        probeRay = new Ray(probeStart, Vector3.down);
            RaycastHit probeHit;

            if (Physics.SphereCast(probeRay, m_curConfig.DetectProbeRadius, out probeHit, m_maxVaultRise + m_maxVaultDrop,
                                   m_layerMask, QueryTriggerInteraction.Ignore))
            {
                //Too high -> cancel the vault
                if (probeHit.distance < Mathf.Epsilon)
                {
                    return;
                }

                //A 'vault over' or 'vault up' may have been detected if the probe distance is between the minimum and maximum vault rise
                if (probeHit.distance < (m_maxVaultRise - m_minVaultRise))
                {
                    //A vault may have been detected

                    //Check if there is enough height to fit the character
                    if (!CheckCharacterHeightFit(probeHit.point, charForward))
                    {
                        return;
                    }

                    //Calculate the hit offset. This is the offset on a horizontal 2D plane between the start of the ray and the hit point

                    //Here we conduct a shape analysis of the vaultable object and store that data in a Vaultable Profile
                    VaultableProfile vaultable;
                    VaultShapeAnalysis(in probeHit, out vaultable);

                    if (vaultable.VaultType == EVaultType.Invalid)
                    {
                        return;
                    }

                    //Check for enough space on top of the object (for a step up)
                    if (vaultable.VaultType == EVaultType.StepUp && vaultable.Depth < m_minStepUpDepth)
                    {
                        return;
                    }

                    //Check object surface gradient (Assume ok for now)

                    //Select appropriate vault defenition
                    VaultDefinition vaultDef = ComputeBestVault(ref vaultable);

                    if (vaultDef == null)
                    {
                        return;
                    }

                    float facingAngle = transform.rotation.eulerAngles.y;

                    if (vaultDef.LineUpWithObstacle)
                    {
                        facingAngle += approachAngle;
                    }

                    //Pick contacts
                    vaultDef.EventDefinition.ClearContacts();

                    switch (vaultDef.OffsetMethod_Contact1)
                    {
                    case EVaultContactOffsetMethod.Offset: { vaultable.Contact1 += transform.TransformVector(vaultDef.Offset_Contact1); } break;

                    case EVaultContactOffsetMethod.DepthProportion: { vaultable.Contact1 += transform.TransformVector(vaultable.Depth * vaultDef.Offset_Contact1); } break;
                    }

                    vaultDef.EventDefinition.AddEventContact(vaultable.Contact1, facingAngle);

                    if (vaultable.VaultType == EVaultType.StepOver)
                    {
                        switch (vaultDef.OffsetMethod_Contact2)
                        {
                        case EVaultContactOffsetMethod.Offset: { vaultable.Contact2 += transform.TransformVector(vaultDef.Offset_Contact2); } break;

                        case EVaultContactOffsetMethod.DepthProportion: { vaultable.Contact2 += transform.TransformVector(vaultable.Depth * vaultDef.Offset_Contact2); } break;
                        }

                        vaultDef.EventDefinition.AddEventContact(vaultable.Contact2, facingAngle);
                    }

                    //Trigger event
                    m_mxmAnimator.BeginEvent(vaultDef.EventDefinition);

                    m_mxmAnimator.PostEventTrajectoryMode = EPostEventTrajectoryMode.Pause;

                    if (m_rootMotionApplicator != null)
                    {
                        m_rootMotionApplicator.EnableGravity = false;
                    }

                    if (vaultDef.DisableCollision && m_controllerWrapper != null)
                    {
                        m_controllerWrapper.CollisionEnabled = false;
                    }

                    m_isVaulting = true;
                }
                else //Detect a step off or vault over gap
                {
                    Vector3 flatHitPoint   = new Vector3(probeHit.point.x, 0f, probeHit.point.z);
                    Vector3 flatProbePoint = new Vector3(probeStart.x, 0f, probeStart.z);

                    Vector3 dir = flatProbePoint - flatHitPoint; // The direction of the ledge

                    if (dir.sqrMagnitude > (m_curConfig.DetectProbeRadius * m_curConfig.DetectProbeRadius) / 4f)
                    {
                        //A step off may have occured

                        //Shape analysis
                        Vector2 start2D = new Vector2(probeStart.x, probeStart.z);
                        Vector2 hit2D   = new Vector2(probeHit.point.x, probeHit.point.z);

                        float hitOffset = Vector2.Distance(start2D, hit2D);

                        VaultableProfile vaultable;
                        VaultOffShapeAnalysis(in probeHit, out vaultable, hitOffset);

                        if (vaultable.VaultType == EVaultType.Invalid)
                        {
                            return;
                        }

                        VaultDefinition vaultDef = ComputeBestVault(ref vaultable);

                        if (vaultDef == null)
                        {
                            return;
                        }

                        float facingAngle = transform.rotation.eulerAngles.y;

                        //Pick contacts
                        vaultDef.EventDefinition.ClearContacts();

                        switch (vaultDef.OffsetMethod_Contact1)
                        {
                        case EVaultContactOffsetMethod.Offset: { vaultable.Contact1 += transform.TransformVector(vaultDef.Offset_Contact1); } break;

                        case EVaultContactOffsetMethod.DepthProportion: { vaultable.Contact1 += transform.TransformVector(vaultable.Depth * vaultDef.Offset_Contact1); } break;
                        }

                        vaultDef.EventDefinition.AddEventContact(vaultable.Contact1, facingAngle);

                        m_mxmAnimator.BeginEvent(vaultDef.EventDefinition);
                        m_mxmAnimator.PostEventTrajectoryMode = EPostEventTrajectoryMode.Pause;

                        //if (m_rootMotionApplicator != null)
                        //    m_rootMotionApplicator.EnableGravity = false;

                        //if (m_controllerWrapper != null)
                        //    m_controllerWrapper.CollisionEnabled = false;

                        m_isVaulting = true;
                    }
                }
            }
        }