How to Move Rigidbody Gameobject

Proper way to move Rigidbody GameObject

You move Rigidbody with Rigidbody.MovePosition and rotate it with Rigidbody.MoveRotation if you want it to properly collide with Objects around it. Rigidbody should not be moved by their position, rotation or the Translate variables/function.

The "w" is not predefined like SherinBinu mentioned but that's not the only problem. If you define it and use KeyCode.W it still won't work. The object will move once and stop.

Change

Vector3 move = new Vector3(0, 0, 1) * speed;
rb.MovePosition(move);

to

tempVect = tempVect.normalized * speed * Time.deltaTime;
rb.MovePosition(transform.position + tempVect);

This should do it:

public float speed;
private Rigidbody rb;

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

public void Update()
{
bool w = Input.GetKey(KeyCode.W);

if (w)
{
Vector3 tempVect = new Vector3(0, 0, 1);
tempVect = tempVect.normalized * speed * Time.deltaTime;
rb.MovePosition(transform.position + tempVect);
}
}

Finally, I think you want to move your object with wasd key. If that's the case then use Input.GetAxisRaw or Input.GetAxis.

public void Update()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");

Vector3 tempVect = new Vector3(h, 0, v);
tempVect = tempVect.normalized * speed * Time.deltaTime;
rb.MovePosition(transform.position + tempVect);
}

Best way to move a game object in Unity 3D

RigidBodies and Velocities/Physics

The only time, I personally have used the rigidbodys system was when implementing my own boids (flocking behaviour) as you need to calculate a few separate vectors and apply them all to the unit.

   Rigidbody.MovePosition(m_Rigidbody.position + movement);

This calculates a movement vector towards a target for you using the physics system, so the object's velocity and movement can still be affected by drag, angular drag and so on.

This particular function is a wrapper around Rigidbody.AddForce I believe.

Pros :

  • Good if realistic physical reactions is something you are going for

Cons:

  • A bit unwieldy to use if all you are trying to achieve is moving a object from point A to point B.

    • Sometimes an errant setting set too high somewhere (for example: Mass > 10000000) can cause really screwy bugs in behaviour that can be quite a pain to pin down and mitigate.

Notes: Rigidbodies when colliding with another Rigidbody would bounce from each other depending on physics settings.

They are also affected by gravity. Basically they try to mimic real life objects but it can be sometimes difficult to tame the objects and make them do exactly what you want.

And Rigidbody.AddForce is basically the same as above except you calculate the vector yourself.

So for example to get a vector towards a target you would do

Vector3 target = target.position - myPosition;

Rigidbody.AddForce(target * 15 * Time.deltaTime, 0, 0, ForceMode.VelocityChange);

If you don't plan on having any major physics mechanics in your game, I would suggest moving by interpolating the objects position.

As it is far easier to get things to behave how you want, unless of course you are going for physical realism!

Interpolating the units position

Pros :

  • Perhaps a little strange to understand at first but far simpler to make objects move how you want

Cons:

  • If you wanted realistic reactions to objects impacting you'd have to do a lot of the work yourself. But sometimes this is preferable to using a physics system then trying, as I've said earlier to tame it.

You would use the technique in say a Pokemon game, you don't stop in Pokemon and wait for ash to stop skidding or hit a wall and bounce uncontrollably backwards.

This particular function is setting the objects position like teleporting but you can also use this to move the character smoothly to a position. I suggest looking up 'tweens' for smoothly interpolating between variables.

    //change the characters x by + 1 every tick, 
Transform.transform.position.x += 1f;

How to move rigidbody object up or down smoothly in unity3d

Your question is not really clear. Move smoothly could mean many things.

In general you should use RigidBody.MovePosition and Rigidbody.MoveRotation to set a Rigidbody's transforms instead of rb.rotation and rb.position in order to get "smooth" movements:

Use Rigidbody.MovePosition to move a Rigidbody, complying with the Rigidbody's interpolation setting.

If Rigidbody interpolation is enabled on the Rigidbody, calling Rigidbody.MovePosition results in a smooth transition between the two positions in any intermediate frames rendered. This should be used if you want to continuously move a rigidbody in each FixedUpdate.

Set Rigidbody.position instead, if you want to teleport a rigidbody from one position to another, with no intermediate positions being rendered.

So as you can see depending on your settings using Rigidbody.MovePosition might already result in a "smooth" movement.

rb.MovePosition(transform.position + Vector3.up * 2.0f);

Also you use Input.GetKeyDown so it works like a trigger ... it is not called continously like Input.GetKey

If you want to move continously while the key stays pressed use e.g.

// set e.g. in the inspector
public float verticalMoveSpeed;

// ...

if (Input.GetKey(KeyCode.UpArrow))
{
rb.MovePosition(transform.position + Vector3.up * verticalMoveSpeed * Time.deltaTime);
}

