So i´m currently making a ball rolling game which is like a platformer.
But after i´ve added some rotated/tilted floor objects the ball bumps when going down the floor rather than stick to it the whole way.
So how would i make my object glue to the floor objects but still be able to move on it?
I dont necessarily ask for a complete script, but i know there must be a keyword to this!
This is what my maps look like:
In this map it bumps a lot when going down the hill so it cant jump properly because it needs to interract with the ground to do so. Screenshot - da7b5c3240356fadedcf88eb29d72f72 - Gyazo
#pragma strict
var jumpHeight = 0.02;
static var jumpCount = 0;
var canJump = true;
var Slow = false;
function FixedUpdate ()
{
GetComponent.<Rigidbody>().AddForce (Vector3.down * 35);
if (Input.GetKey (KeyCode.W) && jumpCount == 0)
{
GetComponent.<Rigidbody>().AddForce (Vector3.forward * 100);
}
if (Input.GetKey (KeyCode.S))
{
GetComponent.<Rigidbody>().AddForce (Vector3.back * 100);
}
if (Input.GetKey (KeyCode.A))
{
GetComponent.<Rigidbody>().AddForce (Vector3.left * 100);
}
if (Input.GetKey (KeyCode.D))
{
GetComponent.<Rigidbody>().AddForce (Vector3.right * 100);
}
if (Input.GetKey (KeyCode.Space) && jumpCount == 0)
{
GetComponent.<Rigidbody>().AddForce(Vector3.up * jumpHeight, ForceMode.Impulse); jumpCount = 1;
}
{
GetComponent.<Rigidbody>().velocity = Vector3.ClampMagnitude(GetComponent.<Rigidbody>().velocity, maxVel);
}
}
var maxVel : float = 16.0;
function OnCollisionEnter (hit : Collision)
{
if(hit.gameObject.tag == "Floor")
{
jumpCount = 0;
}
}
function OnCollisionExit (hit : Collision)
{
if(hit.gameObject.tag == "Floor")
{
jumpCount = 1;
}
}
Note All floor objects are tagged with “Floor” Note Gravity is set to 0 and the player is instead held down to earth by: javascript** ** GetComponent.<Rigidbody>().AddForce (Vector3.down * 35);** **
Have you tried doing something as simple as adding a PhysicsMateral/2DPhysicsMaterial to it and setting the bounce to minimal? That way you could easily have different materials and scenario’s with different friction and bounce.
I havent worked on the game for 5 months, just came back to it today. But i am pretty sure i have tried this, but anyway i will try it and get back to you within a few minutes
Have you set bounciness to 0, and the combine to minimum, and done the same on the other object’s material as well? Unless you’ve set a default PhysicsMaterial in the editor settings, the other material will have a default bounce as well.
Oh yeah definitely, assign it to both of them. Primarily the player, as well as the floor. PhysicsMaterials work in their relationship with each other. Not just by themselves. An object without a PhysicsMaterial (your player right now), will actually use the default PhysicsMaterial set in the player settings, which I think has a bounce of 0.3 or something.
You could perhaps do that in LateUpdate(), to avoid the constant downward force overriding from AddForce getting in the way…
Now that you say it i´ve actually tried this once but ended up quitting it because i couldn´t figure out of i could stop the raycast from rotating with the ball.
I´ve now tried having the PhysicMaterial on both and it definately helps, but the bounch still exists…
The problem is that my players movement script requires the player to be 100% in touch with the ground to be able to jump. Thereby, if the player is just a mini mini mini pixel over a floor object because of a bump then the player cant jump in time.
private void LateUpdate()
{
float snappingRange = 1f;
RaycastHit hit;
Ray ray = new Ray(transform.position, Vector3.down); // << Vector3.Down is the world's down. Instead of transform.down
if (Physics.Raycast(ray, out hit, snappingRange))
{
if (hit.collider.tag == "Floor")
{
transform.Translate(new Vector3(0, hit.distance, 0), Space.World);
}
}
}
The only thing you may need to do is make sure that you’re not hitting your own player. So add a Debug.Log(hit.collider.gameObject.name) in there to check. If it is hitting, just add a layerMask to the RayCast.
I´ve translated it to my language (JS) and it looks like the following:
function LateUpdate()
{
var snappingRange : float = 1f;
var hit : RaycastHit;
var ray = new Ray(transform.position, Vector3.down); // << Vector3.Down is the world's down. Instead of transform.down
if (Physics.Raycast(ray, hit, snappingRange))
{
if (hit.collider.tag == "Floor")
{
transform.Translate(new Vector3(0, hit.distance, 0), Space.World);
}
}
Debug.Log(hit.collider);
}
In the debug it says that it hits an object called “null” so i guess it has something to do with the player.
How do i add a layermask to the raycast called “Floor”?
Aaah that means you’re not hitting anything at all. Sadly
function LateUpdate()
{
var snappingRange : float = 1f;
var hit : RaycastHit;
var ray = new Ray(transform.position, Vector3.down); // << Vector3.Down is the world's down. Instead of transform.down
if (Physics.Raycast(ray, hit, snappingRange))
{
Debug.Log(hit.collider);
if (hit.collider.tag == "Floor")
{
transform.Translate(new Vector3(0, hit.distance, 0), Space.World);
}
}
else
{
Debug.Log("hit nothing");
}
}
Because you’re calling the Debug.Log outside of the physics if statement, it’s not necessarily saying it ‘hit’. Physics.Raycast returns a bool saying whether it hit something or not, so you only know that it’s made a hit when a Debug.Log get’s called the if statement, like above. What you’ll want to do is see the actual direction the ray is firing. To do that you’ll use Debug.DrawRay()
So you’d use it like this:
[code=CSharp]function LateUpdate()
{
var snappingRange : float = 1f;
var hit : RaycastHit;
var ray = new Ray(transform.position, Vector3.down); // << Vector3.Down is the world's down. Instead of transform.down
Debug.DrawRay(transform.position, Vector3.down * 500, Color.Red, 500);
if (Physics.Raycast(ray, hit, snappingRange))
{
Debug.Log(hit.collider);
if (hit.collider.tag == "Floor")
{
transform.Translate(new Vector3(0, hit.distance, 0), Space.World);
}
}
else
{
Debug.Log("hit nothing");
}
}
What this does it shows you the direction the ray is firing in the game, but you need to look for the line in the scene view, not game view. Let me know which way it’s facing.
Well in that case, knowing it’s firing in the right direction, there’s only two possible issues:
You’re not making the ray trace far enough (so up the snappingRange, like so:)
function LateUpdate()
{
var snappingRange : float = 500f;
var hit : RaycastHit;
var ray = new Ray(transform.position, Vector3.down); // << Vector3.Down is the world's down. Instead of transform.down
Debug.DrawRay(transform.position, Vector3.down * 500, Color.Red, 500);
if (Physics.Raycast(ray, hit, snappingRange))
{
Debug.Log(hit.collider);
if (hit.collider.tag == "Floor")
{
transform.Translate(new Vector3(0, hit.distance, 0), Space.World);
}
}
else
{
Debug.Log("hit nothing");
}
}
The floor has no collision. Though I’m guessing it must for the ball to be bouncing off of it. Make sure it’s on the ‘default’ layer, to be sure (found in the top right of the inspector when clicking on it)
Yeah i forgot i had the floors on the “floor” layer instead of default - anyway it does still not work.
It looks like it now knows that it hits the floor, but the player keeps bounching up and down like a bouncy ball of Redbull… haha