Rotation based on velocity (Hungry Shark like)

Hello, I’m new to unity and I’m working on an “Hungry Shark” like game (3d word but action is focused on a certain Z axis, it’s like 2D gameplay inside a 3D world)

So I can get my character to move in the right direction, but I would like to rotate while moving, to get a realistic and smooth movement as in Hungry Shark.

Here you get a video showing the game I’m talking about, so you can see how my character should move:

Until now I can’t get it, the shark’s rotations are everything’s but realistic and I have tried everything I found on this forum or google without success.

void FixedUpdate ()
        {

                float moveHorizontal = Input.GetAxis ("Horizontal");
                float moveVertical = Input.GetAxis ("Vertical");

        Debug.Log (moveHorizontal + " || " + moveVertical);

                if (moveHorizontal != 0 || moveVertical != 0) {
                        float rotHorizontal = -moveHorizontal;
                        float rotVertical = -moveVertical;

            Vector3 rot = new Vector3 (rotHorizontal, rotHorizontal, 0f);
                        Vector3 movement = new Vector3 (moveHorizontal, moveVertical, 0.0f);
                        rigidbody.velocity = movement * speed;
      
                        rigidbody.position = new Vector3
                      (
                rigidbody.position.x,
                rigidbody.position.y,
                1.0f
                        );

                        Quaternion rotation = new Quaternion ();
                        rotation.SetLookRotation (rot, Vector3.down);
                        transform.localRotation = rotation;
                }
        }

I hope someone knows how to do it, thank you in advance.

Ok so just to clarify things what I am looking for is a 2.5D swim simulation.

Hi madragons,

Well I’m not a “rotations” expert but I’ll throw some code at you and maybe it will help, who knows.

One of the first things I see in your code is that there is no multiplication by “Time.deltaTime”. In my experience, if you want “smooth” rotation, you need to multiply your rotation by “Time.deltaTime” somewhere. I’m not sure if the “SetLookRotation” function does this inherently or not. This will make sure your character rotates “frame independently”, so that you get smoother behavior.

Here is code that I use a lot in my game to smoothly rotate a character to face a certain position. Granted, first you have to get the exact position you want your object to rotate towards (you might have to do this every Update). But once I have a position, I use this code:

_direction = Vector3(yourTarget.transform.position.x - thisTransform.position.x, 0, yourTarget.transform.position.z - thisTransform.position.z).normalized;
             
                     
if ( _direction != Vector3.zero) {
    _lookRotation = Quaternion.LookRotation(_direction);
}
             
thisTransform.rotation = Quaternion.Slerp(thisTransform.rotation, _lookRotation, Time.deltaTime * RotationSpeed);

Where “_direction” is a Vector3 position, “_lookRotation” is a Quaternion, and “RotationSpeed” is a Float. “thisTransform” is a reference to the transform component the script is attached to. You might also have to change “z” to “y” for your game, but I’m not sure (on the position).

You might also try using your rotation code in the “Update” function, instead of the “FixedUpdate”, as FixedUpdate runs slower, and so I think your rotation will be choppier just because of that alone.

Cheers.

Sorry, just noticed you are using C#, but maybe you can get the gist of my Unityscript code. If not, I can adjust to C# real quick maybe.

Hey, thank you for answering my topic, I ll give this a try and let you know immediatly.

So I am not sure to understand well what the code is doing but that’s what I ve actualy in my update function:

void Update()
    {
        float moveHorizontal = CFInput.GetAxis("Horizontal");
        float moveVertical = CFInput.GetAxis("Vertical");
   
        Vector3 movement = new Vector3(moveHorizontal, moveVertical, 0.0f);
        Quaternion _lookRotation = new Quaternion();
   
        rigidbody.velocity = movement * speed;
   
        rigidbody.position = new Vector3 (
            rigidbody.position.x,
            rigidbody.position.y,
            1.0f
        );
        Vector3 direction = new Vector3(rigidbody.position.x - movement.x, rigidbody.position.y - movement.y, 0f);
   
        if ( direction != Vector3.zero) {
            _lookRotation = Quaternion.LookRotation(rigidbody.position);
        }
   
        transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * 8);
    }

The shark is moving but there are no rotation at all so I guess I am doing something wrong.

As I told in my first post I’m new to unity and a bit confused with position and rotation.[/code]

Hey madragons,

Sorry to hear it didn’t work first time, but no problem I’m sure you will get it eventually. It looks like you have two things going on that are kind of “jumbled” together in your code. Unfortunately, I’m a little confused myself without knowing how you set up your gameobjects, scripts, etc…

I think the biggest problem is that somehow we need to know how the “input” is working. And quite honestly, I don’t work with “GetAxis” a whole lot. Maybe someone else knows how the input works though.

It looks to me like that code you just posted actually rotates the shark to face where the shark is already facing. Like you’re rotating it to face the position it’s at currently already, instead of a different position on Update, but again that seems to be based on the GetAxis code. If there was a way to get where the player inputs before rotating, then I think the code I gave you would work.

I’ll have to think about it some more though. Maybe someone else can help you in the meantime.

But, don’t give up. If you keep working on it, I’m sure you’ll get it!

Thank you for the support anyway and I ll keep searching, don’t worry I won’t give up, and once I figured out how to do it I’ll let you know in this thread. Once more thank you for your time :slight_smile:

Okay, I looked at the script reference, and maybe this is what you are looking for?

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public float speed = 10.0F;
    public float rotationSpeed = 100.0F;
    void Update() {
        float translation = Input.GetAxis("Vertical") * speed;
        float rotation = Input.GetAxis("Horizontal") * rotationSpeed;
        translation *= Time.deltaTime;
        rotation *= Time.deltaTime;
        transform.Translate(0, 0, translation);
        transform.Rotate(0, rotation, 0);
    }
}

But this looks like it rotates based on “Horizontal” input only. So to fit your needs it would have to be modified.

Thanks, I’ll try this one and let you know if I can get it to work.

With this code the shark is not rotating at all, I’ll make a few other trys

Do you have a “Character controller” on your shark? If so, disable it or get rid of it for now.

But here is also something to try:

Comment out or get rid of all of your rigidbody and “movement” code for now and try only working with the transform (and the script reference code). I think the rigidbody stuff is making it too complicated, and I don’t think you need it right now. Leave the rigidbody script/component on your shark, but don’t code anything for it or with it. Work only with the transform.

Then, use that code from the script reference on your shark and see what it does. If you already did this, and it doesn’t rotate, try putting the “rotation” variable in different axes. So, something like this:

//Original line.
transform.Rotate(0, rotation, 0);

//Try this instead
transform.Rotate(0, 0, rotation);

//Or this
transform.Rotate(rotation, 0, 0);

Also, if the movement isn’t working, try putting the “translation” variables on different axes, just like the rotation.

Observe the behavior, if there is any.

Otherwise, I’d say keep working on it yourself and get help from someone besides me, because I’m obviously not making it work for you :slight_smile:

Good luck!

Hey, I ll give this a try soon.
At the moment I have found a person helping me via teamviewer, and if any succeed, I’ll let you know.

One more thank to you.