OnCollisionEnter not working with duplicate of an object - c#

So I have a wall where the player can jump on and it detect the collision and reduce the gravity. This is working fine.
This is what it looks like
Mossy Wall (L)
and here is the code:
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("MossWall"))
{
onMossyWall = true;
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("MossWall"))
{
onMossyWall = false;
}
}
As you can see it's pretty basic, all I want is to set onMossyWall to true when there is a collision and it works perfectly for this one.
Now I want to do the same but for an opposite wall, I copy the object (Moss Walls (R)), and rotate the platform effector so that it's on the opposite direction, and yet nothing happens. onMossyWall stay false. The tag is the same and the object is basically the same as the first one, why isn't this working ?
Mossy Wall (R)
I assume I must have forgotten something stupid but I have been looking for solutions for a while and I found nothing that works. I tried with a different tag but still nothing.

As unity docs states:
OnCollisionEnter is called when this collider/rigidbody has begun
touching another rigidbody/collider.
So please make sure you have colliders on both objects and one of the object must have a rigidbody.

Related

Unity 3d player jump does't work, rb.addforce doesn't work

I have a very basic infinite runner and I want to make my player jump. I have attached rigidbody to my player, have instantiated it. here is some part of my code
void FixedUpdate()
{
if (OnGround)
{
if (Input.GetKeyDown(KeyCode.Space))
{
rBody.AddForce(new Vector3(0, 10, 0), ForceMode.Impulse);
Debug.Log("jump");
OnGround = false;
}
}
}
void onCollisionEnter(Collision other)
{
Debug.Log("collision");
if (other.gameObject.CompareTag("ground"))
{
OnGround = true;
}
}
I have tried to put this part in Update(), no result.
The interesting part is that Debug.Log("jump") shows on the console, but the player doesn't want to jump.
Method void CollisonOther() is never called.
I have also tried to change velocity and use transform.translate, no result
jump. How can I make it jump?
There are a couple of things that could be the issue. Make sure the isKinematic box is unchecked. It's also possible that the character is jumping but you cannot see it if your sprites were imported too big (ie: it's jumping a very very small amount relative to the size). You could try printing some more debug statements of the character's position to see if it is actually changing or not.
it seems to be correct in your code but don't know why not jumping. BTW, you can try with this code
just without AddForce and changing the checking you are using.
if (Input.GetButtonDown("Jump") && OnGround)
{
rBody.velocity = new Vector2(rBody.velocity.x, jumpSpeed);
}
Make sure it is under your Update method coz Input calls in Update method. If your 'OnGround' Layer check is
perfect it should work.
OnCollisionEnter should have a capital O instead of lower case. As written, onCollisionEnter will never be entered.
That's the only code problem that could be wrong, assuming you actually assigned the other variables corrrectly. However, there could be a variety of game object related behavior.
Is the ground tag applied to the game obejct that you think your runner is colliding with? If not, it won't jump.
Is your mass for the jumper's rigidbody very high? With the default of 1, it jumps pretty high, but could not get the right amount of force if it was a larger mass.
I ran into the same issue and, after hours of investigating, in my case it had nothing to do with the code, but with the below Unity bug (still present in 2020.1.6f1).
For some reason, it interfered with any key inputs I checked for in the code (in your case GetKey(KeyCode.Space)
https://issuetracker.unity3d.com/issues/urp-errors-are-constantly-thrown-when-active-input-handling-is-set-to-input-system-package
The fix was going to Edit - Project Settings - Active Input Handling - select Both.

Rigidbodies touching but OnCollisionStay stops being called (Unity3D)

I want to simulate two pistons that replicates the behaviour of a balance. I'm doing this with spring joints and applying the inverse weight one another when OnCollisionStay is called. This are my pistons and their rigidbodies and joints. Are exactly the same on both.
This is my SpringForceTransmisor.cs code:
using UnityEngine;
public Rigidbody InverseJoint;
private void OnCollisionEnter(Collision collision) {
Debug.Log("Enter");
}
private void OnCollisionExit(Collision collision) {
Debug.Log("Exit");
}
private void OnCollisionStay(Collision collision) {
InverseJoint.AddForce(-(collision.rigidbody.mass * Physics.gravity));
Debug.Log("Stay");
}
And this is a video of what's happening.
So, according to the log showed on the video, OnCollisionStay() stops being called even if OnCollisionExit() had never been called. How is this possible? I've always thought that OnCollisionStay() is called every frame from OnCollisionEnter frame and OnCollisionExit frame.
Can anyone shed some light about what's going on here?
According to the documentation on OnCollisionStay, it says:
OnCollisionStay is called once per frame for every collider/rigidbody
that is touching rigidbody/collider.
Unfortunately, this is not true sometimes. The OnCollisionStay function is called few times in some cases and the call is then stopped. This is either a long time bug that has not been fixed for years or the documentation is wrong.
My usual advise to people is to abandon the OnCollisionStay function and simply set a boolean variable to true in the OnCollisionEnter function then set it to false in the OnCollisionExit function. You can then use the Update function as the OnCollisionStay function by checking that boolean variable in the Update function.
public Rigidbody InverseJoint;
bool collisionStay = false;
Collision collision = null;
private void OnCollisionEnter(Collision collision)
{
Debug.Log("Enter");
collisionStay = true;
this.collision = collision;
}
private void OnCollisionExit(Collision collision)
{
Debug.Log("Exit");
collisionStay = false;
this.collision = collision;
}
void Update()
{
if (collisionStay)
{
InverseJoint.AddForce(-(collision.rigidbody.mass * Physics.gravity));
Debug.Log("Stay");
}
}
The answer to your question would become obvious if you included in the video the part, where the "Enter" is being registered.
Now to explain what is happening, let me show an example on a traingulated sphere . Here is how it looks like (with some triangles intentionally made invisible).
Keep in mind that it is hollow, all it essentially is are a bunch of points that form triangles. Now say this is a mesh for some mesh collider component. If any other collider interacts with this sphere_mesh_collider, the only way for unity to detect it is by checking for the triangles of those two colliders having intersections. This is to say that ANY OTHER area that is not covered INSIDE the triangles will not be checked. In other words the volume of my sphere here will never detect collisions (nor call the collision stay, but the collider havent exited either, so neither it calls exit).
That is what I think is happening in your case, although I can not say for certain because I do not see the whole process of colliders starting to interact (Enter) and than coming apart (Exit).
Edit: You can easily observe this if you enable unity wireframe (or shaded wirefram) in the editor window.
Another note from the Unity documentation:
Note: [...] Collision stay events are not sent for sleeping Rigidbodies.
You could try setting Rigidbody.SleepThreshold to zero to see if that solves your problem.
Just solved this myself. This is because your rigidbodies are sleeping, try setting the rigid body sleep to "Never sleep" and it will work.

Teleporting player object on collide not working

I'm trying to teleport my player to 0,1,0 on the coordinate system (right above the origin) when it hits any object with the "Death" tag.
Resetting the level works fine with this, but I want it to just teleport, so I tried this. I've searched many tutorials, but I just couldn't get this to work.
Any tips on what could be wrong?
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Death"))
{
gameObject.transform.position = new Vector3(0.0f,1.0f,0.0f);
}
}
(Note that the player just falls through the object right now)
Are you using gravity on Rigidbody component on your player object? turn it off and check the behaviour.
Found the problem, apparently there was some weird randomly assigned script that didn't exist on my death ground object.

