2

I have a bit of a issue that has me super stumped here. I am going from Key codes , to mouse input - then it later become touch input, but first I want to figure out why i cant do this with just a mouse.

I have a raycast2d setup - and I want the raycast to read collision with my objects on the screen. They are to only react if its an object tagged as "Cat" - essentially once that happens, the cat will swipe out and try to attack. However, it tells me the tagg itself is a reference that instantiated. But the object itself exists by default so im not sure what to do here. Here is my whole script.

 void Update() {
    //if ((Input.GetKeyDown(KeyCode.O) && !attacking && attackTimer <= 0)) {
    if (Input.GetMouseButtonDown(0) && !attacking && attackTimer <= 0) {  //every frame check to see if the mouse has been clicked.
                                                                          //Get the mouse position on the screen and send a raycast into the game world from that position.
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);//Vector 2 means only 2 points of axis are read. worldpoint means check the point of the world. Camera is used to determien what we are looking at, and we fill it with our mouse location.
        RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
        if (hit.collider == null) {//THIS IS THE LINE that says it is having issues. If i REMOVE this line, ANYWHERE i click on the screen activates the cat and thats not what I want to happen.

            Debug.Log("No Object Touched");

            if (hit.collider.CompareTag("Cat")) {
                GameManager.Instance.AudioSource.PlayOneShot(SoundManager.Instance.Swipe);

                attacking = true;
                attackTimer = attackCd;

                attackTrigger.enabled = true;
            }

UPDATED CODE TO MATCH REQUESTED CHANGES: The error im now getting is the NullreferenceException - for:

 if (hit.collider.CompareTag("Cat")) {

This was the same error i was getting before, after retesting with the methods programmer recommended to test.

The console WILL show me, that I have not clicked a object, then show me the null. So I guess its trying to tell me that it doesnt find anythign tagged as cat that exist in the scene? Even though Cat is a custom tag added, and it was applied to the game object that is the cat - with a Box collider. Does it need a material or anything to read it exists? Is there another way I can call this object on click of its specific location?

UPDATE:

       Debug.Log("No Object Touched");
                if (hit.collider) {
                    if (hit.collider.tag == "cat1") { - 

this got rid of the null reference, BUT It doesnt read the cat at all. if i click the cat nothing happens. and yes it is now tagged as "cat1" properly in editor. meanign tags - new custom tag, created cat1 tag. went to game object, changed tag to cat1. Also ensured a colider is on, with is trigger.

Zoe
  • 27,060
  • 21
  • 118
  • 148
LocalNerd
  • 41
  • 1
  • 6
  • Why can't you debug if something is actually hit an then debug what it is? – Logman Mar 14 '17 at 23:13
  • The issue is that i can see that the call for no object called. But there is no object, when i click ont eh object - so the if (hit.collider.tag - is not working. – LocalNerd Mar 15 '17 at 02:09
  • bad explanation - the debug is to state if nothing is hit. Currently, no matter where i click. I get the No object touched debug. No matter where i click. – LocalNerd Mar 15 '17 at 02:10
  • Can you write whole code of `Update` method after question update? Because your original `Update` code is a bit of a nonsens. – Logman Mar 15 '17 at 02:47
  • btw. do `Debug.Log(gameObject.name);` inside `if (hit.collider)` – Logman Mar 15 '17 at 03:12
  • @Logman sure - when i get home today ill post the whole code. I didnt think it was relevant since everything works except the touch. - meaning, it originated as a get input for key code - and i could press O and the cat would then animate, play sound, attack, enable a collide called attack trigger(a separate collide, from the collide that is the cat) – LocalNerd Mar 15 '17 at 11:51

4 Answers4

6

After hours of searching, I finally figured out the reason for getting null.

You need to attach 'New Component' > 'Physics' > 'Box Collider' to your sprite game object.

Now you can use the below code snippet in the script added to your game-object to know if the object is clicked:

private Ray ray;
private RaycastHit hit;

private void Update()
{
    if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) 
    {
        ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);

        if (Physics.Raycast(ray, out hit, Mathf.Infinity))
        {
            if (hit.transform.gameObject.name == "YourGameObject")
            {
                // Do your stuff on click
            }
        }
    }
}

This is the reason why 3d objects can easily detect touches, because they already have colliders attached to them when you create them.

Hope this answer helps someone.

Ashwin
  • 7,277
  • 1
  • 48
  • 70
1

First of all, Physics.Raycast and Physics2D.Raycast are two different stuff.

Physics.Raycast returns true when something is hit while RaycastHit2D returns the the RaycastHit2D so you must check for null when using Physics2D.Raycast or else you will get the NullPointerException exception..

if (hit == null)
{
    Debug.Log("No Object Hit");
    //Return
    return;
}

I will have diff tags for diff cats, so cat, cat1, cat2, cat3. and each script will relate to the tag seperately.

But why are doing this: if (hit.collider.tag == "Cat") since you did not mention that you have a tag called Cat?

Remember that none of the C in the cat tags you listed is capitalized....

That should be if (hit.collider.tag == "cat" || hit.collider.tag == "cat1" || hit.collider.tag == "cat2" || hit.collider.tag == "cat3")

If each cat is doing different stuff then you should do this:

if (hit == null)
{
    Debug.Log("No Object Hit");
    //Return
    return;
}

if (hit.collider.CompareTag("cat"))
{

}
else if (hit.collider.CompareTag("cat1"))
{

}
else if (hit.collider.CompareTag("cat2"))
{

}
else if (hit.collider.CompareTag("cat3"))
{

}

The null checking and the Cat spelling mentioned above is likely what's causing the problem. Remember that you did not mention the error you are getting to begin with.

You don't know how to use tags? Look here.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • Yea it looks like i made a crap ton of mistakes posting here - I actually wasnt getting a error directly. Just nothing happened. I moved it over recently to Mouse input so i could use the console - since I dont know how to check for touch errors without sending it over to the android - in the developer mode it doesnt give me any errors regardless. So I dont have an error to give - – LocalNerd Mar 14 '17 at 14:44
  • 1
    I would also add that `Physics` will interact only with 3D objects ( colliders ) while `Physics2D` will do the oposite ( catch only 2D colliders and pass through 3D ones ) [link to deiscussion](https://forum.unity3d.com/threads/can-3d-physics-interact-with-2d-physics.210961/#post-1418982) – mrogal.ski Mar 14 '17 at 14:44
  • when i DID switch it over to mouse input, the error i got was the exception error you mentioned - so this gives me hope that you are 100% nail on the head. - the cat tagging, "Cat" is correct. there WILL BE cat1, etc etc - but as of now there is ONLY "Cat" with a capital C :) this misunderstanding is my doing, and i apologize for that, and thank you for your clarifications on the ifs. – LocalNerd Mar 14 '17 at 14:45
  • 1
    @m.rogalski That's true. Didn't mention that because it has 2D in it so I think OP should know that. – Programmer Mar 14 '17 at 14:46
  • So , based on this - I need to use only the 2D physics - and use if statements for multiple. – LocalNerd Mar 14 '17 at 14:50
  • haha, yes i did know 2d goes to 2d. I didnt know however they were called differently. – LocalNerd Mar 14 '17 at 14:51
  • im really appreciating all the help from here. Im almost in tears seriously hahaha. This has stopped me from moving entirely. Everything has worked 100% until i decided to put it over to android, from pc platform. yikes. – LocalNerd Mar 14 '17 at 14:52
  • @LocalNerd Ok try that. You may have other problems. You don't have to move this to mouse input. Take a look at [this](http://stackoverflow.com/a/39107871/3785314) post for how to speed up testing on mobile devices. Does it work now? – Programmer Mar 14 '17 at 14:53
  • I iwll keep you posted. im at work right now. i am flabbergasted at how quick people responded here. Im used to unity forums taking days so i posted here as soon as I got into work. ill be back on the floor to figuring his out as soon as i get home today. will keep you posted @Programmer – LocalNerd Mar 14 '17 at 15:20
  • There are more C# programmers here than Unity forumn so you will likely get more help here. – Programmer Mar 14 '17 at 15:38
  • Somehow i got the error to go away - however, i will edit the post to update the new issues. – LocalNerd Mar 14 '17 at 22:30
0

I suggest you to use

hit.collider.CompareTag("Cat")

instead of

hit.collider.tag == "Cat"

And make sure you've set the "Cat" tag in the editor

  • OOOO thank you - i will try that. Earlier someone suggested on the unity forums hit.collider = !=null && the tag - but that didnt work, which i didnt know it was "CompareTag" - I really hope this works. Its the only thing preventing me from completing a full merge to touch controls and has stopped me for ever. I found this site on a whim and that was a really fast response. I really thank you for the idea - Ill let you know ASAP if this fixes it. If you have any other idea, i would love to hear them. – LocalNerd Mar 14 '17 at 14:23
  • You should explain why he should use `CompareTag` as oppose to equality comparison. There's no difference between these two other than performance wise optimizations and thus it should not yield different results in terms of logic. – mrogal.ski Mar 14 '17 at 14:38
  • Im glad i saw this @m.rogalski - I didnt at first, so that saddens me that no difference woudl occur. However you did catch the other result so ill be going over that and posting more here when i get home. Super excited. – LocalNerd Mar 14 '17 at 16:57
  • Yes I should've said that CompareTag is more performance friendly than "tag==" , sorry for that. And in terms of the issue I was suggesting to check if you've set the "Cat" tag in the editor. – Farkhad Gojazadeh Mar 14 '17 at 22:09
0

It is good practice to first check if the hit has a collider, then confirm it is the object you want comparing the tag.

 if (hit.collider) {
     // The hit has a collider
     if (hit.collider.tag=="Cat") {
         Debug.Log("Touched it!");
     }
 }

From the unity Forums: http://answers.unity3d.com/questions/474523/how-can-i-use-hitgameobjecttag.html

  • Yes, the object has a box collider - and it is tagged as "Cat" - what is your opinion on the above of using CompareTag? I really feel that might be it. What do you think? – LocalNerd Mar 14 '17 at 14:38
  • misunderstood this the first read though, will check this out as well when i get home! – LocalNerd Mar 14 '17 at 17:04