Keeping my quadruped grounded when not jumping

Hey everyone, I am new here, trying to make my first game, and, well, I am hitting a few snags. But before I program a wicked double jump where Goupi, the player sprite, uses his tail to jump, I want to get the basic done.

I don’t know… anything really about c# scripting (although I am starting to understand) and used Mke Geig’s video https://unity3d.com/learn/tutorials/modules/beginner/2d/2d-controllers to create a script for Goupi.

However, there’s one part that I failed to mention so far: Goupi is a 4 legged animal. Because of this, I noticed that I need to fix the controller script to compensate for his hind legs. When Goupi climbs a hill, only his front claws actually touch the ground, and he is sort of running though the air up the hill (for obvious reasons) and when he is going down hill, for an unknown reason ( I think it has something to do with the way that Mike made his jump, or fall, cycle) Goupi’s stuck in the mid arch of his jump and it looks like he is sliding on his thick tail.

My thought was simple: Place another groundCheck on his hind legs, then rotate the character if groundCheck2 = false to fix the uphill, and if the reverse was true (groundCheck = false && groundCheck2 = true) then initiate the falling sequence. However, groundCheck2 is mirroring groundCheck and so, the effect is still lost.

Also, I added a trampoline concept using a mushroom so that Goupi can bounce off the mushroom. That part is easy to do, but the jump animation doesn’t do a realistic jump cycle. So I created the jump cycle as a run cycle, but it is now out of sync.

I have looked online and can’t find a solution on how to fix the movement script or the jumping script of a quadruped. I found, however, a great “this is what I want it to look like” in the game William and Sly (1) on Newgrounds. (if anyone needs it)

Any help in this matter would be greatly appreciated.

One way to cope with a character’s back end floating when going up a slope is to place scenery in front of the character’s feet. Since your character is short, this might not work for you, but for a four-legged creature, actually rotating the character to meet the slope angle would probably look pretty natural. I’m not sure what you mean by your groundCheck2 “mirroring” groundCheck, can you elaborate?

As for “falling” down a slope, what technique are you using to check for grounding? Is it a Raycast(), or maybe an OverlapArea()? Some methods can cause “blind spots” when the character is on a slope, and the solution is usually to check over a wider area.

I’m having a hard time picturing your jumping problem, though I did look up William and Sly, so I know what you’re looking for. Can you post .gifs or videos of the behavior? Do you have the mid-air animation in a blend tree which depends on the character’s vertical speed?

ok, I will answer the parts about the sensors via this:

originally, Mike programmed the bot saying “bool grounded = false;” and “float groundRadius = 0.1f;” in the Monobehavior.

I added “bool groundedf = false;” “bool groundedb = false;” (f for front and b for back) “bool hill = false;” “bool valley = false;” and “float ground2Radius = 0.1f;”

Moving onto the void FixedUpdate(), Mike programmed "grounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);

I changed that to the following, hoping that it would create a check for the front and a check for the back seperately.
"groundedf = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
anim.SetBool(“Ground”, true);

groundedb = Physics2D.OverlapCircle(groundCheck2.position, ground2Radius, whatIsGround);
anim.SetBool(“GroundBack”, true);"

Unfortunately, although I changed a few variables, all that has happened is that the bools for the back sensor come on when the front sensor is true. So if he is going down a hill, due to the polygon collider on the hill, the back sensor doesn’t register that it should be true, since the front legs are in mid air, and when he is going up a hill, although his hind legs are riding in mid air, the bool is still set to true.

What I was hoping for is that the sensors work separately so that I can trigger my extra bools as follows:

"If (groundedf = true && groundedb = true)
{grounded = true;}
else if (groundedf = false || groundedb = true)
{valley = true;}
else if {groundedf = true || groundedb = false)
{hill = true;}

Without knowing much more coding than || means but, && means and and starting to learn terminology, I was thinking that if I could create the differences in all three states, I could use my animator to trigger different stages of a jump cycle. I thought that I could continue by stating “If (hill = true) {rotate gameObject= 45;}” to rotate him with the hills. However, the only rotate functions I found won’t rotate him back when hill = false.

I hope this makes sense. As I said, I don’t know much about terminology yet, I don’t know what a RayCast () is… I just noticed that Mike did use OverlapCircle() so I used it…

Now for the jumping: I took out the blend tree as I didn’t understand how to work it, but what was happening is that (the best I can do to show this, as I don’t know how to show a video of the behavior… or understand what exactly that you wanted to see) when Goupi would go down a hill, he would be stuck in the 7th image slot all the way down the hill. I was hoping for the 11th (last) image slot as it would look more natural, but that didn’t work. (since then, I removed the first, as it should have been seen before he jumped but jumped too soon.)

