Пример #1
0
    public void Rotate(Vector3 a_NewUpDirection, RotateMethod a_Method)
    {
        Vector3 pivot = Vector3.zero;

        switch (a_Method)
        {
        case RotateMethod.FromCenter:
            m_UpDirection = a_NewUpDirection;
            return;

        case RotateMethod.FromBottom:
            pivot = GetDownCenter();
            break;

        case RotateMethod.FromTop:
            pivot = GetUpCenter();
            break;
        }
        Vector3 vectorToCenter = m_Position - pivot;

        Quaternion rotation = Quaternion.FromToRotation(GetUpDirection(), a_NewUpDirection);

        Vector3 targetPosition = pivot + rotation * vectorToCenter;

        m_Position    = targetPosition;
        m_UpDirection = a_NewUpDirection;
        if (!m_IsCopy && m_CapsuleCollider != null)
        {
            m_CapsuleCollider.transform.position = m_Position;
            m_CapsuleCollider.transform.rotation = GetRotation();
        }
    }
Пример #2
0
    //Query whether this module can be active, given the current state of the character controller (velocity, isGrounded etc.)
    //Called every frame when inactive (to see if it could be) and when active (to see if it should not be)
    public override bool IsApplicable()
    {
        if (m_ControlledCollider.IsGrounded())
        {
            return(false);
        }
        //Wall needs to be hit for the module to be active
        if (m_ControlledCollider.GetSideCastInfo().m_HasHitSide)
        {
            if (!m_ControlledCollider.IsPartiallyTouchingWall())
            {
                return(false);
            }
            m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
            m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
            m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);

            if (!m_ControlledCollider.CanAlignWithNormal(m_UpDirection))
            {
                return(false);
            }
            return(true);
        }
        return(false);
    }
Пример #3
0
    //Called for every fixedupdate that this module is active
    public override void FixedUpdateModule()
    {
        if (!m_ControlledCollider.GetSideCastInfo().m_HasHitSide || (!m_ControlledCollider.IsPartiallyTouchingWall()))
        {
            return;
        }
        m_WallNormal = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
        float distance = m_ControlledCollider.GetSideCastInfo().GetDistance();

        m_ControlledCollider.GetCapsuleTransform().Move(-m_WallNormal * distance);
        m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
        m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
        m_ControlledCollider.RotateToAlignWithNormal(m_UpDirection, m_RotateMethod);

        Vector2 currentVel = m_ControlledCollider.GetVelocity();

        Vector2 fGravity = -m_UpDirection *m_WallRunGravity *Vector2.Dot(-m_UpDirection, Vector2.down);  //Gravity along wall, but with correct velocity

        Vector2 fDrag = -0.5f * (currentVel.sqrMagnitude) * m_CharacterController.GetDragConstant() * currentVel.normalized;

        if (!m_ApplyDrag)
        {
            fDrag = Vector2.zero;
        }
        Vector2 summedF = fGravity + fDrag;

        Vector2 newVel = currentVel + (summedF * Time.fixedDeltaTime);

        m_ControlledCollider.UpdateWithVelocity(newVel);
    }
Пример #4
0
 //Reset all state when this module gets initialized
 protected override void ResetState()
 {
     base.ResetState();
     m_WallNormal   = Vector3.zero;
     m_UpDirection  = Vector3.zero;
     m_RotateMethod = RotateMethod.FromBottom;
 }
Пример #5
0
 //Reset all state when this module gets initialized
 protected override void ResetState()
 {
     base.ResetState();
     m_WallNormal            = Vector3.zero;
     m_UpDirection           = Vector3.zero;
     m_RotateMethod          = RotateMethod.FromBottom;
     m_IsAlreadyTouchingWall = false;
 }
Пример #6
0
 public override void RotateToAlignWithNormal(Vector3 a_Normal, RotateMethod a_Method = RotateMethod.FromBottom)
 {
     if (m_CapsuleTransform.CanRotate(a_Normal, a_Method))
     {
         m_CapsuleTransform.Rotate(a_Normal, a_Method);
         UpdateContextInfo();
     }
 }
