My question is the same as the title. My player and enemies both move WAY faster when I build the game compared to when I play in the editor. I have looked online, but most forum pages say to multiply movement by Time.deltaTime, but for some reason, this doesn't work for me, because even when I re-build the game movement is way faster. If it helps, my character and enemies are both moved by Rigidbody2D.MovePosition. I think that I need to limit the framerate so that everything is slower, but I'm not sure. If you think I should, how would I go about doing that? Thanks in advance.
Both the enemies and player use this to move:
GetComponent<Rigidbody2D>().MovePosition(transform.position + move * speed * Time.deltaTime);
If it helps, "move" is a Vector3 coordinate and speed is set to 30 for the player character. I have clicked "build and run" every time after I made a change.
Is your code in FixedUpdate() or Update()? Physics code should be in FixedUpdate(). Note I changed Time.deltaTime to Time.fixedDeltaTime
void Update() {
//Your Non Physics Code
}
void FixedUpdate() {
//Your Physics code aka
GetComponent<Rigidbody2D>().MovePosition(transform.position + move * speed * Time.fixedDeltaTime);
}
Related
I'm currently working on a simple 2d jump and run game. I want to move my player with physics (using addforce).
In the editor, my player jumps at a normal height. But when i build the game it suddenly jumps way higher. I put everything in fixedUpdate() and don't know where the problem is?
//Movement
rb.velocity = new Vector2(horizontalMove, rb.velocity.y);
//Jump
if (jumpPressed)
{
if (isGrounded)
{
rb.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
anim.SetTrigger("takeOf");
}
}
Dan
If jumpPressed is true for every frame when the jump key is held, this could be the issue. This would mean that the code could act several times, reapplying the upwards force several times (before it goes far away enough from the ground that the ground check does not detect it). If this is the case, it can be fixed by:
rather than using AddForce, set the vertical velocity to the velocity of the jump.
changing the jumpPressed to only return true if jump was pressed this frame
Imposing a limit to how often you can jump (if you cannot jump twice within 0.1 seconds, that could fix the issue)
I have a ball in my demo game that has a bounce rate of 0.6. If the ball lands on a platform, of course it bounces. But the thing is, I actually tried to stick the ball to the platform.
When the ball collides with the surface of the platform, the speed of rigid body 2D becomes 0. But I guess because of the bounce rate, ball jumps a little bit and lands again in 0.02 seconds. Because of this, OnCollisionEnter2D runs for 2 times, which is something I don't want. Here is my code;
private void OnCollisionEnter2D(GameObject other) {
if(other.GameObject.tag == "platform") {
//Sets the rigidbody2D velocity as zero vector, angular drag and linear drag as 10f
game.SetBallVelocity(Vector2.zero, 10f, 10f)
}
}
How can I make OncollisionEnter2D only runs for single time? In another word, let the Ball really stick at the first time?
I don't have enough information to give you the exact answer but one of those should fix the problem:
1: Changing collision mode on the ball's rigidbody (test both Discrete and Continuous)
2: OnCollisionEnter2D is called before the physics calculations that change the ball's velocity, so use OnCollisionExit2D()
Quick side note, your IDE should have warned you of this but other.gameobject.CompareTag("platform") is faster than directly comparing the strings (other.GameObject.tag == "platform")
I am using Unity3D to make a replica of the game "Rolling Sky" which you can find on the Google/Apple app store. I was able to make a simple floor which the ball will move on and I was also able to make the ball (Player) move left and right. After moving the ball a couple of times back and fourth, it starts float in the air and eventually what it seems like is change it's axis.
I came up with a couple of alternatives that I think would work, but I had trouble coming up with the code to make it function properly.
1) Do not rotate the ball at all. Just have it smoothly move back and forth.
^^ Probably the best solution I could come up with.
or
2) Use CharacterController to have complete control of how the ball reacts to different events, scenarios, etc.
^^ This would probably be the most necessary and hardest of I had to guess.
or
3) Move the ball an x amount of pixels everytime I move left or right.
^^ I would assume this would create a lot more glitches than what I have right now.
public class PlayerController : MonoBehaviour
{
public float speed;
void Update()
{
transform.Translate(Vector3.right * speed * Input.GetAxis("Horizontal") * Time.deltaTime);
}
}
EDIT:
I was able to provide my own answer, but if anyone has any alternatives, feel free to post your solution!
To prevent the player ball from floating into the sky, no other code was needed. Simply go to the Rigidbody component on the Player and expand the "Constraints" menu. Next, check the axis boxes that you would like to freeze the rotation on to prevent the ball from spinning like so in the picture.
Click the link to see the picture
here.
In this case, I did not freeze the ball on the x axis because I eventually want to animate it to spin as if it is rolling forward.
You're using transform.Translate
and
You're using Vector3.right
transform.Translate will directly move the ball without thought of rotation. You will need to take the object's rotation into consideration when translating. You can also use the physics engine and use Rigidbody.MovePosition to force position or Rigidbody.AddForce to utilize physics interactions.
Vector3.right will use the constant value equivalent to Vector3(1, 0, 0). This will not be in regard to the object's rotation or facing.
I suggest looking through Unity's tutorial for a ball-roller and see how they complete the task of user input with a user controlled ball.
I am working on a 2D Platform game, and i realized that the player's jumping function doesn't work the same way every time, for example. The jumping height is different if the player jumps while moving/running or if the player jumps without moving.
I have 2 separated functions Move() and Jump(), Move() uses transform.Translate to make the player move, and Jump() uses rigidBody.AddForce() to make the player jump. I've already tried to change the player Move() function to use rigidBodies to make the player move instead of using transform.Translate(). And it didn't worked.
I've also tried make the player jump using transform.Translate, which solved the inconsistent jumping height problem, but the player just teleports up instead of jumping
this is a representation of my code structure, not the actual code, because the actual code is like 600 lines
public class Player
{
float JumpSpeed;
bool isGrounded;
void Update()
{
if (Input.GetKey(KeyCode.A))
Move(Directions.Left);
if (Input.GetKey(KeyCode.D))
Move(Directions.Right);
if (Input.GetKeyDown(KeyCode.Space))
Jump(JumpSpeed);
}
public void Move(Directions dir)
{
Vector2 speed;
//figure out speed and etc...
//makes the player move in the right direction and speed
transform.Translate(speed * Time.deltaTime);
}
public void Jump(float speed)
{
if(isGrounded)
rigidBody.AddForce(new Vector2(0, speed * Time.deltaTime), ForceMode2D.Impulse);
}
}
Not sure if this is specifically your issue, but using translate to move the player and then adding force to jump isn't really the best way to approach the problem.
I would look into using the velocity part of the rigidbody for both the jump and the movement. This would prevent any weirdness that Translating the object could cause.
I'm still learning the basics so please be a bit gentle. I'm working on the movement script of a roll-a-ball game. I've got the rolling around working perfectly fine, but now I'm trying to add the ability to jump.
In my case the "player" is a basic Sphere. What I'm trying to accomplish is that when space is pressed, the ball leaps into the air in the direction it's currently rolling.
This is what I've tried myself, but gave very strange results:
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
if (Input.GetKey("space"))
{
transform.position += transform.up * 20 * Time.deltaTime;
}
rb.AddForce(movement * speed); //rb = RigidBody
This resulted in the ball sometimes jumping in the wrong direction or simply just speeding into some direction without jumping at all. So obviously I'm getting closer, but not quite there yet. Could anyone explain what I'm doing wrong and how to fix it?
Not looking for a quick fix! Don't learn anything from that.
Have a try at this :)
if (Input.GetKey("space"))
{
rigidbody.AddForce(new Vector3(0, yourJumpForce, 0), ForceMode.Impulse);
}
You also might want to fiddle with the gravity settings in the rigidbody to get your desired jump as well!
EDIT Explanation:
I think it may be because you are applying you movement to your Rigidbody, but your jumping method to the Transform itself.
A Rigidbody is a physics component (see docs.unity3d.com/ScriptReference/Rigidbody.html), where a Transform is to do with position, rotation and scale.
A jump could be considered a physics problem - therefore altering the jump is to do with physics (Rigidbody), not the position (Transform). I tend to do all movement code with the Transform, as you are moving positions, and do all physics based work with the Rigidbody, as you are applying physics to the GameObject! :)
To add to the accepted answer: The jumping into random directions issue could have been caused by the transform.up. That vector is the up direction relative to your current transform. That's usually the same as the actual up direction, except if you rotate the game object. And as the object happens to be a rolling ball in this case, it's very likely that it's rotated.
You can fix it by using the global up direction instead - either by doing it like in the accepted answer or by using Vector3.up.