0

I'm working on a 2d game in unity with a very limited knowledge about this game engine. So I'm working with 2d effectors and noticed a weird behavior from my character. I tried changing the movement script and it worked! Nonetheless, the movement script that I used is bad and results in a lot of other problems. This is the script that I have been working with since I started

horizontal = Input.GetAxis("Horizontal");
transform.position += new Vector3(horizontal, 0, 0) * Time.fixedDeltaTime * speed; 

Can someone provide me with a fairly simple script that works well with 2d physics. the Time.fixedDeltaTime is pretty crucial as my hardware is weak and the game works poorly without it.

2
  • Please provide more information, like what weird behaviour & what other problems your script results in. Commented Jul 5, 2023 at 18:54
  • My hardware exceeds pretty much the unity recommended requirement the problem might not be on my hardware sorry. I thought running unity usually needs super strong hardware. So, basically the problem is when the character is walking sometime it stops I keep pressing the arrow button the player plays his animation but he is not moving my horizontal variable works fine. It happens in random places sometimes i walk normally in a place but return to it see this problem. if i jump and then return to the same place the problem happens. but this problem does not happen with script that do not use rb Commented Jul 6, 2023 at 10:52

3 Answers 3

0

Depends on a lot of things, but here is something that will make a character go left and right and interract with physics:

Rigidbody2D rb;

void Start() {
   rb = GetComponent<Rigidbody2D>();
}

void Update() {
  var x = Input.GetAxis("Horizontal") * speed;
  rb.velocity = new Vector2(x, _rb.velocity.y);
}
Sign up to request clarification or add additional context in comments.

4 Comments

This script does not work well with weak hardware like mine. There is this problem where the character stops moving but keeps running the animation like there is an invisible wall in front of it while if it jumps and return to the same spot it works fine. the Time.fixedDeltaTime solves this problem. I hope this conditions does not need a super complexe script but if they do let me know.
What are your hardware specifications?
My hardware exceeds pretty much the unity recommended requirement the problem might not be on my hardware sorry. I thought running unity usually needs super strong hardware. So, basically the problem is when the character is walking sometime it stops I keep pressing the arrow button the player plays his animation but he is not moving my horizontal variable works fine. It happens in random places sometimes i walk normally in a place but return to it see this problem. if i jump and then return to the same place the problem happens. but this problem does not happen with script that do not use rb;
I'm guessing the collider gets stuck on things. The transform.position = way of moving can be seen as teleporting the character each frame, and doesn't really play with physics (you will sometimes teleport inside a collider and be pushed out though, which is why it is working probably. Dont think it has too much with deltaTime to do, all that does is apply a 0.017 modifier or thereabout to the math). Perhaps the best way to solve it is to review your flooring, and remove the edges that stops the player. Or make the collider shape have softer edges :D
0

Hi there is the code below can do more than what u need and its a good start.

here is the source Link

Lemme know if you need more information.

using UnityEngine;
using UnityEngine.Events;

public class CharacterController2D : MonoBehaviour
{
    private float m_JumpForce = 400f;                          // Amount of force added when the player jumps.
    [Range(0, .3f)] private float m_MovementSmoothing = .05f;  // How much to smooth out the movement
    private bool m_AirControl = false;                         // Whether or not a player can steer while jumping;
     private LayerMask m_WhatIsGround;                          // A mask determining what is ground to the character
     private Transform m_GroundCheck;                           // A position marking where to check if the player is grounded.
     private Transform m_CeilingCheck;                          // A position marking where to check for ceilings`

    const float k_GroundedRadius = .2f; // Radius of the overlap circle to determine if grounded
    private bool m_Grounded;            // Whether or not the player is grounded.
    const float k_CeilingRadius = .2f; // Radius of the overlap circle to determine if the player can stand up
    private Rigidbody2D m_Rigidbody2D;
    private bool m_FacingRight = true;  // For determining which way the player is currently facing.
    private Vector3 m_Velocity = Vector3.zero;

    [Header("Events")]
    [Space]

    public UnityEvent OnLandEvent;

    [System.Serializable]
    public class BoolEvent : UnityEvent<bool> { }


    private void Awake()
    {
        m_Rigidbody2D = GetComponent<Rigidbody2D>();

        if (OnLandEvent == null)
            OnLandEvent = new UnityEvent();
    }

    private void FixedUpdate()
    {
        bool wasGrounded = m_Grounded;
        m_Grounded = false;

        // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
        // This can be done using layers instead but Sample Assets will not overwrite your project settings.
        Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)
            {
                m_Grounded = true;
                if (!wasGrounded)
                    OnLandEvent.Invoke();
            }
        }
    }


    public void Move(float move, bool jump)
    {

        //only control the player if grounded or airControl is turned on
        if (m_Grounded || m_AirControl)
        {


            // Move the character by finding the target velocity
            Vector3 targetVelocity = new Vector2(move * 10f, m_Rigidbody2D.velocity.y);
            // And then smoothing it out and applying it to the character
            m_Rigidbody2D.velocity = Vector3.SmoothDamp(m_Rigidbody2D.velocity, targetVelocity, ref m_Velocity, m_MovementSmoothing);

            // If the input is moving the player right and the player is facing left...
            if (move > 0 && !m_FacingRight)
            {
                // ... flip the player.
                Flip();
            }
            // Otherwise if the input is moving the player left and the player is facing right...
            else if (move < 0 && m_FacingRight)
            {
                // ... flip the player.
                Flip();
            }
        }
        // If the player should jump...
        if (m_Grounded && jump)
        {
            // Add a vertical force to the player.
            m_Grounded = false;
            m_Rigidbody2D.AddForce(new Vector2(0f, m_JumpForce));
        }
    }


    private void Flip()
    {
        // Switch the way the player is labelled as facing.
        m_FacingRight = !m_FacingRight;

        // Multiply the player's x local scale by -1.
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

how about this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public CharacterController2D controller;

    public float runSpeed = 40f;

    float horizontalMove = 0f;
    bool jump = false;

    // Update is called once per frame
    void Update()
    {
        horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;

        if (Input.GetButtonDown("Jump"))
        {
            jump = true;
        }
    }

    void FixedUpdate()
    {
        // Move our character
        controller.Move(horizontalMove * Time.fixedDeltaTime, jump);
        jump = false;
    }
}

11 Comments

Thanks for you help! the script seems pretty complicated. I'm still a beginner in unity and I don't love it when i write scripts i don't understand. Are there any alternative options or I have to write these long scripts to get good results
I have added another short script. sorry for formatting stackoverflow is not recognizing unitys lib sometimes.
and here is an other one: private float speed = 2.0f; public GameObject character; void Update () { if (Input.GetKey(KeyCode.RightArrow)){ transform.position += Vector3.right * speed * Time.deltaTime; } if (Input.GetKey(KeyCode.LeftArrow)){ transform.position += Vector3.left* speed * Time.deltaTime; } if (Input.GetKey(KeyCode.UpArrow)){ transform.position += Vector3.forward * speed * Time.deltaTime; } if (Input.GetKey(KeyCode.DownArrow)){ transform.position += Vector3.back* speed * Time.deltaTime; } }
Can you add the script in the answer?
This script does not work welll with effectors too. Btw my game is not top down the player can only move right left and jump
|
0

my simplest way is:

 float vertical = Input.GetAxis("Vertical");        
   transform.Translate(vertical * Vector3.forward * speed * Time.deltaTime);

   float horizontal = Input.GetAxis("Horizontal");        
   transform.Translate(horizontal * Vector3.right * speed * Time.deltaTime);

speed is a variable created with an int.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.