Search Unity

CharacterController.Move isn't setting collision flags

Discussion in 'Scripting' started by MeteoricDragon, Aug 25, 2018.

  1. MeteoricDragon

    MeteoricDragon

    Joined:
    Mar 24, 2018
    Posts:
    6
    I have a function in a "LevitateMotor" class that levitates or swims my CharacterController. It is supposed to set a CollisionFlags variable by invoking CharacterController.Move method. But for some reason, no `collisionFlags` are set after the CharacterController moves and collides with walls. The character is being stopped by the walls but no CollisionFlag changes occur. Is there some limitation to the Move method I don't know about?

    The very same CharacterController uses a different "GroundMotor" class to make the character walk on the ground, and the collisionFlags variable in that class changes correctly according to what it collides with.

    `playerMotor.controller` is the CharacterController, Look towards the bottom of the method below to find the collisionFlags assignment.

    Code (CSharp):
    1.         // this is the member-level declaration reference to PlayerMotor inside LevitateMotor class
    2.         public PlayerMotor playerMotor;
    3.  
    4.         // PlayerMotor is initialized like this in the Start method
    5.         playerMotor = GetComponent<PlayerMotor>();
    6.  
    7.         void Move(Vector3 direction, bool upOrDown = false)
    8.         {
    9.             if (playerSwimming)
    10.             {
    11.                 // Do not allow player to swim up out of water, as he would immediately be pulled back in, making jerky movement and playing the splash sound repeatedly
    12.                 if ((direction.y > 0) && (playerMotor.controller.transform.position.y + (50 * MeshReader.GlobalScale) - 0.93f) >=
    13.                 (GameManager.Instance.PlayerEnterExit.blockWaterLevel * -1 * MeshReader.GlobalScale) &&
    14.                 !playerLevitating)
    15.                     direction.y = 0;
    16.  
    17.                 Entity.PlayerEntity player = GameManager.Instance.PlayerEntity;
    18.                 float baseSpeed = speedChanger.GetBaseSpeed();
    19.                 moveSpeed = speedChanger.GetSwimSpeed(baseSpeed);
    20.             }
    21.  
    22.             // There's a fixed speed for up/down movement
    23.             if (upOrDown)
    24.                 moveSpeed = 80f / PlayerSpeedChanger.classicToUnitySpeedUnitRatio;
    25.  
    26.             collisionFlags = playerMotor.controller.Move(direction * moveSpeed * Time.deltaTime);
    27.             // Reset to levitate speed in case it has been changed by swimming
    28.             moveSpeed = 4.0f;
    29.         }
    30.  

    Below is the assignment statement in the GroundMotor class that assigns to collisionFlags correctly. And the CharacterController moves properly too.


    Code (CSharp):
    1. // this is the member level CharacterController declaration
    2.         private CharacterController controller;
    3.  
    4.         // Initialized in start method
    5.         controller = GetComponent<CharacterController>();
    6.  
    7.             // Called to move the controller via walking
    8.             collisionFlags = controller.Move(moveDirection * Time.deltaTime);
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Are you calling Move on the same character controller twice per frame? That's not recommended, and probably why your flags are empty on the second move.
     
  3. MeteoricDragon

    MeteoricDragon

    Joined:
    Mar 24, 2018
    Posts:
    6
    No sir. I have If statements that check to see if the player is swimming or levitating, and if so, it returns and doesn't call the CharacterController.Move for walking.
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
  5. MeteoricDragon

    MeteoricDragon

    Joined:
    Mar 24, 2018
    Posts:
    6
    You're talking about after executing this line, right?

    Code (CSharp):
    1.             collisionFlags = playerMotor.controller.Move(direction * moveSpeed * Time.deltaTime);
    2.  
    Aha!. I tested it out and for some reason the
    CollidedSides
    ,
    CollidedBelow
    , and/or
    CollidedAbove
    flags get set on the intrinsic CollisionFlag property, Not just
    sides
    or
    below
    , or
    above
    . Why add the word collided to the flag?

    Thanks you helped me fix it. But do you know why it is the way it is? I'm curious.
     
  6. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I'm not really sure what you're asking. Could you rephrase?
     
  7. MeteoricDragon

    MeteoricDragon

    Joined:
    Mar 24, 2018
    Posts:
    6
    Certainly, why does the enumerable CollosionFlags have CollisionFlags.CollidedSides as well as CollisionFlags.sides. it seems redundant.
     
  8. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201