#How to stop rolling ball player from bouncing off slopes it rolls onto?

1 messages · Page 1 of 1 (latest)

iron mortar
#

I have a bouncy rolling ball player that can roll up slopes below a certain angle. It is prevented from automatically rolling down those slopes by changing the direction of gravity to point into the slope while the ball touches the slope. I want the ball to smoothly roll up these slopes, but currently (due to an attached PhysicsMaterial) the ball bounces off the steeper slopes it can roll up for a second when it first touches them (once it lands, the changed gravity kicks in and it rolls just fine). The bounciness of the player cannot be removed, since the ball still needs to bounce off the floor and walls, and so far I have been unable to satisfactorily imitate rebounding without a PhysicsMaterial.

I tried disabling the ball's bounciness on a collision-by-collison basis (using OnCollisionEnter()), but I found out that this was futile, since by the time a collision occurs, the colliding objects have already started bouncing. I also tried using a SphereCast to detect if the ball will hit a rollable slope on the next frame and, if so, disable the bounciness for that frame, but this had no effect.

What should I do to prevent the player from bouncing off these slopes in this way?

obtuse ermine
#

you´d have to post a video or something, kind of difficult to visualize

iron mortar
obtuse ermine
#

post it as a mp4 so it can be played here

iron mortar
obtuse ermine
#

you can drag drop the video directly here , no one want to download a file externally

crude thorn
#

TBH that bounce looks very katamari to me 😂

iron mortar
crude thorn
#

bit of a learning curve with that, but it can be very powerful.

iron mortar
#

Okay, after some time I thought I found a way to do what I wanted, but it seems to not be doing anything too? My function OnContactEvent() never seems to fire, and while GetRollableSlopesAhead() is definitely adding colliders to the list of colliders to nullify bounciness against, the list in question is always empty immediately after that function finishes...
Please let me know if any part of this code is too confusing to follow
https://paste.mod.gg/mcuwqbgqkqpz/0

crude thorn
#

Also I think you can't use a managed array in OnContactEvent nor references to Colliders

#

you need to use a NativeArray or NativeList and store the instance IDs not the collider references themselves

iron mortar
#

@crude thorn I implemented everything you suggested, but my code still doesn't prevent bouncing. Strangely, I'm pretty sure that it is adding IDs to the NativeList m_RollableSlopesAheadIDs, but for some reason by the time OnContactEvent() triggers the list is empty... Could you look at it again?
https://paste.mod.gg/eqqynmsvcbqz/0

crude thorn
#

wait also I'm not sure that contactPairs[i].SetBounciness(i, 0f); is going to do what you want. I think that's just equivalent more or less to using a physics material with bounciness 0

iron mortar
iron mortar
crude thorn
#

Are you familiar with vector projection?

iron mortar
iron mortar
#

@crude thorn I have spent a while implementing your proposed solution, but either your solution was not correct or (more likely) I have not properly implemented it
First off, the relevant code: https://paste.mod.gg/vjatbmiiirwb/0
The issue is that, not only does this code not prevent the initial bounce triggered by the player touching the slope, it only seems to trigger once the player has landed from that bounce onto the slope once more, where it then applies a force that appears to be perpendicular to the slope (based on tests where I increased the magnitude of the projected vector)
Would you mind looking over this once again?

crude thorn
# iron mortar <@179367739574583296> I have spent a while implementing your proposed solution, ...

instead of:

Vector3 currVel = m_KatamariRigidbody.linearVelocity;
for (int i = 0; i < contactPairs.Length; i++)
{
    int currCollID = contactPairs[i].otherColliderInstanceID;
    if (m_RollableSlopesAheadColliders.ContainsKey(currCollID))
    {
        contactPairs[i].SetTargetVelocity(i, Vector3.Project(currVel,
                                          m_RollableSlopesAheadNormals[currCollID]));
    }
}```
Can you try this:
```cs
Vector3 currVel = m_KatamariRigidbody.linearVelocity;
for (int i = 0; i < contactPairs.Length; i++)
{
    int currCollID = contactPairs[i].otherColliderInstanceID;
    if (m_RollableSlopesAheadColliders.ContainsKey(currCollID))
    {
        ModifiableContactPair pair = contactPairs[i];
        for (int contactIndex = 0; contactIndex < pair.contactCount; contactIndex++) {
          Vector3 targetVel = pair.GetTargetVelocity(contactIndex);
          pair.SetTargetVelocity(contactIndex, Vector3.Project(currVel, m_RollableSlopesAheadNormals[currCollID]));
        }
    }
}```