Пример #7
0
 public ClingyRotationTweener(GameObject gameObject, TweenOptions tweenOptions,
                              RotateMethod rotateMethod, GetDestinationRotationDelegate GetDestinationRotation,
                              TweenCompleteDelegate TweenComplete = null, TweenCancelledDelegate TweenCancelled = null)
     : base(gameObject, tweenOptions, TweenComplete, TweenCancelled)
 {
     this.rotateMethod           = rotateMethod;
     this.GetDestinationRotation = GetDestinationRotation;
 }
Пример #8
0
 public void CopyFromPathNode(CapsuleMovementPathNode a_PathNode)
 {
     m_Position     = a_PathNode.m_Position;
     m_UpDirection  = a_PathNode.m_UpDirection;
     m_Length       = a_PathNode.m_Length;
     m_Duration     = a_PathNode.m_Duration;
     m_RotateMethod = a_PathNode.m_RotateMethod;
     m_ResizeMethod = a_PathNode.m_ResizeMethod;
 }
Пример #9
0
        public static Tweener TweenRotation(GameObject gameObject, TweenOptions tweenOptions,
                                            RotateMethod rotateMethod, GetDestinationRotationDelegate GetDestinationRotation,
                                            TweenCompleteDelegate TweenComplete = null, TweenCancelledDelegate TweenCancelled = null)
        {
            Tweener tweener = new ClingyRotationTweener(gameObject, tweenOptions, rotateMethod,
                                                        GetDestinationRotation, TweenComplete, TweenCancelled);

            tweener.Start();
            return(tweener);
        }
Пример #10
0
    //Called for every fixedupdate that this module is active
    public override void FixedUpdateModule()
    {
        m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
        m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
        m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
        m_ControlledCollider.RotateToAlignWithNormal(m_UpDirection, m_RotateMethod);

        float distance = m_ControlledCollider.GetSideCastInfo().GetDistance();

        m_ControlledCollider.GetCapsuleTransform().Move(-m_WallNormal * distance);

        m_ControlledCollider.UpdateWithVelocity(Vector2.zero);
    }
Пример #11
0
    void Update()
    {
        if (Input.GetMouseButtonUp(0))
        {
            if (rotateMethod == RotateMethod.Gyro)
            {
                rotateMethod = RotateMethod.Compass;
            }
            else
            {
                rotateMethod = RotateMethod.Gyro;
            }

            SetRotateMethod();
        }
    }
Пример #12
0
    //Called for every fixedupdate that this module is active
    public override void FixedUpdateModule()
    {
        m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
        m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
        m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
        m_ControlledCollider.RotateToAlignWithNormal(m_UpDirection, m_RotateMethod);

        //if touching a wall during a jump, cut it short when jump is released
        if (m_HonorJumpCut)
        {
            m_CharacterController.UpdateJumpCut();
        }

        Vector2 currentVel = m_ControlledCollider.GetVelocity();

        Vector2 fInput = m_CharacterController.GetDirectedInputMovement() * m_EscapeVelocity;

        if (m_WallNormal.y >= 0.1f)
        {
            fInput = Vector2.zero;
        }
        float inputDotToNormal = Vector2.Dot(fInput, m_WallNormal);

        if (inputDotToNormal <= 0)//Moving into wall, or not moving at all
        {
            fInput = Vector2.zero;
            float distance = m_ControlledCollider.GetSideCastInfo().GetDistance();
            m_ControlledCollider.GetCapsuleTransform().Move(-m_WallNormal * distance);
        }

        Vector2 fGravity = -m_UpDirection * m_SlideGravity;//

        if (!m_UseSameGravityForAllSlopes)
        {
            fGravity *= Vector2.Dot(-m_UpDirection, Vector2.down);//Gravity along wall, but with corrected gravity
        }
        Vector2 fDrag = -0.5f * (currentVel.sqrMagnitude) * m_CharacterController.GetDragConstant() * currentVel.normalized;

        Vector2 summedF = fInput + fGravity + fDrag;

        Vector2 newVel = currentVel + (summedF * Time.fixedDeltaTime);

        newVel += GetFrictionAlongWall(newVel);

        m_ControlledCollider.UpdateWithVelocity(newVel);
    }
