Player not colliding with Tilemap 2d collider - c#

For some reason, my player is not colliding with the tilemap walls that have collision on them... Here is my player movement code
void Update()
{
hInput = Input.GetAxisRaw("Horizontal");
vInput = Input.GetAxisRaw("Vertical");
if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.RightArrow))
{
transform.Translate(hInput, 0, 0);
}
else if (Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.DownArrow))
{
transform.Translate(0, vInput, 0);
}
}
When I move my player they go right through the colliders. They are on the same Layer and both have colliders. Anyone know why this is happening? Thanks!
Edit: So I've tested the collisions with OnCollisionEnter2d like suggested and they are colliding, the problem is my player still walks right through the wall. I have no clue why the collider doesn't stop this from happening.

Collider doesn’t actually perform physics like the aftermath of a collision, it just figures out when things are touching. In order to use physics you need a rigidbody or rigidbody2D, which will actually do something about the collisions the collider detects. Then, instead of setting position you will need to set rb.velocity.

The detection of colliders does not happen in Update() method. To detect collision you need to have OnCollisionEnter(). This method will be called when another object with collider and rigidbody enter in it. See the official example here.
void OnCollisionEnter(Collision collision)
{
Debug.Log(collision.collider.name);
}

Make sure the Z axis values are the same.
And just to check if the collisions are actually taking place, do this:
void OnCollisionEnter(Collision col)
{
Debug.Log(col.collider.name);
}
And make sure that the Collider is not a Trigger.
These are the only possible problems, and their fixes.

Related

Player Keeps Going Through the Wall

I have a game where map/background is made up of prefabs. My player and prefabs both have rigidbodies and colliders. Neither of them have is trigger checked and the prefabs have collision detection set as continuous dynamic. The player's collision detection is set on continuous. Each of the prefabs have a mesh collider and the individual walls of the prefabs have box colliders (none are set to is trigger). I keep trying to test it on my phone using Unity Remote 5, and every time I move the player it goes through the walls. If anyone has any advice on how to prevent my player from going through the walls, I would really appreciate it!
My movement script is:
public class Movement : MonoBehaviour
{
private Touch touch;
private float speedModifier;
void Start()
{
speedModifier = 0.01f;
}
void Update()
{
if(Input.touchCount > 0)
{
touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Moved)
{ transform.position = new Vector3(transform.position.x + touch.deltaPosition.x * speedModifier,
transform.position.y,
transform.position.z + touch.deltaPosition.y * speedModifier);
}
}
}
}
It would really help to see your movement script however it sounds like you are moving player by manipulating transform.position or using rigidbody.MovePosition() without setting isKinematic to true. The documentation says;
If the rigidbody has isKinematic set to false, it works like transform.position=newPosition and teleports the object to the new position (rather than performing a smooth transition).
This behaviour will ignore the collision. Also you don't need rigidbody on every GameObject in the scene. 1 rigidbody on the player is enough to collide it with other objects.
depend on what I got from your question, when you are playing and the player hit the wall, it goes inside; so the problem might be the mass of the wall. if you must add a Rigidbody to the wall so you need to add more mass to the wall also edit the border of the box collider and make them reasonably a bit wider, otherwise if you dont need a rigidbody on the wall simply keep just the box collider and it will works good. hope this answer help you, and it will be better if you can explain more the situation using some pics.
Using the Rigidbody position or applying force tends to cause the Rigidbody to clip through other colliders. I recommend changing rigidbody.velocity instead of directly changing the position.

How come the Collider falls from the GameObject when a RigidBody is added?

