Beispiel #1
0
    //This takes a list of raycasthits (which have been obtained from a downwards spherecast) and tries to decide if the character is grounded.
    //The raycasthit which determines the grounded state also contains information about normals.
    public void UpdateWithCollisions(List <RaycastHit> a_Collisions)
    {
        m_ValidHits.Clear();
        m_IsGrounded = false;
        Vector3 downCenter = m_CapsuleCollider.GetDownCenter();

        //Discard all hitresults that are above the lower hemisphere (locally), or have an inacceptable angle (locally or globally)
        for (int i = 0; i < a_Collisions.Count; i++)
        {
            float hitPointDot   = Vector3.Dot(a_Collisions[i].point, Vector3.up);
            float downCenterDot = Vector3.Dot(downCenter, Vector3.up);
            float reqAngle      = m_CapsuleCollider.GetMaxGroundedAngle();
            float angle         = Vector3.Angle(Vector3.up, a_Collisions[i].normal);
            if (hitPointDot < downCenterDot && Mathf.Abs(angle) < reqAngle)
            {
                m_ValidHits.Add(a_Collisions[i]);
            }
        }

        if (m_ValidHits.Count != 0)
        {
            float shortestDistance = m_ValidHits[0].distance;
            m_MostValidHit = m_ValidHits[0];
            for (int i = 1; i < m_ValidHits.Count; i++)
            {
                if (m_ValidHits[i].distance < shortestDistance)
                {
                    shortestDistance = m_ValidHits[i].distance;
                    m_MostValidHit   = m_ValidHits[i];
                }
            }
            m_IsGrounded = true;
        }
    }
    void SpawnParticles()
    {
        Vector3 position = Vector3.zero;
        Vector3 normal   = Vector3.zero;

        CGroundedInfo groundInfo   = m_CharacterController.GetCollider().GetGroundedInfo();
        CSideCastInfo sideCastInfo = m_CharacterController.GetCollider().GetSideCastInfo();
        bool          valid        = false;

        if (groundInfo.m_IsGrounded)
        {
            position = groundInfo.GetPoint();
            normal   = new Vector3(groundInfo.GetNormal().x, groundInfo.GetNormal().y, 0.0f);
            valid    = true;
        }
        else if (sideCastInfo.m_WallCastCount >= 2)
        {
            position = sideCastInfo.GetSidePoint();
            normal   = sideCastInfo.GetSideNormal();
            valid    = true;
        }
        else
        {
            position = m_Collider.GetDownCenter() - m_Collider.GetUpDirection() * m_Collider.GetRadius();
            normal   = m_Collider.GetUpDirection();
            valid    = true;
        }
        if (valid)
        {
            m_ParticleSystem.transform.position = position;
            m_ParticleSystem.transform.LookAt(position + normal, Vector3.back);
            m_ParticleSystem.Emit(m_EmissionCount);
        }
    }