Пример #13
0
    public bool CanRotate(Vector3 a_NewUpDirection, RotateMethod a_Method)
    {
        Vector3 pivot = Vector3.zero;

        switch (a_Method)
        {
        case RotateMethod.FromCenter:
            pivot = m_Position;
            break;

        case RotateMethod.FromBottom:
            pivot = GetDownCenter();
            break;

        case RotateMethod.FromTop:
            pivot = GetUpCenter();
            break;
        }
        Vector3 vectorToCenter = m_Position - pivot;
        Vector3 currentNormal  = GetUpDirection();

        Quaternion rotation = Quaternion.FromToRotation(currentNormal, a_NewUpDirection);

        Vector3 start = Vector3.zero;
        Vector3 end   = Vector3.zero;

        switch (a_Method)
        {
        case RotateMethod.FromCenter:
            start = m_Position - (rotation * vectorToCenter).normalized * m_Length;
            end   = m_Position + (rotation * vectorToCenter).normalized * m_Length;
            break;

        case RotateMethod.FromBottom:
            start = GetDownCenter();
            end   = GetDownCenter() + (rotation * vectorToCenter).normalized * m_Length;
            break;

        case RotateMethod.FromTop:
            start = GetUpCenter() + (rotation * vectorToCenter).normalized * m_Length;
            end   = GetUpCenter();
            break;
        }
        return(!Physics.CheckCapsule(start, end, m_CapsuleCollider.GetRadius() - m_CapsuleCollider.GetRotateCastMargin(), m_CapsuleCollider.GetLayerMask()));
    }
Пример #14
0
    //Called for every fixedupdate that this module is active
    public override void FixedUpdateModule()
    {
        m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
        m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
        m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
        m_ControlledCollider.RotateToAlignWithNormal(m_UpDirection, m_RotateMethod);

        float distance = m_ControlledCollider.GetSideCastInfo().GetDistance();

        m_ControlledCollider.GetCapsuleTransform().Move(-m_WallNormal * distance);

        Vector2 newVel = Vector2.zero;

        if (GetDirInput("Move").m_Direction == DirectionInput.Direction.Down || GetDirInput("Move").m_Direction == DirectionInput.Direction.Up)
        {
            newVel = m_UpDirection * GetDirInput("Move").m_ClampedInput.y *m_Speed;
        }
        m_ControlledCollider.UpdateWithVelocity(newVel);
    }
Пример #15
0
 //Query whether this module can be active, given the current state of the character controller (velocity, isGrounded etc.)
 //Called every frame when inactive (to see if it could be) and when active (to see if it should not be)
 public override bool IsApplicable()
 {
     if (m_ControlledCollider.IsGrounded())
     {
         return(false);
     }
     //Wall needs to be hit for the module to be active
     if (m_ControlledCollider.GetSideCastInfo().m_HasHitSide)
     {
         if (m_IsActive)
         {
             if (!m_ControlledCollider.IsPartiallyTouchingWall())
             {
                 return(false);
             }
         }
         else
         {
             if (!m_ControlledCollider.IsCompletelyTouchingWall())
             {
                 return(false);
             }
         }
         m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
         m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
         m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
         if (!m_ControlledCollider.CanAlignWithNormal(m_UpDirection))
         {
             return(false);
         }
         RaycastHit hit;
         //If moving down, and possibly entering a position where it cannot rotate back (and therefore escape), stop before this happens
         if (Vector3.Dot(m_ControlledCollider.GetVelocity(), m_UpDirection) < 0 && Physics.Raycast(m_ControlledCollider.GetDownCenter(), -m_UpDirection, out hit, m_ControlledCollider.GetRadius() + m_EscapeCornerRaycastDistance, m_ControlledCollider.GetLayerMask()))
         {
             return(false);
         }
         return(true);
     }
     return(false);
 }
