Search Unity

Grounded.

Discussion in 'Scripting' started by Metal Head, Nov 5, 2010.

  1. Metal Head

    Metal Head

    Joined:
    Aug 14, 2010
    Posts:
    411
    What could cause this line here to not function properly?
    Code (csharp):
    1. grounded = (controller.Move(totalMovement )  CollisionFlags.Below) !=0;
    What happens is that when I'm in the air, grounded is false (ok), but when I'm on the ground, instead of being constantly true, it changes it's state every frame.
     
  2. laurie

    laurie

    Joined:
    Aug 31, 2009
    Posts:
    638
    Are you applying gravity or other movement every frame? If so that's normal; the movement causes the character controller to go slightly below ground level, causing a collision; the collision causes a reaction that pushes the character controller back up, a little above ground level. The cycle repeats frame by frame. You should be able to fix it by not moving the controller down when it's already grounded.
     
  3. FluidPixel_Gavin

    FluidPixel_Gavin

    Joined:
    Jan 6, 2010
    Posts:
    88
    is the and operator or is that supposed to be doing something different?
     
  4. Metal Head

    Metal Head

    Joined:
    Aug 14, 2010
    Posts:
    411
    Yes, I have gravity, that's applied, but it's applied only if grounded is false, else it would be:
    if(grounded) {
    gravityVar = 0;
    }

    But since it's using grounded to check if it should be modified, I assume what happens is some sort of loop.
    Maybe

    if((controller.Move(totalMovement ) CollisionFlags.Below) !=0)
    gravityVar = 0;
    will fix it.

    And no, "" is another thing.
     
  5. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Listen to what laurie said, only backwards ;); what you're experiencing is completely expected. You need to apply gravity no matter what.
     
  6. Metal Head

    Metal Head

    Joined:
    Aug 14, 2010
    Posts:
    411
    :D
    But if I apply gravity all the time, it would result in an unreallistic behavior. The gravity will keep multiplying even if I'm on the ground, so if I try to drop from some place (not with a jump), the player will start falling immediately with a huge speed. That's why my gravity becomes 0 when the player touches the ground. On the other hand, I tried it your way and it worked, but the gravity now is acting strange.
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    No, you code around that. Yes, there always has to be a nonzero downward velocity when falling (minDownwardVelocity in this code), but it doesn't have to be large enough to be noticeable, I guarantee you. There's no way that I know of to not have to do this kind of thing, when using a Character Controller. The example in the docs doesn't account for it; I'm interested in whether any example projects do, but not interested enough to wade through them, considering I got sick of all the weirdness of Character Controllers and started using Rigidbodies. ;)

    (This is based on the CharacterController.Move documentation, and worked great for me.)
    Code (csharp):
    1. if (controller.isGrounded  moveDirection.y <= 0) moveDirection.y = minDownwardVelocity;
    2. else moveDirection.y -= gravity * Time.deltaTime;
     
    Last edited: Nov 6, 2010
    armandobourquin likes this.
  8. Metal Head

    Metal Head

    Joined:
    Aug 14, 2010
    Posts:
    411
    Yes, that's what I did after posting. So if you say that's okay, I'm cool with it.
    I really wanted to use a rigidbody in the beginning, but I couldn't get it to work well. It kept rotating on the Z and X when it was on steep surfaces no matter if I had locked the rotation with a script or with something else.
    I should try to use a rigidbody for my player again. For example I made my controller slide of steep surfaces, it works great, but still if the controller used the physics, it would be much more reallistic. Sorry I got off topic, just got interested in what you said :D
     
  9. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    I'm having the same problem... I am using Debug.Log to print the "grounded" status of my character. When standing or running, my log keeps printing the status going back and forth between grounded and not grounded. The issue is that I cannot jump reliably. I have an "if (grounded) then perform the jump" logic in my code. Any suggestions for me? Thanks in advance!

    Jason
     
  10. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Please let me know if anyone has any suggestions on this. I spent all day on this yesterday and still can't find a reasonable solution. :(
     
  11. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    How is my post not helping you?
     
  12. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    I tried this bit of code and included it in my ThirdPersonController.js script. I am still having the problem where "Not Grounded" is the status more often than "Grounded." The net result is that I cannot jump most of the time because my code thinks that my character is not grounded. If I keep hitting the jump button enough, eventually the player character will jump. I will include my code so maybe your more experienced eye can spot where I am going wrong with this. One moment and I will post the code...
     
  13. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Here you go:

    Code (csharp):
    1.  
    2. // The smoothing factor for speed settings
    3. private var speedSmoothing : float = 10.0;
    4. // The speed that the player rotates when turning around
    5. private var rotateSpeed : float = 700.0;
    6. // Input variables
    7. private var inputVAxis : float = 0.0;
    8. private var inputHAxis : float = 0.0;
    9. private var jumpButtonWasPressed : boolean = false;
    10. private var jumpButtonIsPressed : boolean = false;
    11. // Store the camera system object into a static variable, since it won't change.
    12. private var cameraSystem : CameraSystemScript;
    13. // The previous move direction in x-z - We record this to effectively control the
    14. // player based on the last "controlling camera" until the timeout occurs for the
    15. // "controlling camera" or if the player changes direction.
    16. private var previousMoveDirection : Vector3 = Vector3.zero;
    17. // The current move direction in x-z
    18. private var currentMoveDirection : Vector3 = Vector3.zero;
    19. // Stores the "forward" vector for the player, so we always know which way he is facing.
    20. private var playerDirection : Vector3;
    21. // Is the user pressing any keys?
    22. private var isMoving : boolean = false;
    23. // Stores the current analog stick magnitude
    24. private var currentAnalogStickMagnitude : float = 0.0;
    25. // The various move speeds, usage depending on the analog stick magnitude
    26. private var moveSpeed1 : float = 0.4;
    27. private var moveSpeed2 : float = 0.55;
    28. private var moveSpeed3 : float = 0.7;
    29. private var moveSpeed4 : float = 0.85;
    30. private var moveSpeed5 : float = 1.0;
    31. private var moveSpeed6 : float = 1.15;
    32. private var moveSpeed7 : float = 1.3;
    33. private var moveSpeed8 : float = 1.45;
    34. private var moveSpeed9 : float = 1.6;
    35. // The gravity for the character
    36. private var playerGravity : float = 8.0;
    37. // How high do we jump when pressing jump and letting go immediately
    38. private var jumpHeight : float = 0.5;
    39. // We add extraJumpHeight meters on top when holding the button down longer while jumping
    40. private var extraJumpHeight : float = 2.5;
    41. // Are we jumping? (Initiated with jump button and not grounded yet)
    42. private var isJumping : boolean = false;
    43. private var jumpingReachedApex : boolean = false;
    44. // The height we jumped from (Used to determine for how long to apply extra jump power after jumping.)
    45. private var lastJumpStartHeight : float = 0.0;
    46. // Last time the jump button was pressed
    47. private var lastJumpButtonTime : float = -10.0;
    48. // Last time we performed a jump
    49. private var lastJumpTime : float = -1.0;
    50. // Jump timeout variable
    51. private var jumpTimeout = 0.15;
    52. // Jump repeat time variable
    53. private var jumpRepeatTime = 0.05;
    54. // Last time we were grounded
    55. private var lastGroundedTime : float = -1.0;
    56. // The last collision flags returned from controller.Move
    57. private var collisionFlags : CollisionFlags;
    58. // The current vertical speed
    59. private var verticalSpeed : float = 0.0;
    60. // The player's character controller object
    61. private var controller : CharacterController;
    62. // If true, player is grounded.
    63. private var playerIsGrounded : boolean = false;
    64.  
    65. function Awake()
    66. {
    67.     controller = gameObject.GetComponent(CharacterController) as CharacterController;
    68.  
    69.     currentMoveDirection = transform.TransformDirection(Vector3.forward);
    70.     previousMoveDirection = currentMoveDirection;
    71.  
    72.     cameraSystem = GameObject.Find("CameraSystem").GetComponent("CameraSystemScript") as CameraSystemScript;
    73. }
    74.  
    75. function Update()
    76. {
    77.     ReadInput();
    78.     ReadControlCameraVectors();
    79.     MovePlayer();
    80.     ApplyGravity();
    81. }
    82.  
    83. function ReadInput()
    84. {
    85.     inputVAxis = Input.GetAxisRaw("Vertical");
    86.     inputHAxis = Input.GetAxisRaw("Horizontal");
    87.     jumpButtonWasPressed = jumpButtonIsPressed;
    88.     jumpButtonIsPressed = Input.GetButton("Jump");
    89. }
    90.  
    91. function ReadControlCameraVectors()
    92. {
    93.     var controlCameraObject = GameObject.Find(cameraSystem.GetCurrentControlCameraName());
    94.     var cameraTransform : Transform = controlCameraObject.camera.transform;
    95.     var forwardVector : Vector3 = cameraTransform.TransformDirection(Vector3.forward);
    96.     forwardVector.y = 0;
    97.     forwardVector = forwardVector.normalized;
    98.     var rightVector : Vector3 = Vector3(forwardVector.z, 0, -forwardVector.x);
    99.  
    100.     var wasMoving : boolean = isMoving;
    101.     isMoving = Mathf.Abs(inputHAxis) > 0.1 || Mathf.Abs(inputVAxis) > 0.1;
    102.  
    103.     // Store the player's direction, only if the player is actually moving
    104.     if (isMoving)
    105.     {
    106.         // Calculate the direction the player is facing
    107.         playerDirection = inputHAxis * rightVector + inputVAxis * forwardVector;
    108.     }
    109. }
    110.  
    111. function MovePlayer()
    112. {
    113.     // Variable to store the movement information for each frame.
    114.     var movement : Vector3 = Vector3.zero;
    115.  
    116.     // Make sure the isMoving variable is true before processing player movement.  The isMoving variable is set to true
    117.     // whenever the user is using the movement controls on the joypad or keyboard.
    118.     if (isMoving)
    119.     {
    120.         // Save the previous move direction for the "control camera" functionality to know which camera was last.
    121.         previousMoveDirection = currentMoveDirection;
    122.         // The currentMoveDirection variable stores a rotation value.  It gets the current rotation and goes to the target
    123.         // rotation over so many seconds.  The third parameter in the RotateTowards method is the rotation speed.
    124.         // Higher value means faster rotation.
    125.         currentMoveDirection = Vector3.RotateTowards(currentMoveDirection, playerDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
    126.         // Rotate player appropriately
    127.         transform.rotation = Quaternion.LookRotation(currentMoveDirection);
    128.         // The movement variable takes the direction and multiplies it by Time.deltaTime * 2.  This will slow
    129.         // down the movement to rotate by seconds instead of by frames.  The currentMoveDirection is normalized
    130.         // so we can have direct control over the speed of the character later on.
    131.         movement = currentMoveDirection.normalized * Time.deltaTime * 2;
    132.         // Smooth the speed based on the current target direction
    133.         var curSmooth : float = speedSmoothing * Time.deltaTime;
    134.         // Choose target speed.  We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
    135.         var targetSpeed : float = 0.0;
    136.         // Get the amount the analog stick is pushed.  Pushing farther makes player run faster.
    137.         var analogStickMagnitude : float = Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")).magnitude;
    138.         // Pick speed modifier
    139.         if (analogStickMagnitude > 0.9)
    140.             targetSpeed = moveSpeed9;
    141.         else if (analogStickMagnitude > 0.8)
    142.             targetSpeed = moveSpeed8;
    143.         else if (analogStickMagnitude > 0.7)
    144.             targetSpeed = moveSpeed7;
    145.         else if (analogStickMagnitude > 0.6)
    146.             targetSpeed = moveSpeed6;
    147.         else if (analogStickMagnitude > 0.5)
    148.             targetSpeed = moveSpeed5;
    149.         else if (analogStickMagnitude > 0.4)
    150.             targetSpeed = moveSpeed4;
    151.         else if (analogStickMagnitude > 0.3)
    152.             targetSpeed = moveSpeed3;
    153.         else if (analogStickMagnitude > 0.2)
    154.             targetSpeed = moveSpeed2;
    155.         else if (analogStickMagnitude > 0.1)
    156.             targetSpeed = moveSpeed1;
    157.         else
    158.             targetSpeed = 0.0;
    159.         // Adjust the movement vector by the player's speed
    160.         movement *= targetSpeed;
    161.         // Store the analog stick magnitude so that the animation script can fetch and process with it
    162.         currentAnalogStickMagnitude = analogStickMagnitude;
    163.     }
    164.     else
    165.     {
    166.         currentAnalogStickMagnitude = 0.0;
    167.     }
    168.  
    169.     // Update the "control camera" by force if the move direction has changed...
    170.     if (previousMoveDirection != currentMoveDirection)
    171.     {
    172.         cameraSystem.ForceControlCameraUpdate();
    173.     }
    174.  
    175.     // See if the player is freshly pressing the jump button
    176.     if (jumpButtonIsPressed  !jumpButtonWasPressed)
    177.     {
    178.         StartJump();
    179.     }
    180.  
    181.     // Determine if we are grounded or not
    182.     if (controller.isGrounded  movement.y <= 0)
    183.         playerIsGrounded = true;
    184.     else
    185.         playerIsGrounded = false;
    186.  
    187.     if (playerIsGrounded)
    188.     {
    189.         lastGroundedTime = Time.time;
    190.         if (isJumping)
    191.         {
    192.             isJumping = false;
    193.         }
    194.     }
    195.  
    196.     // Make the player fall if there is no floor underneath him.
    197.     if (!playerIsGrounded)
    198.         movement = movement + (Vector3(0, verticalSpeed, 0) * Time.deltaTime * 2);
    199.  
    200.     controller.Move(movement);
    201.  
    202.     if (playerIsGrounded)
    203.         Debug.Log("GROUNDED");
    204.     else
    205.         Debug.Log("NOT GROUNDED");
    206. }
    207.  
    208. function GetAnalogStickMagnitude()
    209. {
    210.     return currentAnalogStickMagnitude;
    211. }
    212.  
    213. function ApplyGravity()
    214. {
    215.     // When we reach the apex of the jump we perform the appropriate operations.
    216.     if (isJumping  !jumpingReachedApex  verticalSpeed <= 0.0)
    217.     {
    218.         jumpingReachedApex = true;
    219.     }
    220.  
    221.     // When jumping up we don't apply gravity for some time when the user is holding the jump button.
    222.     // This gives more control over jump height by pressing the button longer.
    223.     var applyingExtraJumpHeight : boolean = false;
    224.     if (IsJumping()
    225.         verticalSpeed > 0.0
    226.         jumpButtonIsPressed
    227.         transform.position.y < lastJumpStartHeight + extraJumpHeight)
    228.     {
    229.         applyingExtraJumpHeight = true;
    230.     }
    231.     else
    232.     {
    233.         applyingExtraJumpHeight = false;
    234.     }
    235.  
    236.     if (applyingExtraJumpHeight)
    237.     {
    238.         return;
    239.     }
    240.     else if (playerIsGrounded)
    241.     {
    242.         verticalSpeed = 0.0;
    243.     }
    244.     else
    245.     {
    246.         verticalSpeed -= playerGravity * Time.deltaTime;
    247.     }
    248. }
    249.  
    250. function StartJump()
    251. {
    252.     // Prevent jumping too fast after each other
    253.     if (lastJumpTime + jumpRepeatTime > Time.time)
    254.         return;
    255.  
    256.     if (playerIsGrounded)
    257.     {
    258.         verticalSpeed = CalculateJumpVerticalSpeed();
    259.         DidJump();
    260.     }
    261. }
    262.  
    263. function CalculateJumpVerticalSpeed ()
    264. {
    265.     // From the jump height and gravity we deduce the upwards speed
    266.     // for the character to reach at the apex.
    267.     return Mathf.Sqrt(2 * jumpHeight * playerGravity);
    268. }
    269.  
    270. function DidJump()
    271. {
    272.     isJumping = true;
    273.     jumpingReachedApex = false;
    274.     lastJumpTime = Time.time;
    275.     lastJumpStartHeight = transform.position.y;
    276.     lastJumpButtonTime = -10;
    277. }
    278.  
    279. function IsJumping()
    280. {
    281.     return isJumping;
    282. }
    283.  
     
  14. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    That's a lot of stuff, but I'd guess that
    Code (csharp):
    1. if (playerIsGrounded) verticalSpeed = 0.0;
    is the culprit.

    If not, try whittling that down, and provide an example package/project.
     
    Last edited: May 11, 2011
    legoblaster1234 likes this.
  15. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Thank you for your feedback, Jessy. Once again, sorry for the large sized post. If your assessment is that this is the problem...

    Code (csharp):
    1. if (playerIsGrounded) verticalSpeed = 0.0;
    ...then what is wrong with it? Maybe I'm not seeing what you are seeing, but I'm trying to figure out where you think that is causing the problem. Shouldn't I be setting the vertical gravity to 0.0 when the player is grounded? Thanks in advance!
     
  16. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    No. This is what I have posted about in this thread. Please reread, and ask questions to help you understand and internalize if necessary.
     
  17. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Well, the reason I am confused is that I believed I WAS following your advice in this thread by setting downward velocity to 0.0. For example, above in this post Laurie said:
    And then you said:
    So I assumed that Laurie was right about "not moving the controller down when it's already grounded"... however, thinking you meant "backwards" to mean don't do it, I tried commenting out "verticalSpeed = 0,0" and even replaced it with code that pulls the character downward... to no avail. The same behavior of "grounded" and "not grounded" still happens.

    If you need me to post more to get a resolution, please let me know. I am not understanding how other people deal with this kind of problem that use character controllers... :-/
     
  18. Sydeshow

    Sydeshow

    Joined:
    Jun 11, 2009
    Posts:
    15
    I haven't tried to do this and don't claim to be an expert coder, but after reading the platformer tutorial a few times... I remembered something regarding physics.

    From the third person platformer tutorial:
    Key words being "difficult to model".

    If you have your heart set on physics, why not program some variance or leniency into your IsGrounded function? Say by measuring transform distance from something on a "ground" layer? That way if it's within .5 or .3 or however much of a grace period, it can still be considered "grounded".

    just my 2c. Hope I didn't derail this. :eek:
     
  19. Sydeshow

    Sydeshow

    Joined:
    Jun 11, 2009
    Posts:
    15
    Come to think of it... I like laurie's idea better.
     
  20. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    What I meant was, that
    should read
    The ground will push the controller out, but only to a certain threshold, determined by the Skin Width. It will not push the character out enough to cause isGrounded to be false, unless you don't apply a minimum amount of force downward.

    You'll never achieve an equilibrium where no downward movement is being attempted, and isGrounded is true. If you're working with rigidbodies, then this is not a problem, because you're thinking about applying forces, not "attempting movement in a vector". You've got to adjust your thinking to the oddity of CharacterController.Move, if you don't want to try to make a rigidbody character system.
     
    Last edited: May 31, 2011
  21. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Okay, let me give that a try.
     
  22. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Okay, well here's the latest:

    I took out the part where verticalSpeed gets reset to zero. So there is always a downward verticalSpeed present. However, there is no change when it comes to the symptom of "not grounded" being the status over and over per second. My understanding (based on what I've read in this thread and elsewhere) is that "not grounded" will be the status quite a bit if gravity is involved since the player is always getting pushed down (past the plane of collision) and then Unity is pushing the player back up to the floor again.

    SO........... here's my question. All I want to do is determine if the player is standing on solid ground or not (for the sake of jumping logic). Is there another way you would advise to accomplish this instead of using controller.isgrounded?

    Many thanks yet again.
     
  23. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Check out this simple package and see what you can get from it. It illustrates what you need to be doing vertically; anything that changes from this is the result of your code not working for you properly.

    You just need enough downward force to overcome the "force" of being pushed out of the surface.
     

    Attached Files:

    Last edited: May 31, 2011
    muammar_a_tq and Koenn like this.
  24. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Thank you, Jessy. I'll check this out (by tomorrow morning) and see how it works out. I truly appreciate the assistance.
     
  25. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Jessy, the unity package you shared made it real to me, and I could see exactly what you were talking about. You have converted me, and turned me into a believer. THAT WORKED!!!!!!!!!!!!!!!!!!!!!!!!!! After a month of not understanding how to fix this, you have become my hero... THANK YOU!!!!!!!
     
  26. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    :D

    Sorry I didn't think to make it earlier. It didn't take that long, and illustrates the situation better than any forum babble could. Good luck incorporating it into your more complex script. It shouldn't be too difficult; you'll just need to make sure you're putting code in the right order, and branching appropriately, so you always have just enough downward force to make isGrounded true, but not so much that when you step off a cliff, you are moving downward faster than anticipated.
     
  27. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    The great part about it is, I have already incorporated it into the script and cleaned up a few loose ends that remained from my crazy tests and attempts to fix this problem. Thank you, thank you, thank you.
     
  28. jpdavis81

    jpdavis81

    Joined:
    Apr 1, 2011
    Posts:
    33
    Jessy, for what it's worth, I gave you credit for this fix on my Severe Software Facebook page. Thanks again. :)
     
  29. toum

    toum

    Joined:
    Nov 21, 2009
    Posts:
    15
    Dear all,

    I'am experiencing the same problem of "alternative" grounded state with character controller. I used the workaround of Jessy which solved a part of my problem :).

    I my game i got a snowboarder riding a slope. When grounded i got moveDirection.y -= theMagicValue ;)

    However this workaround works only if i go down slope. If my snowboard try to ascend the slope the isGrounded state stay false !

    I think the controller don't detect the ground when ascend the slope.

    Anyone has already experienced that?

    T
     
  30. toum

    toum

    Joined:
    Nov 21, 2009
    Posts:
    15
    A note to my previous post: I got the problem if my slope angle is too important too. Character Controller is not able to detect grounded state to true even if theorically i'm grounded...

    Thank you for your assistance
     
  31. pn99

    pn99

    Joined:
    Feb 9, 2012
    Posts:
    20
    Hi,
    Been reading this thread, as I too had a object with jitters. After much messing around to fix it (thanks to the above posts by all the smart folks), I see that it has to do with an interaction between either the character controller, mesh coliider and the surface it is resting on.

    Well, I just made my character controller 'skin width' thicker from 0.001 to 0.007 and the jitters stopped (the unity reference manual actually mentions this). I don't know if that was the best solution or even if it sticks, but it works for me now, and I can move on. Hope it can helps someone.

    cheers,
    Pm99
    :D
     
    Last edited: Apr 25, 2012
  32. muammar_a_tq

    muammar_a_tq

    Joined:
    Dec 9, 2017
    Posts:
    2
    Dear future googlers, this is the one... this is the solution.
     
  33. Yurchee

    Yurchee

    Joined:
    Aug 16, 2019
    Posts:
    1
    The .unitypackage isn't working anymore for me - using Unity 2019.3.10f1. The scrips aren't getting imported. And after reading a couple of forum posts i am still not sure what the hell is going on.
     
    Captainzero and lagallardo5426 like this.