So here it is, Iam making a game for my thesis. The game is called hacky sack, Iam having a problem when my trigger is true because the collision for my character and the object is passing through and if idon`t have a trigger it was just basically hitting it even when my Player is running.
And can you guys help me on how the Object/Sack going up randomly when it hit. So here is my code :
public void Sipa()
{
if (canSipa == true)
{
_pitcha.GetComponent<Rigidbody2D>().AddForce(new Vector2(-400, 1000));
}
}
}
And here is for my object
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Player")
{
_player.GetComponent<PlayerManager>().canSipa = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "Player")
{
_player.GetComponent<PlayerManager>().canSipa = false ;
}
}
}
add a second collider, slightly larger then the first, mark it trigger. leave the smaller inner collider for physics. you "foot" should enter the trigger and activiate it, then collide with the inner collider. make sure the collider marked trigger is the larger one.
Related
I'm working on a school project, and I need help with this trigger2dstay thing. I'm trying to make it were when my player's collider tag enters the triggers collider, an image pops up which works, but I'm also trying to make it were when the play does the same thing and presses E, it will trigger a animation, but when my 2d player walks in the trigger and presses E, nothing happens. pressing E only works when you are moving and pressing it, and not staying still.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class buttonele : MonoBehaviour
{
public GameObject Obje;
public GameObject blockers;
public GameObject eledoorn;
public GameObject eledormation;
bool Unlock;
// Start is called before the first frame update
void Start()
{
Obje.SetActive(false);
eledormation.SetActive(true);
Unlock = false;
}
void OnTriggerStay2D(Collider2D other)
{
if (other.tag == "Player")
{
Unlock = true;
Obje.SetActive(true);
}
if (Unlock == true && Input.GetKeyDown(KeyCode.E))
{
Destroy(blockers);
Destroy(eledoorn);
eledormation.GetComponent<Animator>().Play("eleopen");
}
}
void OnTriggerExit2D(Collider2D other)
{
if (other.tag == "Player")
{
Obje.SetActive(false);
}
}
}
The following code means that your player enters another player's collider, do you really want that?
if (other.tag == "Player")
To solve this problem, test the logic of the code. If you want your player to be able to use the E key by entering a certain area, you need to enter the tag of that place in this field. If you want the boxes to open, give them a special tag (Item for e.g) and change the code as follows.
if (other.CompareTag("Item"))
{
// do something..
}
I'm trying to make my character do a drop attack in Unity where I want to ignore the collision detection of boxCollider2D for the moment when character & an enemy collide, then undo the ignore. So far the ignore collision is working but it's not reverting back to detect. So after the first successful drop attack my character can pass through the enemy instead of colliding. Here's my code below,
private Rigidbody2D rb;
private Animator anm;
private Collider2D coll;
private enum State {idle, running, jumping, attacking, falling, hurt}
private void OnCollisionEnter2D(Collision2D other) {
if (other.gameObject.tag == "Enemy") {
Enemy enemy = other.gameObject.GetComponent<Enemy>();
if (state == State.falling && anm.GetBool("dropAtk")) { // hurt enemy if drop attack
enemy.Hurt();
Physics2D.IgnoreCollision(other.gameObject.GetComponent<Collider2D>(), GetComponent<Collider2D>(), true);
} else { // take damange
if (other.gameObject.transform.position.x > transform.position.x) {
PlayerHurt("right");
} else {
PlayerHurt("left");
}
}
}
}
private void OnCollisionExit2D(Collision2D other) {
if (other.gameObject.tag == "Enemy") {
if (coll.IsTouchingLayers(ground)) {
Physics2D.IgnoreCollision(other.gameObject.GetComponent<Collider2D>(), GetComponent<Collider2D>(), false);
}
}
}
How can I re-enable collision detection by turning off the IgnoreCollision when character hits the ground? I'm a novice in unity so any suggestion will be really helpful. Thank you!
hope you get the idea
// Update is called once per frame
void FixedUpdate()
{
if(state==dropattck)
{
ChangeTrigger(player, true);
if(player.transform.position.y<floorvalue/*check your floor value*/)
{
transform.position.y = floorvalue;
}
}else
{
ChangeTrigger(player, false);
}
}
public void ChangeTrigger(GameObject obj,bool tf)
{
if(obj.GetComponent<Collider2D>().isTrigger!=tf)
obj.GetComponent<Collider2D>().isTrigger = tf;
}
a solution that comes to mind is to bound the position on the y axis and then temporarily set your collider to trigger. you bound the y so the player doesn't fall through the floor
otherwise you can check when your animation ends and set the collider back to detecting
Some part of the code works (hp1 -= damage1;), but the second part doesn't work.
Where did I make a mistake?
Here are parts of two scripts:
Player1.cs
private Bullet1 b1;
void Start()
{
b1 = FindObjectOfType<Bullet1>();
}
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Bullet1")
{
hp1 -= damage1; // it works, my player loses hp
Destroy1(); // doesn't work
}
}
void Destroy1()
{
b1.hit1 = true; // hit for bullet1.cs
}
Bullet1.cs
public bool hit1;
void Update()
{
if (hit1)
{
hit1 = false;
Destroy(gameObject);
}
}
If I switch bool hit = true in real time in Unity, destroying works. It means that Bullet1.cs can't recieve hit = true;
If I swap lines hp1 -= damage1; and Destroy1();, my player can't get damage. So, Destroy1(); stops my code and then can't activate other lines. Also if I change Destroy1(); to b1.hit1 = true; nothing new happens.
Just destroy the bullet through the collision instead of using the boolean. It's creating unnecessary resource usage. Of the given code, this is all you need to do to destroy the bullet using the player script. The parts of the bullet script shown are unnecessary. If you want additional logic handled inside the bullet when destroyed then use a OnDestroy function to handle it.
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.tag == "Bullet1")
{
hp1 -= damage1;
Destroy(col.gameobject);
}
}
Is there a way to detect if the collider on the player (with a rigidbody) object is not colliding with any other collider in a 2D environment?
Not per se, but there are two ways you can get the information. It's easiest to keep an int counter, and increment it in OnCollisionEnter and decrement in OnCollisionExit. When the counter is 0, there are no collisions.
Another way, which will tell you which colliders are overlapping but not necessarily if they are touching, is to use a physics function. Note which type of collider you have--sphere, capsule, box. Knowing the size/shape/position of the collider, you can call Physics.OverlapBox, Physics.OverlapCapsule, or Physics.OverlapSphere. Give the function the same shape as your collider, and it will return the colliders that overlap that space. (For 2D colliders, you can use the Physics2D.Overlap* functions.)
/edit - actually piojo's idea with counters is better, just use int instead of bool.
One way would be to add an int to your script called collisions and set it to 0. Then if at any point the collider fires OnCollisionEnter just increment it, and in OnCollisionExit decrement it.
Something like this should work for 3D:
public int collisions = 0;
void OnCollisionEnter(Collision collision)
{
collisions++;
}
void OnCollisionExit(Collision collision)
{
collisions--;
}
https://docs.unity3d.com/ScriptReference/Collider.OnCollisionEnter.html
https://docs.unity3d.com/ScriptReference/Collider.OnCollisionExit.html
I don't understand what's with all the number keeping. I just did this for when my character jumps or falls off the edge and it works great.
Both my player and terrain have colliders. I tagged my terrain with a "Ground" tag.
Then check if I am currently in contact with the collider with OnCollisionStay()
void OnCollisionStay(Collision collision)
{
if (collision.collider.tag == "Ground")
{
if(animator.GetBool("falling") == true)
{
//If I am colliding with the Ground, and if falling is set to true
//set falling to false.
//In my Animator, I have a transition back to walking when falling = false.
animator.SetBool("falling", false);
falling = false;
}
}
}
void OnCollisionExit(Collision collision)
{
if (collision.collider.tag == "Ground")
{
//If I exit the Ground Collider, set falling to True.
//In my animator, I have a transition that changes the animation
//to Falling if falling is true.
animator.SetBool("falling", true);
falling = true;
}
}
void OnCollisionEnter(Collision collision)
{
if (collision.collider.tag == "Obstacle")
{
//If I collide with a wall, I want to fall backwards.
//In my animator controller, if ranIntoWall = true it plays a fall-
//backwards animation and has an exit time.
animator.SetBool("ranIntoWall", true);
falling = true;
//All player movement is inside of an if(!falling){} block
}
}
I have animation Clip for swinging sword. At a specific frame, I added Event. I want when player swing sword, in that case only the enemy could die.
So I added the following OnTriggerEnter Code
void OnTriggerEnter(Collider col)
{
hit = true;
if (hit)
{
if (col.GetComponent<Collider>().tag == "enemy")
{
Destroy(col.gameObject);
}
}
}
When I try to add function OnTriggerEnter (in animation Clip) as animation Event, it is asking me to pass Collider parameter, Which i am not able to add.
Here is the screen shot of Add Event
Please help me , how can I add event with collider ( as parameter ) at a specific frame.. Thanks
Collision and Trigger events are called on their own on every frame.
Call another public method from animation event for your task and put necessary Boolean or Enum there to control collision, trigger after swinging the sword.
public void SwingingSword()
{
isSwingingSword = true; // make it false when not swinging the sword.
}
void OnTriggerEnter(Collider col)
{
hit = true; // not sure what it's job here
if (isSwingingSword && hit)
{
if (col.GetComponent<Collider>().tag == "enemy")
{
Destroy(col.gameObject);
}
}
}