Beispiel #3
0
    public bool CanBeResized(float a_Length, CapsuleResizeMethod a_Method)
    {
        Vector3 newPosition = m_Position;

        switch (a_Method)
        {
        case CapsuleResizeMethod.FromCenter:
            return(!Physics.CheckCapsule(newPosition - m_CapsuleCollider.GetUpDirection() * a_Length * 0.5f, newPosition + m_CapsuleCollider.GetUpDirection() * a_Length * 0.5f, m_CapsuleCollider.GetRadius(), m_CapsuleCollider.GetLayerMask()));

        case CapsuleResizeMethod.FromBottom:
            return(!Physics.CheckCapsule(m_CapsuleCollider.GetDownCenter(), m_CapsuleCollider.GetDownCenter() + m_CapsuleCollider.GetUpDirection() * a_Length, m_CapsuleCollider.GetRadius() - m_CapsuleCollider.GetResizeCastMargin(), m_CapsuleCollider.GetLayerMask()));

        case CapsuleResizeMethod.FromTop:
            return(!Physics.CheckCapsule(m_CapsuleCollider.GetUpCenter(), m_CapsuleCollider.GetUpCenter() - m_CapsuleCollider.GetUpDirection() * a_Length, m_CapsuleCollider.GetRadius() - m_CapsuleCollider.GetResizeCastMargin(), m_CapsuleCollider.GetLayerMask()));
        }
        return(true);
    }
    void Start()
    {
        //Make sure that we start at the right height, and that the parent is aligned to the lower demisphere
        //Prevents having to manually adjust both sprite and parent
        Vector3 originalPosition = transform.position;

        m_SpriteTransformHook.transform.position = m_CapsuleCollider.GetDownCenter();
        transform.position = originalPosition;
        m_StartHeight      = transform.localPosition.y;
    }
    //This takes the results of a sidecast and tries to determine if a wall is found.
    //Using the sidecast information, it sends out three probes (from the center of the top and bottom hemispheres and the center of the capsule).
    //It counts the amount of hits that are valid and stores this for other classes to access.
    void WallCast(RaycastHit a_SidecastHit)
    {
        if (Vector3.Angle(Vector3.up, a_SidecastHit.normal) > m_CapsuleCollider.GetMaxWallAngle() || Vector3.Angle(Vector3.up, a_SidecastHit.normal) < m_CapsuleCollider.GetMaxGroundedAngle())
        {
            m_WallCastCount = 0;
            return;
        }
        float   wallCastMargin   = m_CapsuleCollider.GetWallCastMargin();
        float   wallCastDistance = m_CapsuleCollider.GetWallCastDistance();
        Vector3 hitPos           = a_SidecastHit.point;
        Vector3 normal           = a_SidecastHit.normal;
        Vector3 currentUp        = m_CapsuleCollider.GetUpDirection();
        Vector3 direction        = CState.GetDirectionAlongNormal(Vector3.up, normal);
        Vector3 startHitPos1     = Vector3.zero;
        Vector3 startHitPos2     = Vector3.zero;
        Vector3 startHitPos3     = Vector3.zero;
        Vector3 normalOff        = normal * (m_CapsuleCollider.GetRadius() - wallCastMargin);

        //Determines where the sidecast has hit. This to orient the probes in the correct way.
        if (Vector3.Dot(currentUp, hitPos) <= Vector3.Dot(currentUp, m_CapsuleCollider.GetDownCenter()))//Hit on the lower hemisphere
        {
            startHitPos1 = m_CapsuleCollider.GetDownCenter() + direction * m_CapsuleCollider.GetDefaultLength() - normalOff;
            startHitPos2 = m_CapsuleCollider.GetDownCenter() - normalOff;
            startHitPos3 = m_CapsuleCollider.GetDownCenter() + direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff;
        }
        else if (Vector3.Dot(currentUp, hitPos) >= Vector3.Dot(currentUp, m_CapsuleCollider.GetUpCenter()))//Hit on the upper hemisphere
        {
            startHitPos1 = m_CapsuleCollider.GetUpCenter() - direction * m_CapsuleCollider.GetDefaultLength() - normalOff;
            startHitPos2 = m_CapsuleCollider.GetUpCenter() - normalOff;
            startHitPos3 = m_CapsuleCollider.GetUpCenter() - direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff;
        }
        else //Hit somewhere in the middle
        {
            startHitPos1 = m_CapsuleCollider.GetDownCenter(true) + direction * m_CapsuleCollider.GetDefaultLength() - normalOff;
            startHitPos2 = m_CapsuleCollider.GetDownCenter(true) - normalOff;
            startHitPos3 = m_CapsuleCollider.GetDownCenter(true) + direction * m_CapsuleCollider.GetDefaultLength() * 0.5f - normalOff;
        }

        RaycastHit newHit;

        m_WallCastCount = 0;
        if (Physics.Raycast(startHitPos1, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask()))
        {
            m_WallCastCount++;
        }
        if (Physics.Raycast(startHitPos2, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask()))
        {
            m_WallCastCount++;
        }
        if (Physics.Raycast(startHitPos3, -normal, out newHit, wallCastDistance + wallCastMargin, m_CapsuleCollider.GetLayerMask()))
        {
            m_WallCastCount++;
        }
    }