I could really need some help with my GameObjects.
I am working on a game in which I want a pick-up Item to create a Physics Force explosion to blow away the enemies. I made a simple Bomb-Object to test this idea. I added a straightforward code, using a loop to collect all the colliders within its radius, to then addForce to these colliders. Now the code is working properly, but not all my GameObjects are reacting properly.
I looked into why this is, and I noticed that my Collider keeps falling away from the GameObject as soon as I add a RigidBody component to the object. The RigidBody is needed for the AddForce impact. When I remove the rb, the collider stays in place, but the object does not react to the Physics Force.
I added some images to illustrate what I mean:
Image of the Collider of the leaf sinking away..
Example image of objects which DO react to the AddForce.
I already tried to:
Copy/Paste all component settings from the reacting Cube and stone
Gameobjects to the Leaf Gameobject while disabling all other code
such as the c# scripts. The Collider & RB do not fall through the
floor but when Physics Force hits the Collider is blown away while
the GameObject keeps its position.
Try different GameObjects/Collider types.
Removed the water.
Play with amount of force/radius of the bomb.
Edited 'Tag' and 'Layerstyle' of GameObject.
The 'Explosion Code' is added below, however, I don't think the problem is in the code. I added the code to the Main Camera of my scene, and added a simple sphere as the 'bomb' GameObject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Explosion : MonoBehaviour
{
public GameObject bomb; //set the position of the explosion
public float power = 10.0f;
public float radius = 10.0f;
public float upForce = 0.0f;
private void FixedUpdate()
{
if (Input.GetKeyDown("space"))
{
print("space key was pressed");
Invoke("Detonate", 1);
}
}
void Detonate()
{
Vector3 explosionPosition = bomb.transform.position; //set the position of our explosion to the position of the bomb.
Collider[] colliders = Physics.OverlapSphere(explosionPosition, radius); //collects all colliders within the radius.
foreach (Collider hit in colliders) { //for each individual collider the following code is ran.
Rigidbody rb = hit.GetComponent<Rigidbody>(); //declare'rb' rigidbody. Get rb component from each collider
if (rb != null)
{
print("BOOM!");
rb.AddExplosionForce(power, explosionPosition, radius, upForce, ForceMode.Impulse); //add force to each collider
}
}
}
}
How do I make the Rigidbody, Collider and GameObject of the leaf hold onto each other like the standard 3D object 'cube', so that I can make these blow away with the Physics Force just like the other models?
Thank you for your time, I have been trying things and looking around on the Internet for hours now but can't seem to find any solution.
What happens if you add the rigidbody in stop mode and press play? Does it move away in a similar manner? This may, and is expected to happen, if your colliders intersect with each other. As soon as you add a rigidbody, they find themselves trapped in a serious collision.
If you don't want to modify the scene, you can fiddle with the collision matrix in project settings / physics

Detect if the player is landed on top of a box with rigidbody

I'm working on a Unity game where the player shoots on cubes to change their weight (it can be positive or negative, last one meaning 'falling' to the roof) and i'm experiencing a problem with rigidbodies, spherecasting and detecting if the player is grounded or not.
When my player is on the ground or on top of any object with a collider, I detect it as 'grounded' using the following function:
if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
((m_Capsule.height / 2f) - m_Capsule.radius) + advancedSettings.groundRoofCheckDistance, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_IsGrounded = true;
}
where advancedSettings.groundRoofCheckDistance is set to 0.01f.
Until there, everything works fine. But now, when I try to get on top of a cube with a non-kinematic rigidbody, I can't get that boolean to be true.
Here are two captures to illustrate my problem :
In this one, the player is falling on a non-kinematic rigidbody box and the boolean circled in red is m_isGrounded (false):
And here, same but the cube is kinematic and the ground is detected just fine:
I really can't figure out why the rigidbodies do that, or if I have a problem with my ground detection function, so any help is welcome.
Thanks!
PS: I'm using Unity 2018.2.15f1
There are many ways to detect if player is grounded or not. If raycast, SphereCast and other ray based detection API are not working properly, try something different. Use the callback functions such as OnCollisionEnter and OnCollisionExit with flag. Check that flag in the Update function.
bool m_IsGrounded;
void OnCollisionEnter(Collision collision)
{
if (collision.collider.CompareTag("Ground"))
m_IsGrounded = true;
}
void OnCollisionExit(Collision collision)
{
if (collision.collider.CompareTag("Ground"))
m_IsGrounded = false;
}
void Update()
{
if (m_IsGrounded)
{
Debug.Log("Grounded");
}
}
Note that this is checking for the "Ground" tag so your ground object must be on the "Ground" tag. You have to manually create this tag from the Editor then change your ground object tag to this.

Instantiate and Fire Object, when OnTriggerEnter or OnCollisionEnter