Collision script on an object to be collided with from the player for pickup

I'm trying to write a script that allows the player to walk into a pack of ammo (or health) and gain something from doing so. I'm struggling with the actual collision part of this as no matter what I do I can't seem to get it to work. I currently have this script on my ammo pack object.
void onTriggerEnter(Collider collision) {
if (collision.gameObject.tag == "Player")
{
Debug.Log ("Collided");
}
}
My ammo pack object has a collider on it (currently capsule, will be box for final product) that has "Is Trigger" enabled.
My player has a capsule collider also (non-trigger) and a rigidbody with gravity enabled and everything else default. It is also tagged as "Player". When my player walks into the ammo pack, there is no message printed.
I've tried several solutions that involve changing triggers on colliders and rigidbody kinematic settings but none of them seem to work. I'm using Unity 5 and so I was wondering if I'm doing something wrong. Any help would be greatly appreciated.
This function will never get called because your capitalisation is wrong. Capitalise the first letter of the function name.
void OnTriggerEnter(Collider c)
Instead of:
void onTriggerEnter(Collider c)
Note: Always use CompareTag() instead of == to compare strings. Both work but CompareTag is GC friendly.

OnCollisionEnter() not working in Unity3D

I have an object with a mesh collider and a prefab with sphere collider. I want the instance of the prefab to be destroyed if the two collide.
I wrote the following in a script:
private void OnCollisionEnter(Collision c)
{
if (c == target)
Destroy(transform.gameObject);
print("something"); // Doesn't get printed
}
But it is not working. I have tried toggling isTrigger on both the objects.
I had the same problem of OnCollisionEnter not being called and found this question.
For me, the problem was that I was making a 2D game so the answer is to use the OnCollisionEnter2D function instead.
Have a look at this table
If you want your OnCollisionEnter to be called make sure:
(a) Both objects have a collider attached.
(b) None of the objects is a trigger collider (this will issue OnTrigger function & not OnCollisionEnter)
(c) One of the objects (doesn't matter which of them) is a rigid, non kinematic & non static object (the second don't have to be a rigid body).
(d) Due to computational difficulties MeshCollider might have hard times colliding with other mesh collider, use them with caution.
(e) Make sure both the objects are in the same layer (or at least that they collide in scene settings).
(f) If you are working in 2d - OnCollisionEnter2D will be called, rename your function.
Make sure one of them has a non-kinematic rigidbody attached. Taken from the Unity docs:
When a collision between two Colliders occurs and if at least one of them has a Rigidbody attached, three collision messages are sent out to the objects attached to them. These events can be handled in scripting, and allow you to create unique behaviors with or without making use of the built-in NVIDIA PhysX engine.
From here: Unity3D MeshCollider
I had a similar problem. The box collider wasn't as big as the collision object. Setting the x and z values to 2 units fixed the problem!
Have you tried using the OnTriggerEnter() method and setting a collider on the object to a trigger?
If it doesn't need to tell what object its colliding with you could do a simple
void OnTriggerEnter(){
Destroy(transform.gameObject);
}
Edit:
Also I have done OnCollision like this
private string hitobject;
void OnCollisionEnter(UnityEngine.Collision hit)
{
hitobject = hit.gameObject.tag;
if(hitobject == "Plane")
{
isgrounded = true;
}
}
None of the objects are triggers and they don't need rigid bodies to work.

Categories

Resources