Okay so basically im working on this test project that relies heavily on movement and momentum to complete levels, with a bit of parkour. I need a collider for two reasons, 1. The player touches an object at the end and gets put back into the menu. 2. If the player falls out of the map they die.
I tried a bit messing around with Colliders and at the Docs and while usually id figure it out ive been stumped for 20 minutes looking at Unity's docs and a few questions from here.
public GameObject objectCollider;
public GameObject anotherCollider;
void OnCollisionEnter(Collision collision)
{
if (CollisionDetection.IsTouching(objectCollider.gameObject, anotherCollider.gameObject))
{
Destroy(plr);
}
}
This is what I got so far. I get an error from here and if I switch it to if collider object == the other it errors out.
Basically what I want (If you perfer to just post the answer code but comments on it would still be helpful so i learn!) is for one gameobject (player (but in code its objectCollider)) to be detected if it touches the other (a cube (in code its anotherCollider)) and to execute code (for example Destroy(playerObject))
Thank you for any help you bring here, links, code anything!
Hopefully this is what you're looking for:
public void OnCollisionEnter(Collision collision)
{
if (collision.collider.name == "endObject")
{
//put back into the menu
}
}
Once your player enters a collision, it checks the name of whatever object it collided with. Then you can execute what code you want in the if statement.
You can use collision.collider for many other things, such as collision.collider.tag, but this should give you a start.
Related
I'm trying to make a shooting game and I wanted to check if an enemy is hit using a raycast. Here is the code:
void CheckForShooting()
{
Vector3 mousePos = Input.mousePosition;
RaycastHit2D bulletCheck = Physics2D.Raycast(gunPoint.position,Camera.main.ScreenToWorldPoint(mousePos), gunRange);
Debug.DrawLine(gunPoint.position,Camera.main.ScreenToWorldPoint(mousePos),Color.white);
if(Input.GetButtonDown("Fire1"))
{
if (bulletCheck.collider.tag =="Enemy")
{
print("Hit");
}
}
}
However, even if the raycast is right on top the red enemy the console doesn't print "Hit" and I get the error "NullReferenceException: Object reference not set to an instance of an object", the line that is getting this error is this one bulletCheck.collider.tag =="Enemy".
Here is a ss:
Screenshot]
You need to make a raycast everytime you click the Fire1
Look at this official unity site: https://learn.unity.com/tutorial/let-s-try-shooting-with-raycasts# its explained how to shoot with raycasts.
I wish i could help you directly but i haven't entered Unity in over a year. I hope this helps but for such simple questions its faster to make a google search in my opinion
You just need to check if collider you were supposed to hit is null or not (if it was actually hit). You shoot the ray and expect it to always hit the target in your current code. Just check:
if(bulletCheck.collider != null)
and the code will only run if there was a hit. Only then you can check what was hit.
Also follow the advice and learn about NullReferenceException, it is the most common and basic exception, also one of the easiest to solve.
im trying to track collsion on a unity project and i dont get whats wrong
thats the code i'm working with.
im trying to destroy an object on collision but it doesnt work for some reason.
void OnCollisionEnter(Collision col)
{
if (col.collider.gameObject.tag == "Enemy")
{
Destroy(col.gameObject);
Debug.Log("collided");
}
}
it hits the object but nothing happends i dont get a message and the object doesnt get destroyed
Assuming that the script you posted is a component of some kind of a character (which it should be since you are looking for an Enemy using its tag) and you have proper Rigidbody components with proper settings and Colliders, you should use:
void OnCollisionEnter(Collision col)
{
// You can also use col.gameObject.tag == "Enemy" since it does the same thing as CompareTag().
// Although using col.gameObject.tag == "Enemy" is less performant.
if (col.gameObject.CompareTag("Enemy"))
{
// Using print to get proper information on what is happening.
print("destroyed " + col.gameObject.name);
// Destroying the gameObject with the tag "Enemy"
Destroy(col.gameObject);
}
}
If you wanted to destroy the player object then you should change the tag accordingly and have this script as a component of the enemy.
The most common issues if nothing is showing up can be:
the object has no RigidBody (or RigidBody2D if you are in a 2D project) component
the 2 objects are in 2 layers which don't collide with others (or the same layer which don't collide with itself). Check both objects' layers, and go to Edit -> Project Settings -> Physics (or Physics2D if the project is in 2D) and go at the bottom and check that the layers collide with each other (the check box is on)
one of the 2 colliders is in 2D and the other in 3D
I want my Player to interact with object, so I use Fungus and a script that when the Player is close enough to the object and I press E, it sends a message to Flowchart to activate a block. But it doesn't work.
The script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EventTrigger : MonoBehaviour
{
public bool enter;
int count = 1;
// Use this for initialization
void Start()
{
enter = false;
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player" || other.gameObject.tag == "NPC")
{
enter = true;
if (enter && Input.GetKeyDown(KeyCode.E))
{
Fungus.Flowchart.BroadcastFungusMessage("StartConversation");
}
}
Debug.Log("Entered");
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player" || other.gameObject.tag == "NPC")
{
enter = false;
count = 1;
}
Debug.Log("Exited");
}
}
OnTriggerEnter is called once, and you are listening to input only during one frame.
Consider moving this part to Update:
if (enter && Input.GetKeyDown(KeyCode.E))
{
Fungus.Flowchart.BroadcastFungusMessage("StartConversation");
}
or changing OnTriggerEnter to OnTriggerStay
I'm unfamiliar with Fungus, however, as mentioned in the comments, you're having trouble getting the event to be called upon Collision.
Please take the following into account:
Colliders must be marked IsTrigger for OnTriggerXXX to be called, however, trigger colliders are non-physical, this means if you only have 1 trigger collider in your gameobject, other physical objects can pass through them. To fix this, you can either add a second collider with IsTrigger unchecked, OR, you can uncheck IsTrigger and use OnCollisionXXX instead. I'd suggest the latter solution.
Make sure your colliders can actually collide.
Go to "Edit > Project Settings > Physics", scroll down until you see "Layer Collision Matrix" and make sure the checkbox in the intersection of your objects' layers is checked.
Make sure the two colliders can actually collide during play. This is common with character collisions. You might have a simple box or cylider physical collider around your characters, but have an inner mesh collider be the trigger on your NPC. This way your player character can never collide with the trigger inside the physical collider.
This may sound stupid, but make sure you added your script to correct object. I've lost the count of how many times I went through an unecessary frustration after writting a script and forgetting to add it to the test object.
This should be enough to ensure your events are actually called.
Now, please note that, as pointed out by Hermesis, you're trying to read input in a 1-frame event. You're also using Input.GetKeyDown() which is also a 1-frame check, that is, it will only return true on the frame when the key state has changed.
In your code, the condition (enter && Input.GetKeyDown(KeyCode.E)) will only ever be true, if the user happens to press the key in the exact frame the collision begins.
Again, as noted by Hermesis, consider using "OnXXXStay" instead of "OnXXXEnter".
Here are some tips:
Use OnXXXEnter to display a message to the player so he knows he is in contact with an interactable, and also knows which key(s) can do what.
Use OnXXXStay to respond to keypresses only while the collision is happening.
Use OnXXXExit to clear the message that was set upon collision.
I hope this helps.
I am building a platformer with appearing boxes. The box gets rendered as soon as the player hits it hitbox. This works just fine like so:
public class AppearingBoxes : MonoBehaviour
{
public GameObject Block, RageFace;
bool showBlock = false;
void Start()
{
showBlock = false;
}
void OnCollisionEnter(Collision2D col)
{
if (col.gameObject.name == "Birdy")
{
showBlock = true;
}
}
void FixedUpdate()
{
Block.GetComponent<Renderer>().enabled = showBlock;
RageFace.GetComponent<Renderer>().enabled = showBlock;
}
}
This script is attached to all of those boxes. Each box is an individual box but all with the same script and properties and name:
But here comes the issue. Only the first HIT triggers a box. As you can imagine, the player jumps on top of those invisble boxes and then triggers the one he hits. The player now moves forward over the other boxes that are still invisble and enters there hitboxes. However they dont appear. I believe this is due to the fact that the player is still in the "same" hitbox even though it is a different prefab object. If I jump ontop of the invisible platform and then fall back down to it (i left and then reentered the trigger) the box on which I land immeadiately appears as it should.
So what can I do to get the box to appear as soon as the player touched it even though he is has not left the hitbox of the box before?
Thank you! :)
Try to change the boxes colliders to isTrigger and use instead OnTriggerEnter2D
Or maybe it's because you use OnCollisionEnter instead of OnCollisionEnter2D ?
There is a problem in your code. I don't know if you missed that or it is a typo but you can not use OnCollisionEnter with a Collision2D parameter. Your game would run but it must be giving you this error message:
Script error: OnCollisionEnter
This message parameter has to be of type: Collision
The message will be ignored.
Use OnCollisionEnter2D instead
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.name == "Birdy")
{
showBlock = true;
}
}
Everyone, I did find a "workaround" It sill doesnt really explain the issue but alreast works...
What I did was to increase the size of the BoxCollider for every box just a little bit more. Like 3 pixels bigger than the actual box the player stands on. This solved the issue but makes me wonder: If the player didnt "really" collide with the collider in the first place he wouldve fallen through. But he didnt. Now the colliders a slightly bigger and everything gets triggered just perfect. Maybe a bug in the engine?
Thanks for all your help
He didn't fall because the collider isn't Trigger that's all.
I have a player character, made of some cubes, spheres and a capsule. I created the empty object Player and all body parts of the player are a child of Player. I have two planes, with a moving platform in between. I can walk and jump on the normal planes and the walls, but when the player is on the moving platform the bodyparts of the player fall apart. Maybe it's something really stupid, but I just started with Unity.
This is what goes wrong, the player falls apart on the moving platform: http://nl.tinypic.com/r/207s3sz/9
And below the information about the overview, the player, the body parts, and the moving platform with according character-holder. All bodyparts have the same properties as the body part on the screenshot. Can anyone help me with what goes wrong here? How can I transport the whole player by the moving platform?
HoldCharacter script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HoldCharacter : MonoBehaviour {
void OnTriggerEnter(Collider other) {
other.transform.parent = gameObject.transform;
}
void OnTriggerExit(Collider other)
{
other.transform.parent = null;
}
}
You just need to disable the isTrigger flag. Here are some insights
so how Is Trigger works is that... it will fire OnTriggerExit and OnTriggerEnter, but it will let the object go through it. If you disable the IsTrigger, then you need to move the logic to OnCollisionEnter on OnCollisionExit methods. If the isTrigger uncheck kind of worked, maybe is just the fact that you move the logic for HoldCharacter to OnCollisionEnter and OnCollisionEnd respectively Like this:
void OnCollisionEnter(Collision collisionInfo) {
collisionInfo.gameObject.transform.parent = gameObject.transform;
}
void OnCollisionExit(Collision collisionInfo) {
collisionInfo.gameObject.transform.parent = null;
}
Regards
If I'm correct, the children of objects with Rigidbodys have physics as well. Maybe put the rigidbody on a child of the player, like so.
Player
-head
-arms
-legs
-empty gameobject with rigidbody