What I then tried to do is to create three animations: a Rise animation, and Arch animation and a Fall animation. That way, when yspeed < 0; so when his yspeed shows a negative number, he’d go from the anystate to the Fall animation, comprised of the picture 11. When his yspeed =10f, (trial and error for his jump speed), he goes from anystate to Rise, which comprises of pictures 2,3,4, and 5 I believe. Then I wanted to make a transition "When yspeed is less than 10 but greater than -.01f, transition from Rise to Arch. witch comprises of pictures 9 and 10. With groundCheck and ground2Check being false on each option.

I also wanted to make it so that if valley is true, enact the Fall as well, but I did that via another transition from anystate.

The problem I am getting now is that if I go back to the tree design, I would get the same problems I have been getting, however, this jump cycle repeats itself on rise in multiple repeats until I hit the ground again. I wanted it to play the animation once, and stick itself into the last image until Arch sets in, so that when the bouncy mushroom is added to the mix, he still looks natural.

I should mention that with the tree, it made the bouncy mushroom look weird as he fell going up for some reason.

Does this clarify my confusion?

2620752--183997--Goupi jump side show.png

Thanks for that info, I can more clearly imagine the issues now, I think. Some comments for you:

I’m confident you’ll want to use a blend tree for this purpose. Make it dependent on the y speed, and have each branch be one frame of the jumping animation. You can set it up so that each frame corresponds to a particular positive or negative vertical speed, which will give a natural extending-to-anticipation effect. If you’re confused about how it works, just ask us more questions, we’ll help.

I have this technique running well in my game, so I can help you along.

Raycasts are very important in game programming. Essentially you specify a point in game space and a direction, and the game calculates an imaginary line (a ray…) and tells you if it would run into any colliders (…cast). It’s often used for projectile weapons, but is also vastly useful for physics. Keep it in mind as a potential tool as you move forward and encounter more scripting challenges.

|| is actually a logical OR. The expression (A || B) returns true if either A or B is true. Fun fact: logically, “but” means the same thing as “and”, although it implies contradiction. Naturally anything that “implies” has no place in coding. (For the nitpickers, yes I know that implicitness is actually relevant in coding, but it means something entirely different in spoken language, which is what I’m referring to here.)

Knowing this, double-check your code to make sure it’s doing what you meant for it to do; it seems like you meant to use AND for all the if statements, like this:

If (groundedf = true && groundedb = true)
{grounded = true;}  //If both ends are grounded, Goupi is on flat ground

else if (groundedf = false && groundedb = true)
{valley = true;}  //If the back is grounded and the front is not, Goupi is descending

else if {groundedf = true && groundedb = false)
{hill = true;}  //If the front is grounded and the back is not, Goupi is ascending

EDIT: The above code should use ‘==’ instead of ‘=’ in the if statements. I wrote it wrong, but I’m leaving it that way so the next few posts remain consistent.

(Make sure you use code tags when posting code on the forum.)

Are you using if statements to set those bools? As in if (groundedf) {anim.SetBool("Ground", true);}? If not, then your bools will always be set to true the way you have it written.

If you have, then I don’t see anything wrong with this logic, and I think it’s the same thing I would try. If you have two check points on opposite sides of the character, there’s no reason that they should always return the same value when slopes are involved unless some of your numbers are off. Are you sure that groundCheck and groundCheck2 aren’t the same, or too close together? Is groundRadius or groundRadius2 too large? Try using Debug.DrawLine() to help visualize where the circles are (or you can just add temporary colliders set as triggers which have the same center and radius, then look in scene mode to see them).

The character is cute, by the way. I also like the name.

1 Like

Sorry I didn’t reply right away, I was looking forward to your reply and missed it until Friday (had appointments all day)

I am going to try the blendtree again upon your request, and play with the y axis variables a little bit more. I wish that Mike would have gone more into detail on how to set one up. The one question I came up with while writing the following is: Can you change the sprite’s collides depending on which branch of the blend tree you are on? So that if Goupi is straight up, then he isn’t blowing through the roof?

ON ANOTHER NOTE: Since Goupi is a quadruped, turning around looks really odd for him to just “pop” on the other side. I watched the game I mentioned before and studied it a bit more to realize that the reason his animation is so fluent is that when Sly is grounded and he turns around, his speed drops to 0 for a split second while an animation image of a turn happens. So I broke it down to the three things. 1. trigger event when direction changes and is grounded, 2. Stop speed for 23 f (it seems that my animation of Goupi works at 23 f) 3. display a different icon for Goupi. Any thoughts?

Lastly, how would you make wasd or ^ optional? since float move = Input.GetAxis("Horizontal") gets both options? I realize that Horizontal is a main feature in System.Collections where all is available, but I was thinking of having a screen where you can select your input.

