Obstacle course corner issue

Hi, during experimenting with course and checking some options I found this issue. It’s seems like dependent from movement speed of cube. With lower values it dosen’t go throught walls. How should it be fixed?

It happens in all corners and looks like sliding on one collision, but missing 2nd one. On direct collision with any wall it works fine even on very much higher speeds.

1 Like

Hi Jaroski,

Welcome to our community! :slight_smile:

Good job on analysing the problem. You discovered one of the most important things to know about Unity: Unity’s physics simulation is highly optimised and cannot handle fast moving objects well. There are ways to improve the behaviour but since this is the first project in our course, Rick does not want to overwhelm his students with complexity.


If you want to challenge yourself, you could optimise your game a bit:

  1. Select all game objects with colliders that are not supposed to move. In their Inspector, tick “Static”. Do not do that for moving game objects, only for non-moving ones.

  2. This is the “difficult” part. Your goal is to make the physics simulation control your game object. You won’t manipulate the Transform values directly anymore (via the Translate method) but “communicate” with the Rigidbody, which gets used by the physics simulation.

    1. In your Mover class, create a new method named FixedUpdate. It’s a Unity method.
    2. Declare the xValue and yValue variables at the top of your code but without the [SerializeField] attribute.
    3. Remove the float keyword from the Update method. If you don’t remove it, you declare two variables here. What you actually want to do is to assign the values returned by GetAxis to the instance variables, which you declared in 2.2).
    4. Now look up the Rigidbody.AddRelativeForce method up in the API and read the example. Try to apply it. Test your game.
    5. Now go back to your code. Instead of a hard-coded Vector3 object, you create a new Vector3 object with the xValue and the yValue values. Pass on that Vector3 object to the AddRelativeForce method. Then test your game again. It might be that you made a little mistake but if you see it in your game, you will very likely know what went wrong.

Since structs have not been covered at this point, here is the pattern:
Vector3 velocity = new Vector3(x, y, z);

You would pass on velocity to AddRelativeForce by which I mean: Put the variable name into the parentheses.

x, y and z are just placeholders in my example. Replace them with your variables. One of the values is supposed to be 0f, which you may hardcode.

The solution will appear to be a bit circuitous but there is a reason for that: While you could get the user input in FixedUpdate, that’s not recommended because data could get “lost” as FixedUpdate does not get called “each frame”. You want to check the user input each frame. See the definition of GetAxis in the API.

Let me know how it worked. :slight_smile:


See also:

1 Like

I did as you said. For sure it’s different kind of movement - it’s more like acceleration. Speed accumulates untill it touch wall, or I use reverse velocity. It doesn’t stops untouched (It doesn’t use gravity).
When player touch walls it get’s immediately stopped. (Except crazy speed modifier values like 10k :wink: But I can understand it just doesn’t see small walls with velocity like (200, 0, 200) )

void FixedMovePlayer()
{
float xValue = Input.GetAxis(“Horizontal”);
float zValue = Input.GetAxis(“Vertical”);
Vector3 velocity = new Vector3(xValue, 0f, zValue);
Debug.Log("Vector3: " + velocity.ToString() + "\nObject velocity: " + GetComponent().velocity.ToString());

    GetComponent<Rigidbody>().AddRelativeForce(velocity * Time.deltaTime * moveSpeed);
}

I suppose there is no point in clearing this, probably Rick will make it better way during the course, isn’t he? :slight_smile:

Going back to the initial version:
Is there any way to fix this using Translate?
I can understand it could skip walls with big speed values, but these are like: speedX: 0,008698 speedZ: -0,008698 per update.
It makes throught the wall with scale (1,1, 21) - tried experimenting with bigger scale, player was able to get inside the wall.
I tried experimenting with wall’s Box Collision size from 1,1,1 to 2,1,2 and it still didn’t matter.

Or is it just “known issue” and it’s not recommended way?

Unfortunately, there isn’t unless you want to write your own physics engine. In that case, you wouldn’t want to use Unity anymore.

The problem is the following: The physics simulation controls the collisions and, ideally, also the movement of game objects. To allow the physics simulation to move a game object, you have to move the game object via the Rigidbody component. The simulation calculates stuff and overrides the Transform values.

If you use Transform.Translate, you override the Transform values directly without taking the physics simulation into consideration. That’s why you are able to move game objects into a wall and beyond. The physics simulation tried to push the game object out but since you override the values again, you basically undo the changes caused by the simulation.

Do you call FixedMovePlayer in FixedUpdate? If so, remove Time.deltaTime from that method. Then your game object should move smoothly.

And if there are still problems with the collision, you could increase the values in the Physics2D settings. However, this might have a negative impact on the performance of your game. For this reason, it is better to leave the values alone unless you were not able to find an alternative solution.

2 Likes

Just adding my two cents:

If you are still having issues with the collisions try setting the Rigidbody’s Collision Detection to Continuos in the inspector, that’s a little bit more demanding performance-wise, but it’s not too much of an issue when it’s just one object.

If you want to move the cube using the physics system in a way that matches the Translate method, try using the Rigidbody’s MovePosition method instead of adding a force, this will behave pretty much the same as Translate. Just be sure to use MovePosition and not position, since the latter will cause pretty much the same issue you are having with Translate.

Ok, thanks <3

I used FixedMovePlayer() inside Update() and FixedUpdate() independently.
In Update() it was faster. - Found quite good explaination I believe :slight_smile:
https://answers.unity.com/questions/1097715/why-dont-we-always-use-fixedupdate.html

Yes, it works the same way as Translate, even with the same speed issue. While Vector3 gets (1,0,1) and moveSpeed = 3 it’s fine, but with value of 4 it get’s too fast and walks throught the wall, even with Collision Detection set to Continuos.

GetComponent().MovePosition(transform.position + velocity * Time.deltaTime * moveSpeed);

On the other hand, it use physics :wink:

That should not happen, there’s something weird going on there, I’ll leave that up to you to experiment.

Are you using GetComponent every frame? That method is kinda slow, you don’t want to do that, cache it instead.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms