Unity2D - Ignore collision with edge collider - unity3d

I am trying to have my player ignore the collision with an edge collider on a platform i have.
Here's the script that I have added to the player
public class TestMovement : MonoBehaviour
{
public Rigidbody2D ball;
private GameObject purplePlat1;
private GameObject player;
// Start is called before the first frame update
void Start()
{
purplePlat1 = GameObject.Find("purple_plat");
player = GameObject.Find("circle-png-44659");
ball = GetComponent<Rigidbody2D>();
ball.AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
Debug.Log("start");
}
// Update is called once per frame
void Update()
{
}
void OnCollisionEnter2D(Collision2D collision)
{
Physics2D.IgnoreCollision(purplePlat1.GetComponent<EdgeCollider2D>
(), GetComponent<CircleCollider2D>());
Debug.Log("collision");
}
}
The ball is still hitting the platform. I have confirmed that the oncollisionenter method is firing.

You can use the layer system of Unity to avoid collisions between both. Set a layer for a player and another for the edge and untick the collision between them.

What you can do is create a layer mask for the different type of game objects. Then, open your Physics2D settings.
On the bottom part, you can see a matrix of physics objects that can collide to one another. Just uncheck which layer should not collide with the other.

Related

How do I rotate an object's parent without the child being moved along?

In my game on unity 2d I have spaceship and a planet. The planet is orbiting a star so I made a script that parents the planet to the player when I get within a range so the planet doesn't fly past or into the player. This script makes the player move with the planet so they land on it and fly around it easily.
Here is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParentPlayer : MonoBehaviour
{
[SerializeField] GameObject Player;
private float Dist;
[SerializeField] float Threshold;
private CircleCollider2D ParentTrigger;
// Start is called before the first frame update
void Start()
{
ParentTrigger = GetComponents<CircleCollider2D>()[1];
ParentTrigger.isTrigger = true;
ParentTrigger.radius = Threshold / transform.localScale.x;
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(transform);
}
}
private void OnTriggerExit2D(Collider2D collider)
{
if(collider.gameObject == Player)
{
collider.gameObject.transform.SetParent(null);
}
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, Threshold);
}
}
The problem is that as the planet rotates it ends up moving the player that has been parented to it. How can I make the planet's rotation not affect the position and rotation of the player, but still make the planets position affect the position of the player?
This might not be what you're looking for but I'm going to add it reguardless. Given that the Child-object will follow the parent, I would suggest putting the planet and spaceship as a child of the empty gameobject. Then you could rotate the the planet object, and if planets are in movement, you could add the movement to the parent object.
How about instead of parenting the player, write a script to set its position to the planets + some offset, and then the rotation wouldn't be an issue. Alternatively, if the player doesn't rotate at all, add constraints to its Rigidbody. Maybe something like this:
player.transform.position = planet.transform.position + offset;
Hope that works!

Add Force teleporting the player

I want to push back my player when it collides with an object but when it collide with the object, it just teleporting back rather then pushing smoothly. I tweaked with values like Mass, Drag on player's rigidbody or knockbackStrenght value from script. It just teleporting further positions with higher values and teleporting to closer positions with lower values but it always teleports not pushback.
My code on the object that will push back player looks like:
public class StickRotator : MonoBehaviour
{
[SerializeField] float rotateSpeed;
[SerializeField] float knockbackStrenght;
[SerializeField] Vector3 rotateDir;
Vector3 _parentPos;
void Start()
{
_parentPos = GetComponentInParent<Transform>().position;
}
void Update()
{
transform.RotateAround(_parentPos, rotateDir, rotateSpeed * Time.deltaTime);
}
void OnCollisionEnter(Collision other)
{
if (other.gameObject.CompareTag("Player"))
{
other.gameObject.GetComponent<Rigidbody>().AddForce
(Vector3.back * knockbackStrenght, ForceMode.Impulse);
}
}
}
Player's rigidbody settings
When player collide with stick, it just teleporting back rather then pushing back
Along with #absinthe's comment, you could try using rigidbody.velocity instead of AddForce.
I find out that Animator component on the player causing the issue. Unticking 'Apply root motion' seems solved my problem but now when player pushing back smoothly, its jittering.

How would I add a collider to a line renderer?

I'm a noob trying to make a game like this https://youtu.be/qxwO1wyz50w?t=37 , but i cannot figure out how to add collision to my line renderers. Would a line renderer be the way to go about this or is there a better way?
Here is my code so far (messy I know im new to programming as well )
public GameObject crossHair;
public LineRenderer line;
public Transform startPoint;
public GameObject lazer;
void Start()
{
Cursor.visible = false;
}
void Update()
{
crossHair.transform.position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
if (Input.GetKeyDown(KeyCode.Mouse0))
{
LineSpawner();
startPoint.position = crossHair.transform.position;
}
}
void LineSpawner()
{
Vector2 shootDir = crossHair.transform.position - startPoint.transform.position;
GameObject lazerInstance = Instantiate(lazer);
line = lazerInstance.GetComponent<LineRenderer>();
line.SetPosition(0, startPoint.transform.position);
line.SetPosition(1, crossHair.transform.position);
Physics2D.Raycast(startPoint.transform.position, shootDir);
Debug.DrawRay(startPoint.transform.position, shootDir, Color.red);
}
Unfortunately, you cannot add a collider component to line renderers but a way around this is to create another gameobject that is invisible and make it a child of the line itself. What you then want to do is use the invoke("targetFunctionName", amountOfSeconds) method to destroy the collider gameobject after the player has hit it, this is so the game doesn't lag for those who are doing well while playing it. What you then want to do is add a physics material to the game object and set its bounciness property to max(which I think is 1). Do the same for the player's gameobject and you're done.

How to call a method every time, when player stay at any collider?

I have a game like CubeSurfer. When player goes through an collectable, two methods are called (for "jumping" and creating a cube under player). But, when player goes through second, or third collectable, nothing happens. I tried to attached script to collectable, and tried to put the method "OnTriggerEnter" in the body of methods "Start" and "Update". But it doesn't work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollider : MonoBehaviour
{
[SerializeField] Collider player;
[SerializeField] GameObject destroyIt;
[SerializeField] GameObject objToClone;
[SerializeField] Transform rootObjInScene;
Transform curParent;
Vector3 posOffset, posPlayer;
float distance = 1f;
private void OnTriggerStay(Collider player)
{
PlayerJumping();
CreateAnother();
Destroy(destroyIt);
}
public void PlayerJumping()
{
posPlayer = Vector3.up * distance;
Vector3 playerPos = rootObjInScene.position + posPlayer;
rootObjInScene.transform.position = playerPos;
}
public void Awake()
{
curParent = rootObjInScene;
posOffset = Vector3.down * distance;
}
public void CreateAnother()
{
Vector3 newPos = curParent.position + posOffset;
GameObject newObj = Instantiate(objToClone, newPos, Quaternion.identity, curParent);
curParent = newObj.transform;
}
}
You should also check your Rigibody collision detection mode in the inspector.
By default, this is set to Discrete, but if your object is fast-moving, you should set it to Continuous or ContinuousDynamic, otherwise the collisions won't be registered because the object is moving too quickly.
These are a little bit performance intensive, so I'd still recommreading up on the Unity documentation or digging through a couple of good articles to know what's best for you :)
You shouldn't call OnTriggerEnter explicitly (in your Update()), it's an event message and gets called automatically by unity when you enter a Collider marked isTrigger.
You can use OnTriggerEnter only if your collider is marked isTrigger, if you want to get a collision with a Collider that is not explicitly a trigger, you use OnCollisionEnter
To execute a method repeatedly while touching a Collider use OnCollisionStay, while touching or inside a Collider with isTrigger use OnTriggerStay
OnCollisionStay
OnTriggerStay
You can use OnCollisionStay or OnTriggerStay
void OnCollisionStay(Collision collisionInfo)
{
//Do something when collisionInfo.gameObject stay in this.gameObject collider
}

Bullet passes through the player

I'm using unity and when the enemy shoots, the bullet passes right threw the player. I don't know how to solve this. Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyBullet : MonoBehaviour
{
public float speed;
public Rigidbody2D rb;
private Transform player;
private Vector2 target;
private Vector2 moveDirection;
// Start is called before the first frame update
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
moveDirection = (player.transform.position - transform.position).normalized * speed;
}
// Update is called once per frame
void Update()
{
rb.velocity = new Vector2(moveDirection.x, moveDirection.y);
//transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "Player") {
Destroy(this.gameObject);
}
}
}
I put a tag named BulletEnemy on the bullet but it doesn't work
How fast is your speed value?
At high speeds a bullet might move farther in one frame than the depth of the object you want it to hit. You can still detect collisions by every frame storing the position of your bullet as a vector and on the next frame casting a ray between the current position and the last known position in the previous frame. If the ray hits your enemy then call the same function that you would on a physics collision.
There is no way to do it with only OnCollisionEnter because of the effect of bullet speed.
Check your bullet's speed. if they are too fast, your physics engine just ignore the collision and therefore no OnCollisionEnter will be called.
Use larger Collider for your player. and also check Player tag on your player object. also make sure your tagged object has Collider2D component.
Change OnCollisionEnter2D to OnCollisionStay2D. if you want to Destroy bullet, there will be no difference in runtime