Пример #16
0
 public static void MoveRotation(Quaternion rotation, Transform transform, RotateMethod rotateMethod,
                                 Rigidbody rb = null, Rigidbody2D rb2D = null)
 {
     if (rotateMethod == RotateMethod.Translate)
     {
         transform.rotation = rotation;
     }
     else if (rotateMethod == RotateMethod.SetPhysics)
     {
         if (rb)
         {
             rb.rotation = rotation;
         }
         else if (rb2D && rb2D.simulated)
         {
             rb2D.rotation = rotation.eulerAngles.z;
         }
         else
         {
             transform.rotation = rotation;
         }
     }
     else if (rotateMethod == RotateMethod.MovePhysics)
     {
         if (rb)
         {
             rb.MoveRotation(rotation);
         }
         else if (rb2D && rb2D.simulated)
         {
             rb2D.MoveRotation(rotation.eulerAngles.z);
         }
         else
         {
             transform.rotation = rotation;
         }
     }
 }
Пример #17
0
 public virtual void RotateToAlignWithNormal(Vector3 a_Normal, RotateMethod a_Method = RotateMethod.FromBottom)
 {
 }
Пример #18
0
    //Query whether this module can be active, given the current state of the character controller (velocity, isGrounded etc.)
    //Called every frame when inactive (to see if it could be) and when active (to see if it should not be)
    public override bool IsApplicable()
    {
        if (m_ControlledCollider.IsGrounded())
        {
            return(false);
        }
        //Do allow if we just jumped up
        if (m_CharacterController.DidJustJump())
        {
            m_IsAlreadyTouchingWall = false;
        }
        if ((DoesInputExist("Crouch") && GetButtonInput("Crouch").m_IsPressed) ||
            GetDirInput("Move").m_Direction == DirectionInput.Direction.Down)
        {
            return(false);
        }
        //Disable when already touching wall beforehand, except when coming from standing position
        if (!m_IsActive && m_AllowOnlyWhenJustTouchingWall && (Time.time - m_CharacterController.GetLastGroundedTime() >= 0.02f))
        {
            if (m_ControlledCollider.GetSideCastInfo().m_HasHitSide&& (m_ControlledCollider.IsCompletelyTouchingWall()))
            {
                if (m_IsAlreadyTouchingWall)
                {
                    return(false);
                }
                m_IsAlreadyTouchingWall = true;
            }
            else
            {
                m_IsAlreadyTouchingWall = false;
                return(false);
            }
        }
        if (m_ControlledCollider.GetSideCastInfo().m_HasHitSide)
        {
            if (m_IsActive)
            {
                if (!m_ControlledCollider.IsPartiallyTouchingWall())
                {
                    return(false);
                }
            }
            else
            {
                if (!m_ControlledCollider.IsCompletelyTouchingWall())
                {
                    return(false);
                }
            }

            m_WallNormal   = m_ControlledCollider.GetSideCastInfo().GetSideNormal();
            m_RotateMethod = (m_WallNormal.y < 0) ? RotateMethod.FromTop : RotateMethod.FromBottom;
            m_UpDirection  = CState.GetDirectionAlongNormal(Vector3.up, m_WallNormal);
            float upVelDot = Vector2.Dot(m_UpDirection, m_ControlledCollider.GetVelocity());
            if (m_DisableWhenBelowVelocity && upVelDot <= m_MinimumUpVelocityOnStart) //Already going downwards, not applicable
            {
                return(false);
            }
            if (!m_ControlledCollider.CanAlignWithNormal(m_UpDirection))
            {
                return(false);
            }
            return(true);
        }
        return(false);
    }
Пример #19
0
 public override bool CanAlignWithNormal(Vector3 a_Normal, RotateMethod a_Method = RotateMethod.FromBottom)
 {
     return(m_CapsuleTransform.CanRotate(a_Normal, a_Method));
 }
Пример #20
0
 public virtual bool CanAlignWithNormal(Vector3 a_Normal, RotateMethod a_Method = RotateMethod.FromBottom)
 {
     return(false);
 }