I will keep that in mind and will study Raycasts.

Thanks for the advice. AND the lesson in how to post code in the form. I will send a review on here on my finished code to see if there is some sprucing up that I can do. ( copying is good, but you seem great at explaining the “why it could be this way instead”)

EDIT: when I put your code in, it works well, except I am getting a CS0131 error code “The left-hand side of an assignment must be a variable, property or indexer” How do I fix that?

So here are my ControllerScript things (before the void start). If you chance seeing something wrong, please let me know. Also, the health part, I am learning how to do, but I thought it would be useful in the future. (he has very high health, super strength, but too much innocence to use it as a weapon… However, in later games, he will use this wisely.)

    public int health;
    public float maxSpeed = 3f;
    bool facingRight = true;

    Animator anim;

    bool groundedf = false;
    bool groundedb = false;
    bool grounded = false;
    bool hill = false;
    bool valley = false;
    public Transform groundCheck;
    public Transform groundCheck2;
    float groundRadius = 0.1f;
    float ground2Radius = 0.1f;
    public LayerMask whatIsGround;
    public float jumpForce = 700f;
[FONT=Arial]

Thanks! I recently drew Goupi with a husky (picture included) as my gf likes huskies and realized that I lost some fox features to him. So I will be fixing that real soon (also, he tends to shake when he is idle, so I need to get that fixed, as well as shading.)

Just a cute anecdote, since you shared one: In french, fox is named “Renard” but that name was coined by an author some hundred years ago when the name of the animal was “Goupil”. He wrote a book named “Renart le Goupi” (Renart the fox) and the name was changed ever since… I just keep forgetting to add the L so it’s now Goupi.

2627089--184608--^7740848020C273B38A23777081BD4BB99727766D9CDAC2CD2B^pimgpsh_fullsize_distr.jpg

Yep, animate the colliders’ offsets/sizes in each animation to the correct position. It’s ok if each animation is only one frame.

Sounds about right to me, just make sure you make transitions from the “turning” state to all of the states that you should normally be able to go to from the running state, unless you don’t want your player to be able to do anything while turning around (not recommended). If you’re using localScale to turn your character around, you’ll have to make sure that this is timed properly as well (either just before or just after the turning animation; which you choose will change the way the animation graphics should be flipped by default).

If you want axes to be dynamically configurable, you will need to write your own axis functionality, sadly. Not that hard to do, though. For your purposes, I’d recommend just creating a set of horizontal/vertical axes for WASD and another set for arrow keys, and then just check an in-game configuration flag to know which one to use in scripts.

In the example that I gave you, I used assignment operators in the if statements by accident. My bad… make sure you use ‘==’ instead of ‘=’ when comparing values in if statements.

That looks more or less in order. Where are your groundCheck variables getting their values? I assume you’re setting them in the inspector. Are they set to the transforms of two “socket” child objects?

I like that your character’s name is based in real language. When I don’t know what to name a monster for my game, I like to look up Latin, Greek, and Germanic roots for things that describe it, then mix them together until it sounds interesting.

Will the husky be in the game too?

1 Like

Hey, sorry for not replying. I have been working hard off the game and remaking the game from scratch thanks to Unity sporadically doing a memory wipe. Seriously, I was adding more world to Goupi’s life and bam. All animations disappeared, all scripts… everything but the sprite covers (land and Goupi)… (could have been windows 10, since have been having problems since. Worried a bit about reinstalling, but meh. want to finish one game… first.

So now, I decided to take a moment and make a final version of Goupi and better land graphics. This has resulted in me redesigning the world with the hiccup that when copying and pasting the hill that I am working on (to add to the mountain), the land tiles break up sporadically. I need to use Ctrl+V to keep them straight. And it’s slow now… dunno how to fix that, but pushing forward.

As for the Husky, I drew that because my gf likes Huskies. I am planning to make her create her own husky (to replace the one I drew) and create a story behind him/her. I’ll turn the husky into a game with it’s own storyline and eventually merge the stories. But need to focus on my first game first right?

As for all your help, I will be reviewing and applying them, and coming back with more questions, but for now, I need to get back to that spot.

I’m really sorry to hear that. A lot of us have been there… Glad to know you aren’t deterred.

I’m not really sure what’s going on with your tiles separating. Could try posting a .gif of the effect to see if anyone has anything to say.

I’m glad to help with anything I can. Make sure that if you come back to this thread, you tag me with @ ( @DragonFlamesMedia ) so I know you made a post, otherwise I might miss it altogether (that I saw this one was pure luck). You can send messages to my account any time, too. Godspeed!

…I’m gonna go back up my project.