How to move a rigidbody object like Crossy Road?

Hi,
I’m making a kind of CrossyRoad game for android.

I’d like to move a player with rigidbody for the reason of collision.
I’m currently using rigidbody.velocity, but it turns not fixed amount movement.

It moves 5 units forward once, then moves 3.33 units, then 8.43 …so on.

(What I want to achieve)
Move the player 5 units away when I tap a screen once. I need the player to work with collision.

I wonder if this is a problem with rigidbody.velocity or Input method is wrong.

I’d really appreciate any help!

private int leftRight;
private int upDown;

void Update(){
        leftRight =0;
        upDown=0;

#if UNITY_STANDALONE|| UNITY_WEBPLAYER
        leftRight = (int)(Input.GetAxisRaw("Horizontal"));
        upDown = (int)(Input.GetAxisRaw("Vertical"));

#elif UNITY_IOS || UNITY_ANDROID || UNITY_WP8 || UNITY_IPHONE
        if(Input.touchCount > 0){
            //touch on screen
            if(Input.GetTouch(0).phase == TouchPhase.Began){
                firstTouch = Input.GetTouch(0).position;
            }

            // release touch/dragging
            else if(Input.GetTouch(0).phase == TouchPhase.Ended && firstTouch.x>=0|| Input.GetTouch(0).phase == TouchPhase.Canceled){

                Vector2 touchEnd = Input.GetTouch(0).position;
                x = touchEnd.x -firstTouch.x;
                y = touchEnd.y -firstTouch.y;
                firstTouch.x =-1;

                    //drag just too little / just a click
                if(Mathf.Abs(x) <swipeLength && Mathf.Abs(y) <swipeLength)
                        upDown =1;

                    //drag left or right
                else if(Mathf.Abs(x) >=swipeLength || Mathf.Abs(y) >= swipeLength ){

                        if(Mathf.Abs(x)>Mathf.Abs(y))
                            leftRight = x>0?1:-1;
                        else
                            upDown = y>0?1:-1;
                }
               
            }
        }
#endif
    }

    void FixedUpdate(){

        if(leftRight !=0 || upDown !=0){
            Move(leftRight,upDown);
        }
        else if(leftRight ==0 && upDown ==0 )
            anim.SetBool("Idle",true); 
    }

    void Move(int leftRight,int upDown){
        ridbody.velocity = new Vector3(leftRight,0,upDown)*200;

I wouldn’t bother with a ridgidbody body for movement. Maybe for collision detection. I would just move the position forward a set amount and animate the transition.

3 Likes

The vertical motion doesn’t have to be part of physics. You could parent that chicken to a cube and slide the cube around. Just make the chicken jump with an animation. Remember it just has to look right to a player, however you get there all up to you.

I don’t use physics for most things because it has an element of randomness… but keep that in mind, you may need that randomness one day.

Anyway, I have always created a per update or per step Movement variable that gets added to the position per each update, all you do is simulate a slowdown by bringing that movement amount to zero slowly over time. You can also set how fast it slows down with another variable, like friction. Why this is good… well it always seems to work perfectly. Never failed me.

Almost forgot make sure you multiply that motion by Time.deltaTime so it works on different frame rates.

Good luck

1 Like

IIRC Crossy Road is a grid(?) They probably don’t use physics.

1 Like

True! You could lerp that position.

You could just use root motion in an animation the moves a constant distance.

I’ve got an interview with Matt Hall and Andy Sum for a job tomorrow. I could always ask them how they did it.

1 Like

Good luck! Let us know how it goes

1 Like

Good luck!

1 Like

So, are you saying that you would use transform.translate then attach ridgidbody for collision?
I did it before, but the collision’s detection messed up with transform.tranlate or other non-physics movement.
Did I miss something??

If moving the transform directly is giving you collision detection issues try using Rigidbody.Move.

Thank you for good explanation!
Yeah…I don’t need physics either.
I use rigidbody only for the collision sake. I messed with it when I used transform.translate/transform.position etc.

I’m trying to understand your method well.
I don’t know if I get it right though…

How do you detect collision by this?Raycast?
I want my player to bang trees and enemies( well, I have enemies instead of trains).

Just fyi modifying the transform directly bypasses physics for a moment, then the physics try to catch up and objects push away from each other as if they had hit each other harder than they did. You have to move the rigidbody using physics if you want it to work right.

Yeah…I don’t mean to use physics , but I need collision.
How do you not mess with collision without rigidbody?

What I would do is make it so the object moves exactly the right amount per swipe. You can raycast out one jump distance to see if something is there. If not, jump. Only do this for the environment. The actual animation part is not important for moving in the environment and interacting with walls. So, it is arbitrary as far as moving the chicken. You can use Lerp to move him between last position and next position. Disable swipes until current position = next position. Cars and other things can be handled without physics as well. Use triggers. When he hits a car, arrest his motion and parent him to the car. On and on, no need for physics.

Physics is expensive and for use when you need to simulate physics. Crowd simulation, is a big one. Sports games. Just think of physics as being there for when you need realism.

You can make cross road easily without the physics engine.

Also, I would make it so he falls if there is no ground below him via raycasting, this way you can easily implement ditches and water. All you have to do is tag the logs as ground.

Also, for the ground, raycast from all four corners, there may be a boxcast or sweeptest method but I never needed it so I never used it. Figures.

Physics can really mess up a simple game, you need to be pretty good to use physics without “weird stuff” happening.

Night, good luck.

Wow!!! I’m counting on you!! Good luck :smile:

Actually I succeed to move the player by same amounts per an input( tap) last night.
What I did is just move the method of Update to FixedUpdate.
I wonder if my input will slow down by this solution.

I’m a little bit confused here:(
English is my second language, and I’m a beginner in programming.
Please be patient with me if I say something idiot!

Do I understand you correctly?

1)No physics needed in this game.
2)Move the player position directly by Lerp.
3)Detect obstacles via Raycasting.
4)Use trigger to detect if enemies hit.

I still need a rigidbody to deal with trigger right?
So, I should set all rigidbody as kinematic, then move their transform directly.

What do you mean by this?
I thought you were saying that I don’t need to move rigidbody but transform.position with Lerp.

I will try your method!
Thank you for helping me;)

There are two ways of doing it:
1 - using Rigidbodies and physics. You can’t move transform.position because it can mess with the physics. You’ll need to use Rigidbody.MovePosition instead.
2 - Not using Rigidbodies or physics at all - just Colliders. Here you would move transform.position, but you’d use Raycast to detect if there are any other colliders in your path before you move.

I’d personally go for option 2. Example of using Raycast: http://www.theappguruz.com/blog/collision-detection-without-rigid-body-in-unity

If you keep everything to 1 grid then you can move exact by using vector3.forward etc. I used that for a snake game to move the segments then put a time delay in between each movement so it slowed down enough to look smooth.

Yes, for two objects to register Trigger events, both need Colliders, at least one of the two must have a Rigidbody and at least one of the two must have their Collider set to IsTrigger. Yes, IsKinematic is what you want.

I was just telling you why non-kinematic Rigidbodies don’t like it when you set their transform directly, since you had encountered it but I figured you might want to know why as well*.*