if (Input.GetKey(KeyCode.DownArrow))
{
rb.MovePosition(transform.position - Vector3.up * verticalMoveSpeed * Time.deltaTime);
}

If you want to trigger the movement only with GetKeyDown instead you could also do something like e.g.

// set e.g. in the inspector
public float verticalMoveSpeed;

// ...

if (Input.GetKeyDown(KeyCode.UpArrow))
{
StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
}

// ...

private IEnumerator MoveVertical(float distance, float speed)
{
var originalY = transform.position.y;
var targetY = originalY + distance;

var currentY = originalY;
do
{
rb.MovePosition(new Vector 3(transform.position.x, currentY, transform.positiom.z);

// Update currentY to the next Y position
currentY = Mathf.Clamp(currentY + speed * Time.deltaTime, originalY, targetY);
yield return null;
}
while(currentY < originalY);

// make sure you didn't move to much on Y
rb.MovePosition(new Vector3(transform.position.x, targetY, transform.position,z));
}

Than there are two options to prevent concurrent routines:

  1. use a flag. This also prevents the routine from beeing interrupted/called twice/called concurrent

    privtae bool isMovingVertical;

    // ...

    if (Input.GetKeyDown(KeyCode.UpArrow) && !isMovingVertical )
    {
    StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
    }
    else if (Input.GetKeyDown(KeyCode.DownArrow) && !isMovingVertical )
    {
    StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
    }

    // ...

    private IEnumerator MoveVertical(float distance, float speed)
    {
    isMovingVertical = true;

    // ...

    isMovingVertical = false;
    }
  2. use StopAllCoroutines to interrupt a running routine (attention this might lead to "infinite" moves in one direction - at least without you preventing it with additional checks)

    if (Input.GetKeyDown(KeyCode.UpArrow)) 
    {
    StopAllCoroutines();
    StartCoroutine(MoveVertical(2.0f, verticalMoveSpeed));
    }

    if (Input.GetKeyDown(KeyCode.DownArrow))
    {
    StopAllCoroutines();
    StartCoroutine(MoveVertical(-2.0f, verticalMoveSpeed));
    }

Unity: RigidBody2D, how to move GameObject in straight lines (no curves)

Unity has a built-in physics engine that calculates movement based on velocity (and collisions, etc.) By using Rigidbody2D.AddForce, you are adding to your rigidbody's velocity. This means that if you press the up arrow and then the right arrow, the velocity from pressing the up arrow remains, causing a diagonal velocity and curved path. If you want straight lines, you can use Rigidbody2D.velocity or just use Transform.translate.

_playerRB2D.velocity = movement * _speed;

Edit: You said that collisions were important, so keep the rigidbody

or remove the rigidbody2D component and use

transform.Translate(movement * _speed);

Is there a way to move a gameobject with a rigidbody

I figured it out. I added a image(UI) game object to an empty game object so it can move from 0 on the X and 0 on the Y axis. Added 3 transforms - 1 tilted to the left, 1 tilted to the right and 1 in the middle of the top of the screen to serve as guides in the game and then disabled them so they don't show up in the actual game. Attached a script to my Image UI gameobject and assigned the necessary transforms in the inspector and voila, it works.

using UnityEngine;
using UnityEngine.EventSystems;

public class MoveStick : MonoBehaviour, IDragHandler, IEndDragHandler {

public Transform leftTarget;
public Transform rightTarget;
public float rotateSpeed;

[Space]

Vector2 joyStartPosition;
public Transform stick;
public Transform topTarget;
public float speed;

bool goingUp;

void Start()
{
joyStartPosition = transform.position;
goingUp = false;
}

public void OnDrag(PointerEventData eventData)
{
transform.position = eventData.position;
if (transform.localPosition.y > 80f || transform.localPosition.x > 50 || transform.localPosition.x < -50)
{
goingUp = true;

var step = speed * Time.deltaTime;
stick.position = Vector3.MoveTowards(stick.position, topTarget.position, step);

Debug.Log("Going up: " + goingUp);
}
else if (transform.localPosition.y < 80f)
{
goingUp = false;
Debug.Log("Going up: " + goingUp);
}
if (transform.localPosition.x > 80 && transform.localPosition.y > 80)
{
stick.rotation = Quaternion.RotateTowards(stick.rotation, rightTarget.rotation, rotateSpeed * Time.deltaTime);
}
else if (transform.localPosition.x < -80 && transform.localPosition.y > 80)
{
stick.rotation = Quaternion.RotateTowards(stick.rotation, leftTarget.rotation, rotateSpeed * Time.deltaTime);
}
}

public void OnEndDrag(PointerEventData eventData)
{
transform.position = joyStartPosition;
eventData.position = joyStartPosition;
Debug.Log("Joystick is not moving");
goingUp = false;
}

}

There is still a lot to smooth and improve, however as a base code it works fine.



Related Topics



Leave a reply



Submit