Checking raycast hit on tagged collider - unity3d

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.

Related

How to move an object in Unity

Hello guys I try to make a city building game the idea is very simple actually Instantiate an Building and move them with mouse after that hit the place button and place.
The issue is if the collider of a another building completely encloses the collider of the building that I am built I can't move new building.
I can probably explain better with pictures.
Issue 1
The first picture my new building you can see collider limits and the second one my old building that I already placed. I Understand the problem but I can not solve it.
And here it is my object drag code
private void OnMouseDrag()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, 1000f,(1 << LayerMask.NameToLayer("Ground"))))
{
Debug.Log(hitInfo.transform.name);
transform.position = SnapToGrid(hitInfo.point);
}
}
private Vector3Int SnapToGrid(Vector3 pos)
{
Vector3 tempPos = pos;
Vector3Int snappedPos;
snappedPos = new Vector3Int(Mathf.RoundToInt(tempPos.x), Mathf.RoundToInt(tempPos.y), Mathf.RoundToInt(tempPos.z));
return snappedPos;
}
Thanks for the help in advance
If I got your question right, I believe that you can solve the problem by enableing the "Is Trigger" option of the previously placed buildings colliders at the moment that a new building is being moved around. Enableing this option in an object makes it so other objects can pass trought it when collision happens.

How would I detect if my player is touching a game object?

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.

Why 'Is Kinematics' works different on HoloLens?

Overview
I wanted to have a cube, that I can drag around the scene with the components Collider, Rigidbody and ObjectManipulator. In play mode everything works fine, but running it on the hololens, the cube starts flying around after dragging it a few time.
Steps to reproduce (All components are set via editor, not via code)
Create new project and set it up for AR/HoloLens
Import MRTK 2.4
Create cube with a Box Collider. Set Is Trigger = true
Add Rigidbody to cube. Set Use Gravity = false and Is Kinematic = true
Add Object Manipulator to cube. I have a method getting called after On Manipulation Ended, but don't know if thats important.
Expected behavior
The rigidbody is set to Is Kinematic = true and Use Gravity = false, so that the cube stays still/stops moving after releasing dragging it. This works while trying it inside the unity play mode. But running it on the hololens, the cube behaves like Is Kinematic = false and starts flying around after interacting with it. Sometimes after the second drag and sometimes after the third time drag.
Error
Before updating this post, I didnt noticed the development console in left corner of my hololens. At the beginng of the scene I get the message [Physics.PhysX] BV4 midphase only supported on intel platforms but at that moment everything is fine. As the cube begins to fly around I get the a NullReferenceExeption: Object reference not set to an instance of an object.
I fixed my issue. I know the approximate cause, but I do not fully understand it. The method, getting called after OnManipulationEnded caused that.
I have a list, getting filled and drained by OnTriggerEnter/-Exit (exit looks the same, except add→remove):
private void OnTriggerEnter(Collider other){
if (other.gameObject.layer != 31) return;
_objectsCollidingWith.Add(other.gameObject);}
OnManipulationEnded triggered this method:
private int GetMeshes(List<KeyValuePair<Transform, Mesh>> transMeshes){
foreach (GameObject go in _objectsCollidingWith)
{
transMeshes.Add(new KeyValuePair<Transform, Mesh>(go.transform , go.GetComponent<MeshFilter>().mesh));
}
return transMeshes.Count;}
So I got alot of nullreferences from GetMeshes, because some gameobject in the list _objectsCollidingWith were null. Thats because the mesh is getting updated every once in a while. That caused a lot of nullreferences until the cube just flew away.
I used the whole time the logging provider via the device portal and couldnt see what is causing this errors. But after running the project via holographic emulation I could see in the console where they were coming from.
How did I fixed my problem?
I found this post because I realized that my OnTriggerExit didn't get called and cased having null objects and some spatial meshes with the same name triggered OnTriggerEnter very often. Also I added this line in the foreach loop in GetMeshes because once in a while there is still a null object:
if (go == null)
continue;
PS: Please forgive the strange code formatting, somehow the editor here on so does not allow me to place the brackets somewhere else

Unity: OnCollisionEnter fires only on NEW entry, but not on NEW entry on different object with same name

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.

How to disable a collider when the trigger of another collider has been entered?

I am building a game where the player runs on a path. When the player triggers a collider, 2 enemy objects will spawn.
What I want is when the first collider trigger has been entered, I want the second collider, which is at a certain distance from the first collider, to get disabled for a certain time. How to achieve this?
If you'd like to disable the colliders so they won't hit or rebound off the wall, for example, then you can change your collider's "isTrigger" variable to true, to change it into a trigger volume instead of a solid collider. This has the effect of disabling it - in that it won't cause other objects to stop or rebound if they hit it.
For example:
function Update() {
if (Input.GetKeyDown(KeyCode.X)) {
collider.isTrigger = true;
}
}
Note that things like MouseOver still work.
If you want to disable that completely, you can try collider.enabled = false. I'm not sure if that works or not. If it doesn't, you can always scale down your collider:
var myOldSize:Vector3;
function DisableBoxCollider(myCollider:BoxCollider)
{
//actually just resizes it
myOldSize=myCollider.size;
myCollider.size=Vector3(0,0,0);
}
function EnableBoxCollider(myCollider:BoxCollider)
{
if(myOldSize!=Vector3(0,0,0))
myCollider.size=myOldSize;
}
You can use the above code to integrate it in your own project. I'm not going to spill out all of the code for you because else we'd miss the point of learning to program and post on Stackoverflow in general. But it should help you to get on your way. Try and play some with the code, and if you have questions, get back here and ask them, providing the question with some code to show what you have tried.