Search Unity

Unity's FPS microgame and player collision

Discussion in 'Getting Started' started by ncho, Jan 19, 2020.

  1. ncho

    ncho

    Joined:
    Feb 1, 2014
    Posts:
    99
    I am trying to adapt the FPS microgame (https://learn.unity.com/project/fps-template) to my own game because it has a nice feel to it and the scripts are not overloaded with bloat and mechanics I don't need like a lot of the asset store FPS controllers.

    I have one problem however which is that the player collision handling seems to be handled in a weirdly idiosyncratic way. Instead of having a capsule collider on the player, it seems that a capsule is created at runtime when needed to handle collision. At least I think that is what is happening because I don't fully understand the code. I think this is the relevant excerpt:

    Code (CSharp):
    1.  // apply the final calculated velocity value as a character movement
    2.         Vector3 capsuleBottomBeforeMove = GetCapsuleBottomHemisphere();
    3.         Vector3 capsuleTopBeforeMove = GetCapsuleTopHemisphere(m_Controller.height);
    4.         m_Controller.Move(characterVelocity * Time.deltaTime);
    5.  
    6.         // detect obstructions to adjust velocity accordingly
    7.         m_LatestImpactSpeed = Vector3.zero;
    8.         if (Physics.CapsuleCast(capsuleBottomBeforeMove, capsuleTopBeforeMove, m_Controller.radius, characterVelocity.normalized, out RaycastHit hit, characterVelocity.magnitude * Time.deltaTime, -1, QueryTriggerInteraction.Ignore))
    9.         {
    10.             // We remember the last impact speed because the fall damage logic might need it
    11.             m_LatestImpactSpeed = characterVelocity;
    12.  
    13.             characterVelocity = Vector3.ProjectOnPlane(characterVelocity, hit.normal);
    14.         }
    15.     }
    16.  
    17.     // Returns true if the slope angle represented by the given normal is under the slope angle limit of the character controller
    18.     bool IsNormalUnderSlopeLimit(Vector3 normal)
    19.     {
    20.         return Vector3.Angle(transform.up, normal) <= m_Controller.slopeLimit;
    21.     }
    22.  
    23.     // Gets the center point of the bottom hemisphere of the character controller capsule  
    24.     Vector3 GetCapsuleBottomHemisphere()
    25.     {
    26.         return transform.position + (transform.up * m_Controller.radius);
    27.     }
    28.  
    29.     // Gets the center point of the top hemisphere of the character controller capsule  
    30.     Vector3 GetCapsuleTopHemisphere(float atHeight)
    31.     {
    32.         return transform.position + (transform.up * (atHeight - m_Controller.radius));
    33.     }
    34.  
    35.     // Gets a reoriented direction that is tangent to a given slope
    36.     public Vector3 GetDirectionReorientedOnSlope(Vector3 direction, Vector3 slopeNormal)
    37.     {
    38.         Vector3 directionRight = Vector3.Cross(direction, transform.up);
    39.         return Vector3.Cross(slopeNormal, directionRight).normalized;
    40.     }
    41.  
    42.     void UpdateCharacterHeight(bool force)
    43.     {
    44.         // Update height instantly
    45.         if (force)
    46.         {
    47.             m_Controller.height = m_TargetCharacterHeight;
    48.             m_Controller.center = Vector3.up * m_Controller.height * 0.5f;
    49.             playerCamera.transform.localPosition = Vector3.up * m_TargetCharacterHeight * cameraHeightRatio;
    50.             m_Actor.aimPoint.transform.localPosition = m_Controller.center;
    51.         }
    52.         // Update smooth height
    53.         else if (m_Controller.height != m_TargetCharacterHeight)
    54.         {
    55.             // resize the capsule and adjust camera position
    56.             m_Controller.height = Mathf.Lerp(m_Controller.height, m_TargetCharacterHeight, crouchingSharpness * Time.deltaTime);
    57.             m_Controller.center = Vector3.up * m_Controller.height * 0.5f;
    58.             playerCamera.transform.localPosition = Vector3.Lerp(playerCamera.transform.localPosition, Vector3.up * m_TargetCharacterHeight * cameraHeightRatio, crouchingSharpness * Time.deltaTime);
    59.             m_Actor.aimPoint.transform.localPosition = m_Controller.center;
    60.         }
    61.     }
    62.  
    63.     // returns false if there was an obstruction
    64.     bool SetCrouchingState(bool crouched, bool ignoreObstructions)
    65.     {
    66.         // set appropriate heights
    67.         if (crouched)
    68.         {
    69.             m_TargetCharacterHeight = capsuleHeightCrouching;
    70.         }
    71.         else
    72.         {
    73.             // Detect obstructions
    74.             if (!ignoreObstructions)
    75.             {
    76.                 Collider[] standingOverlaps = Physics.OverlapCapsule(
    77.                     GetCapsuleBottomHemisphere(),
    78.                     GetCapsuleTopHemisphere(capsuleHeightStanding),
    79.                     m_Controller.radius,
    80.                     -1,
    81.                     QueryTriggerInteraction.Ignore);
    82.                 foreach (Collider c in standingOverlaps)
    83.                 {
    84.                     if (c != m_Controller)
    85.                     {
    86.                         return false;
    87.                     }
    88.                 }
    89.             }
    90.  
    91.             m_TargetCharacterHeight = capsuleHeightStanding;
    92.         }
    93.  
    94.         if (onStanceChanged != null)
    95.         {
    96.             onStanceChanged.Invoke(crouched);
    97.         }
    98.  
    99.         isCrouching = crouched;
    100.         return true;
    101.     }
    The problem is that I am trying to use Behavior Designer's line of sight mechanics that depend on a collider to be able for an object to see another object and adding a collider to the player on top of the above code breaks jumping and crouching.

    Is there some elegant or simple way to fix this? Or what exactly do I need to change to have the player use a standard collider instead?
     
    Angir777 likes this.
  2. yoursisteramister1

    yoursisteramister1

    Joined:
    Sep 28, 2020
    Posts:
    1
    I'm also having the same problem. Whoever attempted this part of the mini-game did it stupidly.
    Any luck?
     
  3. Angir777

    Angir777

    Joined:
    Nov 18, 2019
    Posts:
    1
    Hello, I have the same problem. Can someone solve it?