The premise for my game is that it’s a sidescroller where the spherical character can be controlled in two ways - statically, with the left and right arrows, which moves the character at a fixed rate with no acceleration. The other way is to spin the character, where a lot more physics like friction and momentum get applied. On the ground, spinning won’t get you far because of the friction, but if you jump and build up spin speed in the air, you can get a burst of speed when you hit the ground and go faster than you could with static movement. I’d like the character to be able to act like a buzzsaw and adhere to walls and ceilings with enough spin, but I have no idea how to approach that so it’s not featured here!
Here’s my conundrum: I’m no good at programming, I came up with two drafts for the code to control this character on a simple, flat plane.
This is the first draft, where I wasn’t worried about efficiency and just wanted to get the concept running so I could visualize it and see if it’s fun.
//COUNTERCLOCKWISE
if (Input.GetKey(KeyCode.UpArrow))
{
if (GetComponent<Rigidbody2D>().IsTouching(ground)) //Set speed cap against ground
{
if (spinAnim["spin"].speed < 0.3f)
{
spinAnim["spin"].speed += 0.05f;
}
} else
{
if (spinAnim["spin"].speed < 2.0f)
{
spinAnim["spin"].speed += 0.1f;
}
}
}
else if (spinAnim["spin"].speed > 0.0f)
{
spinAnim["spin"].speed -= 0.1f;
if (spinAnim["spin"].speed < 0.0f)
{
spinAnim["spin"].speed = 0.0f;
}
}
//CLOCKWISE
if (Input.GetKey(KeyCode.DownArrow))
{
if (GetComponent<Rigidbody2D>().IsTouching(ground)) //Set speed cap against ground
{
if (spinAnim["spin"].speed > -0.3f)
{
spinAnim["spin"].speed -= 0.05f;
}
} else
{
if (spinAnim["spin"].speed > -2.0f)
{
spinAnim["spin"].speed -= 0.1f;
}
}
} // Deceleration
else if (spinAnim["spin"].speed < 0.0f)
{
spinAnim["spin"].speed += 0.1f;
if (spinAnim["spin"].speed > 0.0f)
{
spinAnim["spin"].speed = 0.0f;
}
}
Debug.Log(spinAnim["spin"].speed);
if (GetComponent<Rigidbody2D>().IsTouching(ground))
{
finalSpeed = (100 * spinAnim["spin"].speed * -1);
}
else
{
finalSpeed = 0;
}
// Apply all the added speed variables
rigidbody.velocity = new Vector2((100 * Input.GetAxis("Horizontal") + finalSpeed), rigidbody.velocity.y);
It’s not the entire code, but hopefully you get the idea. I knew it was ineffecient, having two very samey blocks of code just for left and right movement. I tried to streamline it more with this next iteration:
//Check if touching the ground
if (GetComponent<Rigidbody2D>().IsTouching(ground))
spinDrag = 0.3f;
else
spinDrag = 2.0f;
//Set speed
spinAnim["spin"].speed += ((spinDrag / 6.0f) * spinDir);
//Set speed cap
if (Mathf.Abs(spinAnim["spin"].speed) > spinDrag)
spinAnim["spin"].speed -= ((spinDrag / 6.0f) * spinDir);
//Deccelerate
if (Mathf.Abs(spinAnim["spin"].speed) > 0.0f)
{
//Make sure object won't start spinning in the other direction, then set the new speed
if (spinAnim["spin"].speed * (spinAnim["spin"].speed + (-0.01f * Mathf.Sign(spinAnim["spin"].speed))) >= 0)
{
spinAnim["spin"].speed += (-0.01f * Mathf.Sign(spinAnim["spin"].speed)); // Deccelerate according to entropy
groundSpeed = spinAnim["spin"].speed; // Use groundSpeed variable here to keep track of spin speed temporarily;
spinAnim["spin"].speed += (-0.1f * Input.GetAxisRaw("Horizontal")); // Deccelerate by input
// Make sure horizontal input can't reverse the spin animation
if (spinAnim["spin"].speed * groundSpeed < 0.0f)
spinAnim["spin"].speed = 0.0f;
if (Mathf.Abs(spinAnim["spin"].speed) > Mathf.Abs(groundSpeed))
spinAnim["spin"].speed = groundSpeed;
}
else
spinAnim["spin"].speed = 0.0f; // If it would start spinning in the other direction, set speed to 0
}
// Determine the final spin speed to be applied to the character, should only occur when on the ground
if (spinDrag == 0.3f)
spinSpeed = spinAnim["spin"].speed * 100 * -1;
// Set ground speed
groundSpeed = (75 * Input.GetAxisRaw("Horizontal"));
if (Mathf.Abs(groundSpeed) > 190)
groundSpeed = Mathf.Sign(groundSpeed) * 190;
if (Mathf.Abs(spinSpeed) > 190)
spinSpeed = Mathf.Sign(spinSpeed) * 190;
// Set speed based on strongest force
if (Mathf.Abs(groundSpeed) > Mathf.Abs(spinSpeed))
finalSpeed = groundSpeed;
else
finalSpeed = spinSpeed;
if (Mathf.Abs(finalSpeed) > 190)
finalSpeed = Mathf.Sign(finalSpeed) * 190;
Debug.Log(spinSpeed);
rigidbody.velocity = new Vector2(finalSpeed, rigidbody.velocity.y);
This code accomplishes the same purpose, with a few extras like being able to quickly diminish spin speed using static input. So, it’s not the EXACT same thing, but
Here’s what I want input on the most: is the style I coded in for the second iteration actually better? Not only is it a lot harder to read and took me much longer to write, but the way it uses all of those Mathf functions has me worried about it actually being heavier on CPU than the first iteration of code. Should I be opting for simpler, easier-to-read code like the first example? Thanks for anyone who chips in, there’s no need to examine the code super thoroughly or anything, I’d just like to know if the use of all these Mathf functions and the like is advisable.