示例#1
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();
     }
 }
 public void ApplyEntireMovement(CapsuleTransform a_Transform)
 {
     if (a_Transform.GetPosition() != m_Position)
     {
         a_Transform.SetPosition(m_Position);
     }
     if (a_Transform.GetUpDirection() != m_UpDirection)
     {
         a_Transform.Rotate(m_UpDirection, m_RotateMethod);
     }
     if (a_Transform.GetLength() != m_Length)
     {
         a_Transform.SetLength(m_Length, m_ResizeMethod);
     }
 }
示例#3
0
    protected override void GeneratePath()
    {
        CEdgeCastInfo info = m_ControlledCollider.GetEdgeCastInfo();

        m_Path.Clear();
        CapsuleTransform copy = m_ControlledCollider.GetCapsuleTransformCopy();

        //First node is in edgehang alignment, moving away from the edge mildly
        CapsuleMovementPathNode newNode = m_Path.CreateFirstNode(copy);
        Vector3 upCenter = info.GetProposedHeadPoint();

        upCenter += m_ControlledCollider.GetEdgeCastInfo().GetWallNormal() * 0.03f;
        copy.SetUpCenter(upCenter);
        copy.Rotate(info.GetUpDirection(), RotateMethod.FromTop);
        newNode = m_Path.DuplicateAndAddLastNode();
        newNode.CopyFromTransform(copy);

        //Second node moves up along local up, until the bottom can slide over the edge
        newNode            = m_Path.DuplicateAndAddLastNode();
        newNode.m_Duration = m_MoveUpTime;
        float contactDot  = Vector3.Dot(info.GetEdgeNormal(), info.GetEdgePoint());
        float bottomDot   = Vector3.Dot(info.GetEdgeNormal(), copy.GetDownCenter()) - m_ControlledCollider.GetRadius() - m_MoveUpMargin;
        float normalDot   = Vector3.Dot(info.GetEdgeNormal(), copy.GetUpDirection());
        float rawDistance = contactDot - bottomDot;
        float distance    = rawDistance / normalDot;

        newNode.m_Position += copy.GetUpDirection() * distance;
        newNode.ApplyEntireMovement(copy);
        //Third node snaps the capsule to the "upright" position for the ground it's going to stand on
        newNode                = m_Path.DuplicateAndAddLastNode();
        newNode.m_Duration     = 0.0f;
        newNode.m_UpDirection  = (m_CharacterController.GetAlignsToGround()) ? info.GetEdgeNormal() : Vector3.up;
        newNode.m_RotateMethod = RotateMethod.FromBottom;
        newNode.ApplyEntireMovement(copy);
        newNode.m_Position = copy.GetPosition();
        //Final node moves the capsule over the ground
        newNode            = m_Path.DuplicateAndAddLastNode();
        newNode.m_Duration = m_MoveSideTime;
        Vector3 direction = CState.GetDirectionAlongNormal(-info.GetWallNormal(), info.GetEdgeNormal());

        newNode.m_Position += direction * m_MoveSideDistance;
        newNode.ApplyEntireMovement(copy);
    }
示例#4
0
    //Called for every fixedupdate that this module is active
    public override void FixedUpdateModule()
    {
        float currentTransitionTime = Time.time - m_TransitionStartTime;

        //A MovingColPoint is used to move and rotate the animation path when the collider it starts on is moved
        //This allows animated abilities to work on moving colliders
        if (m_ReferencePoint != null)
        {
            //Position
            CapsuleTransform copy = m_ControlledCollider.GetCapsuleTransformCopy();
            Vector3          diff = m_ReferencePoint.m_Transform.position - m_ReferencePoint.m_PrevPoint;
            copy.Move(diff);
            m_Path.Move(diff);

            //Rotation
            Quaternion rotationDifference = Quaternion.FromToRotation(m_ReferencePoint.m_PrevRot * Vector3.up, m_ReferencePoint.m_Transform.rotation * Vector3.up);
            copy.Rotate(rotationDifference * copy.GetUpDirection(), RotateMethod.FromCenter);
            m_Path.Rotate(rotationDifference, m_ReferencePoint.m_PrevPoint);

            //Offset for rotation
            Vector3 newRelativePoint   = rotationDifference * m_ReferencePoint.m_PointRelativeToThis;
            Vector3 relativeDifference = newRelativePoint - m_ReferencePoint.m_PointRelativeToThis;

            copy.Move(relativeDifference);

            m_ReferencePoint.m_PrevPoint           = m_ReferencePoint.m_Transform.position;
            m_ReferencePoint.m_PrevRot             = m_ReferencePoint.m_Transform.rotation;
            m_ReferencePoint.m_PointRelativeToThis = m_ReferencePoint.m_Transform.position - m_ControlledCollider.GetCapsuleTransform().GetPosition();
            m_ReferencePoint.m_Normal = Quaternion.FromToRotation(m_ReferencePoint.m_PrevRot * Vector3.up, m_ReferencePoint.m_Transform.rotation * Vector3.up) * m_ReferencePoint.m_Normal;

            if (copy.CanExistHere())
            {
                m_ControlledCollider.ApplyCapsuleTransform(copy);
            }
            else
            {
                m_WasInterrupted = true;
                return;
            }
        }
        m_ControlledCollider.SetVelocity(Vector2.zero);
        //Move along the nodes as long as they can be applied (either they are finished or their duration is 0)
        while (!m_Path.IsDone() && m_Path.m_CurrentPathNode != null && (m_Path.m_CurrentPathNode.m_Duration == 0 || Time.time - m_TransitionStartTime >= m_Path.m_CurrentPathNode.m_Duration))
        {
            if (m_Path.m_CurrentPathNode.CanApplyEntireMovement(m_ControlledCollider.GetCapsuleTransform()))
            {
                m_TransitionStartTime += m_Path.m_CurrentPathNode.m_Duration;
                currentTransitionTime -= m_Path.m_CurrentPathNode.m_Duration;
                m_Path.m_CurrentPathNode.ApplyEntireMovement(m_ControlledCollider.GetCapsuleTransform());
                m_Path.IncrementCurrentNode();
            }
            else
            {
                m_WasInterrupted = true;
                return;
            }
        }
        //Move along the current node
        if (m_Path.CanApplyMotion(m_ControlledCollider.GetCapsuleTransform(), currentTransitionTime))
        {
            m_Path.ApplyMotion(m_ControlledCollider.GetCapsuleTransform(), currentTransitionTime);
        }
        else
        {
            m_WasInterrupted = true;
            return;
        }
        m_ControlledCollider.UpdateContextInfo();
    }