I would like a bullet that is fired from the Enemy, to bounce back off my Players shield.
I have set up my character and the enemy fires towards me at time intervals.
I can then activate my players shield (turning on a BoxCollider) and pressing a button.
So when the Bullet (IsTrigger) collides with my Players Shield (IsNotTrigger) I want to remove this Bullet and then Instantiate a new Bullet from the shield, in the direction of the Enemy.
I am also having an issue destroying the Bullet.
When the OnTriggerEvent or OnColliderEvent occurs (tried both), hundreds of bullets will appear from my Shield. How do I only allow one bullet to be fired towards the enemy?
Below is part of my script, which is located in the GameObject of my Players Shield.
Ideally I would like to destroy the bullet once it has collided with an object.
void OnTriggerEnter(Collider col) {
if (col.tag == "Weapon") {
attack();
}
}
private void attack() {
if (!GameManager.instance.GameOver) {
bulletReturnClone = Instantiate(bulletReturn, transform.position, transform.rotation) as GameObject;
bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;
Strachan,
That's not how I would approach the problem but I will stick to your desired solution then share some ideas for improvement.
void OnTriggerEnter(Collider col) {
if (col.tag == "Weapon") {
attack(col);
}
}
private void attack(Collider col) {
if (!GameManager.instance.GameOver) {
bulletReturnClone = Instantiate(bulletReturn, transform.position, transform.rotation) as GameObject;
bulletReturnClone.GetComponent<Rigidbody>().velocity = transform.forward * 25f;
// the following line of code should remove the bullet from the shield collider in order to prevent any future problems like spawning multiple bullets or instantly destroying the newly created bullet
bulletReturnClone.GetComponent<Transform>().position *= bulletReturnClone.GetComponent<Rigidbody>().velocity;
Destroy(col.gameObject);
}
}
If your trigger(Bullet) is tagged as weapon this code should achieve your intentional goal of reflecting the bullet in the direction of your shield pointing to by destroying the bullet and instantiating a new one and modifying it's velocity. It works but it's kind of sloppy development. It can be much better if you approach the problem from a different perspective - the one of the Bullet not the Shield.
Let's pretend for a moment you are a Bullet. All you do is fly in the direction you are shot. Once you collide with a terrain you stop/disappear. If this terrain is a shield you don't stop/disappear but change your direction (you get reflected).
So... long story short... the one who should have a trigger collider is the bullet not the shield. OnTriggerEnter(Collider col) for the bullet script will destroy it but if col.tag == "Shield" the bullet will only change its direction without all the useless instantiations and transformations.
I'm too lazy to write the code for the 2nd solution. If you got my point you should be able to easily write it down. Also learning through trials and errors helps you develop (excuse for me being lazy).
Im not really sure why you would want to despawn and respawn the bullet with a new velocity?
Depending on the shield geometry you could look up Coefficients of Restitution and therefore reflect the kinetic energy of the bullet into a realistic velocity.
Note the complexity of that maths will be proportional to the complexity of your shield geometry depending on the different collision primitives.
Sphere-sphere
Sphere-plane
Sphere-terrain (terrain could represent any un-even surface)
Or are you trying to collect the bullets in some sort of "charge" mechanic to release them back at a different time?

Is there a way two make two trigger gameObjects collide?

This is for a 2D game.
I have a Player who can shoot trigger projectiles(with a trigger collider) and Enemies that can do the same. When a Player projectile collides with the Enemy, stuff happens and vice versa. However, when the Player projectile and the Enemy projectiles collide, they just ignore collision, go through each other, and nothing happens. They also have a Rigidbody2D with continuous collision detection.
Is there a way to make it so something happens when these two gameObjects with trigger colliders touch?
Here's what I've got for the Enemy projectile script:
void OnTriggerEnter2D( Collider2D other ){
if (other.gameObject.name == "Ground"){
Destroy (gameObject);
}
else if (other.gameObject.name == "Player"){
other.gameObject.GetComponent<RControlScript>().RHealth = other.gameObject.GetComponent<RControlScript>().RHealth - damage;
Instantiate(transformInto, gameObject.transform.position, gameObject.transform.rotation);
Destroy (gameObject);
}
else if(other.gameObject.name == "Shot"){
Destroy (gameObject);
}
}
"Shot" being the name of the Player projectile being the gameObject not colliding with the Enemy projectile.
Yes.
Here is a graph that tells you what collides with what in Unity3d.
Ok, turns out two trigger colliders do in fact collide. My problem was that the projectiles instantiated were clones, therefore its name = "Shot(clone)". Had to change that in order to make things happen.

Categories

Resources