How To Make Objects Move With Fluid Movement

Hey guys,

I am building a project that requires enemies to move in a fluid motion.

They should be able to move in any direction, up, down, diagonal up left, diagonald down left,etc.

The enemies need to move in fluid motion.

Right now I have an AI script that moves the fish in any direction but the movement is somewhat choppy when the enemy decides to change directions. I want it to operate somewhat as a AI would. The enemies can wander anywhere they please. The only restrictions are walls.

This is also a physics based game. Not sure if the plug-in i’ve listed below moves physic items. I heard it is not good to move objects by transform when using physics.

Anyone know of any good AI plug-ins I can use for this?

It is 2D by the way. Right now I am looking into this plug-in: any thoughts?

Please let me know your thoughts or if you have any other recommendations on options or plug-ins you have tried.

Thanks!

If your game is using Physics, then move your enemies using AddForce within FixedUpdate, and give their rigidbodies a linear drag value. That will give them smooth movement.

The issue is. I want to have a smooth transition between the first velocity of the object and the second. For example, I initially set the first velocity and it moves then a few seconds later I make the object move in a diagonally path by changing its x and y velocity. The issue is. The movement is somewhat chopoy when I switch velocities and a choppy jerk when the velocity suddenly changes. I would like to make it look more fluid and natural by making it gradually change velocity on x and y until it reaches it’s full velocity that was set by me. Until it changes again and then rinse repeat.

That is exactly what AddForce will give you. Put this on an object, set the acceleration and deceleration in the inspector and move it with WASD:

In your game instead of using Input Axes, use your AI direction vector as the “input” vector.

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class PhysicsMovement : MonoBehaviour {

    public float acceleration;
    public float deceleration;

    private Rigidbody2D physics;
    private Vector2 input;

    public void Start() {
        physics = GetComponent<Rigidbody2D>();
        physics.gravityScale = 0;
        physics.drag = deceleration;
    }

    public void Update() {
        input.x = Input.GetAxis("Horizontal");
        input.y = Input.GetAxis("Vertical"));
    }

    public void FixedUpdate() {
        physics.AddForce(input * acceleration * Time.deltaTime, ForceMode2D.Impulse);
    }
}

Ah I see. But how do I know how much force to apply at a body to move in in a certain direction? Since the force will be applied randomly.

If you have the direction vector, then you can do “direction * speed” to get the force needed to move in that direction. I did that in the example class, using “input” as my direction vector.

If your direction vector isn’t normalized (vector length of 1), or you’re not sure, use the “.normalized” property on the vector when using it as a direction, this will make sure the vector length will equal 1, and won’t mess with your speed value when you multiply. (see below for syntax)

If you want to find a random direction, you can use “UnityEngine.Random.insideUnitCircle”, which will give you a random normalized Vector2 (length of 1) to use as a direction.

Here’s the same example class which gets a random direction to move in at the start:

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class PhysicsMovement : MonoBehaviour {

    public float acceleration;
    public float deceleration;

    private Rigidbody2D physics;
    private Vector2 direction;

    private void Start() {
        physics = GetComponent<Rigidbody2D>();
        physics.gravityScale = 0;
        physics.drag = deceleration;

        direction = UnityEngine.Random.insideUnitCircle;
    }

    private void FixedUpdate() {
        Vector2 directionalForce = direction * acceleration;
        physics.AddForce(directionalForce * Time.deltaTime, ForceMode2D.Impulse);
    }
}

If you want the object to move towards another object, you can get that movement direction by doing:

(otherObjectPosition - thisObjectPosition).normalized

and using that vector in your “direction * speed” calculation.

So with that you should be able to see how you can either move randomly, or move towards a checkpoint or target of sorts.

Also just a tip, you can use these shorthands to get normalized cardinal directions:
Vector2.right, Vector2.left, Vector2.up, Vector2.down.

These are equivalent to Vector2(1,0), Vector2(-1,0), Vector2(0,1), Vector2(0,-1), respectively.

Awesome. So now how would I rotate the object to move in the direction that was randomly selected form the unity circle. how do I go about getting the angle the object is moving in, in order to make the object face that angle?

If you want to rotate the object so that its X Axis points in the direction of movement, you can do something like this:

 private void LateUpdate () {
    // get a rotation that points Z axis forward, and the Y axis in the movement direction
    Quaternion newRotation = Quaternion.LookRotation(Vector3.forward, movementDirection);

    // apply new rotation
    transform.rotation = newRotation;

    // rotate 90 degrees around the Z axis to point X axis instead of Y
    transform.Rotate(0, 0, 90);
}

The reason for the extra rotation is that “LookRotation” takes parameters for Z axis and Y axis for 3D orientation, but for 2D we need Z axis and X axis, so rotating an additional 90 degrees will offset the result to work for 2D.