Reputation: 13
So I'm working on a basic platforming game, and my player controller has a system where if S is hit, then the player should ignore collisions with objects in the platform layer. However, Even though run the IgnoreLayerCollision, my player still detects the collisions. Any fixes?
private void FixedUpdate()
{
//Drop through platforms or not?
if (dropDown)
{
Physics2D.IgnoreLayerCollision(9, 8, true);
playerCollider.enabled = false;
platformCollider.enabled = false;
playerCollider.enabled = true;
platformCollider.enabled = true;
print("Dropdown");
}else
Physics2D.IgnoreLayerCollision(9, 8, false);
}
void getInput()
{
if(Input.GetKeyDown(KeyCode.S))
{
dropDown = true;
}
else if(Input.GetKeyUp(KeyCode.S))
{
dropDown = false;
}
}
Dropdown does print properly
Upvotes: 1
Views: 4269
Reputation: 1
i solved this problem with: change by "Platform Effector 2D" the "Use Collider Mask" to false
Upvotes: 0
Reputation: 125415
The FixedUpdate
function is called every fixed framerate frame. When dropDown
is false, Physics2D.IgnoreLayerCollision(9, 8, false);
is called every fixed framerate frame. I do think this is the problem. You need to call this once only. Similar thing happens when dropDown
is true. Physics2D.IgnoreLayerCollision(9, 8, true);
is called every fixed framerate frame but this should only be called once.
Move that code directly to your getInput
function so that they are called once only. Ofcourse, you can use boolean variables in the FixedUpdate
function to fix this but that's totally unnecessary.
void getInput()
{
if(Input.GetKeyDown(KeyCode.S))
{
Physics2D.IgnoreLayerCollision(9, 8, true);
playerCollider.enabled = false;
platformCollider.enabled = false;
playerCollider.enabled = true;
platformCollider.enabled = true;
}
else if(Input.GetKeyUp(KeyCode.S))
{
Physics2D.IgnoreLayerCollision(9, 8, false);
}
}
getInput
must be called from the Update function. Finally, make sure that both objects are set to layer 8
and 9
in the Editor or code. It won't work if they are not set to these layers.
Using PlatformEffector2D
with Physics2D
:
With your new screenshot in your question, Physics2D.IgnoreLayerCollision
is not currently working because you are using PlatformEffector2D
on your colliders.
It doesn't work because PlatformEffector2D
have it's own collider mask settings which is enabled by default and overrides whatever you set to Physics2D.IgnoreLayerCollision
. You can use PlatformEffector.colliderMask
to select the layers or disable PlatformEffector2D
's mask so that you can use Physics2D.IgnoreLayerCollision
. I suggest disabling PlatformEffector2D
's mask as that's because it's more easy to use Physics2D.IgnoreLayerCollision
.
You can disable PlatformEffector2D
's mask by setting PlatformEffector2D.useColliderMask
to false
. This must be done for both the player and the platforms PlatformEffector2D
component.
Just add to the Start
function:
void Start()
{
PlatformEffector2D playerEffector = playerCollider.GetComponent<PlatformEffector2D>();
PlatformEffector2D platformEffector = platformCollider.GetComponent<PlatformEffector2D>();
//Disable PlatformEffector2D
playerEffector.useColliderMask = false;
platformEffector.useColliderMask = false;
}
Also modified your title to reflect that you are using PlatformEffector2D
.
Upvotes: 3
Reputation: 4204
Firstly, you should only use single key method (only use key-down
) to toggle ignore-collision property of the 2 layers. This is demonstrated in below code, here layerCube
is for yellow cube and layerRoof
is for blue roof.
Try adding logs in your code to test your incorrect logic.
public class Character : MonoBehaviour {
bool ignore = false;
int layerCube = 0;
int layerRoof = 8;
void Update () {
if (Input.GetKeyDown(KeyCode.Space))
GetComponent<Rigidbody>().AddForce(Vector3.up * 8,ForceMode.Impulse);
if (Input.GetKeyDown(KeyCode.S)) {
ignore = !ignore;
Physics.IgnoreLayerCollision(layerCube, layerRoof, ignore);
}
}
}
Secondly, the below snippets in your code are also completely wrong and should be corrected:
playerCollider.enabled = false;
platformCollider.enabled = false;
playerCollider.enabled = true;
platformCollider.enabled = true;
the above code effectively is simply setting the colliders to true
. For what you are trying to achieve, you should simply remove the above lines. These are not at all required if you are already adding code to ignore layer collisions.
Upvotes: 0