Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

wide raycast?

Discussion in 'Scripting' started by Denisowator, May 24, 2017.

  1. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I want to make a raycast projecting from the camera, but with a radius (CapsuleCast), so that there's a lot of leeway for looking and still triggering what I need to trigger.

    I basically want to detect if something is visible on the screen, but I want to not trigger it if it's behind a wall, which is why I'm using casts.

    I've looked around, and read about CapsuleCast on the Manual, but for some reason I can't get it working, even after watching multiple tutorials.

    This is what I got so far:
    Code (CSharp):
    1. if (Physics.CapsuleCast (transform.position, transform.position.x, transform.forward, Mathf.Infinity, out hit)) {
    2.  
    3. }
    I converted it from a normal Raycast, so some stuff might be there that is not supposed to. As I said, I read the manual, but I just don't understand some parts, so I just kept them the same as for the raycast.

    First thing is, I'm not sure how to specify the second transform position.

    And I'm generally not sure how to set the whole thing up. I want it to have one at the camera's position, and the other away from the camera (so it would be laying down and not standing).

    Also, I don't want to use a LayerMask, so I don't know if I can just not include it without any errors.
     
    Last edited: May 24, 2017
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Could you explain (a bit more) what the cast is looking to find/discover? Just curious. May lead to "why not using layer mask" and/or maybe some other way of doing what you want to do .. (only maybe:))

    As for what the 2 points are: They are the position of the centre of the sphere at both ends of the capsule.
     
    Denisowator likes this.
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    yeah, the method you appear to be calling is this overload:
    Code (csharp):
    1. public static bool CapsuleCast(Vector3 point1, Vector3 point2, float radius, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);
    https://docs.unity3d.com/ScriptReference/Physics.CapsuleCast.html

    This means you're passing a float (position.x) as point2, which should be a Vector3.

    Then the forward as your radius... that'a Vector3 as a float.

    Then Mathf.infinity as your direction... a float where you should have a Vector3.

    Basically you're calling this all wrong!

    ...

    Also, you may prefer a SphereCast really, from the sounds of your description:
    https://docs.unity3d.com/ScriptReference/Physics.SphereCast.html

    Check the documentation, you need to pass the appropriate values as the appropriate parameters.
     
    Denisowator likes this.
  4. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I'm using a tag to detect a specific object in the scene.
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Just 1 object? Could you maybe set this up with OnBecameVisible/Invisible maybe?
    @lordofduct gave some good feedback.

    Lastly, if it's 1 or a few objects, and the became visible thing is not great for you, layermask is nice, in that it cuts down how much work has to be done, that's the only reason i mentioned it may be good. If you don't mind or think it's not important, that's cool with me if it's cool with you :)
     
    Denisowator likes this.
  6. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Would that (the layermask) account for the object being behind another one (in which case it wouldn't trigger)?
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ahh, wow.. my brain. lol My bad.. I see what you're talking about. :)
    You're initial thought was correct, I just wasn't getting it at first.
     
    Denisowator likes this.
  8. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    So I've got this for a SphereCast:
    Code (CSharp):
    1. if (Physics.SphereCast(transform.position, 45f, transform.forward, out hit, Mathf.Infinity)) {
    2.  
    3. }
    I'm not getting any errors but it's not working either.

    Inside this, I have a nested "if" statement, checking for the tagged object being hit.
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    It's returning false or returning true but not finding your tag?
     
    Denisowator likes this.
  10. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    No, the whole cast doesn't seem to be working properly.

    I can get it to trigger, but only in certain positions in relation to the object.

    I think the cast might be somehow positioned incorrectly, or facing the wrong way.

    For example, if I look at the object from my spawn position, nothing happens, but if I move around slightly, it does. I also walked behind the object, and slightly to its right, and it wasn't triggering either.
     
    Last edited: May 24, 2017
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Okay, I just tried this.. and here's what I discovered : If you're hitting anything at the start, it will fail. At least this is what I think I found out. I've moved some cubes around and tested it :)

    Edit: Yep, pretty sure that is it. I put a radius of 2 for the cast, and put a cube at 0,0,2.4 and the one with the casting script at 0,0,0 .. no hit. then moved the first one to 0,0,2.55 (centre of the cube is the start, I think), and it hit. :)
    If that's the case and your area is huge, if it's just 1 or a few objects, I might recommend again OnBecameVisible/Invisible (as I think this should work for "if it's seen"). The other option, I'm guessing would be to spherecast on a layer, and if you get 'true', to linecast, maybe, and if that hits it, as well, you've got a success. I dunno, just thinking out loud :) (the linecast wouldn't be on a layer, but you'd have a target to aim at/direction, I think..)
     
    Last edited: May 24, 2017
    Denisowator likes this.
  12. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    But it also doesn't trigger at certain locations. As I said, if I walk behind the object and slightly to the right, then look at it, it won't trigger.

    That's still helpful to know though. :)
     
    Last edited: May 24, 2017
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hm.. Right, so that's not contradicting what I wrote in my "observations" --- ie: Are you too close to the object, so that it's inside the spherecast when it begins, thereby not producing a hit..?
     
    Denisowator likes this.
  14. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Yes. I had the radius set to 5, which caused the object to be inside the cast at the start. I reduced it to 2, and now it works.
    The "back-right" situation still persists.
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, at this point.. you can imagine that the spherecast alone can't do what you were originally wanting, I'd imagine. I mean, once you're too close/the sphere is too big, it won't work.
    I should alter my previous response about spherecasting a layer, as I imagine the same thing would happen. I'd change that to "overlapsphere" maybe ;)
    What do you think?
     
    Denisowator likes this.
  16. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    SphereCast will not pick up thing inside itself when cast.

    What you should do is set the start position to be: position - (direction * radius)

    This should catch everything in front... though it could also catch some things above and below yet slightly behind the camera.

    Another option is to do a BoxCast:
    https://docs.unity3d.com/ScriptReference/Physics.BoxCast.html

    And again, position it to start from behind the camera. Though remember, you need to include the orientation, just use the camera's rotation for that.

    This will resolve grabbing those things slight above and below.
     
    Denisowator likes this.
  17. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I think that first thing actually got it working ( "(direction * radius)" ). And I also discovered that what is causing it to stop working from certain positions, is the trees painted on the terrain. Because the SphereCast is hitting those, and stopping.

    And I just realized what a problem that is. Because the trees are part of the terrain, therefore I can't somehow exclude the terrain from the cast checking, in case the object is behind a hill or something like that. But I need to be able to trigger stuff when even the slightest part of the object is in view.

    Could this be achieved by checking if it's visible, and also projecting a raycast to see if something is in front of it?

    Like make so that if it's visible and there's something in front of it, then trigger stuff, but it's it's not visible and there's something in front of it, don't trigger stuff.

    Because there's going to be a lot of scenarios when the object is partly obstructed, and I want it to trigger stuff in those cases. If if it's not and it's behind the terrain, it won't trigger.

    Since just checking for "visible" doesn't check for objects in front of it, which would result in triggering even if the object is fully obstructed.
     
    Last edited: May 24, 2017
  18. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I think it's worth a shot to try visible. Ya, you could cast a line after (but if it's visible, does it have to be all visible , not partially blocked.. ? otherwise, just being visible would be "done").
    At least try and see! lol
     
    Denisowator likes this.
  19. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I updated my post.

    Basically I just added a statement saying, that "visible" doesn't check for stuff in front of it. So if it was visible (rendered) but it was fully obstructed by another object, it would still trigger. That's why I suggested a "visible" and "raycast" combo.
     
  20. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I will try that tomorrow, as it is getting late and I have college early in the morning. I will let you guys know how it goes and if I have any further issues.
     
  21. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ah, okay.. yes, combo sounds good. I didn't know that being obstructed meant that "visible" would be true ;) Never really tested that myself. I thought of one last idea while we're at it, if it's just 1 object (i keep repeating that to be sure, lol sorry), would maybe an angle check + a raycast also work? I mean, in the end you only need 1 option..
    Look forward to hearing how it goes next time you try :)
     
    Denisowator likes this.
  22. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Yes it is just 1 object. ;)

    Could you explain how the angle check works/would work? I'm gonna go offline now, but I'll read your response tomorrow while waiting between classes.
     
  23. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You know, after I thought about what I wrote it occurred to me, that while possibly valid.. what's the point if you're going to try visible. lol I'm just tired, sorry. Angle, I was thinking.. if the angle is in your forward arc for the target. I dunno if that makes sense, I'm going to pass on this until tomorrow. :)
     
    Denisowator likes this.
  24. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    I was thinking about the combo thing, and I realized a few things.

    I would only be able to detect if the object "isVisible" to the camera, while being obstructed by an object. So let's say it was behind a hill, it would be visible to the camera, but the raycast would prevent the trigger.

    However, if the object was visible to the camera, and only partly obstructed, it would still prevent the trigger from going off since the raycast would hit something that's not the tagged object. That is, unless I had thousands of rays covering the whole screen. And if none of them hit that tagged object, it wouldn't trigger. But that's obviously not very good. For one thing, it would definitely somewhat decrease the performance, and it would take a while to create a specific number and pattern of raycasts to cover most (if not the whole) of the screen.

    So unless there is something I'm not thinking of, the combo isn't going to work.

    Not to mention, I've been reading about the "Renderer.isVisible" on the manual, including the whole "Renderer" page, and I just can't figure out how to even set that up. Like do I make it a whole method, do I create a GameObject reference, set that equal to "Renderer" and write "Object.isVisible" instead? I've tried a lot of stuff, and I just can't figure out how the whole "isVisible" works (code-wise). And I swear there are like no videos on this, because I've been looking for an hour now, and found absolutely no video titled "Unity isVisible tutorial" or anything of the sort.

    I'm having some thoughts, but I would need to know how to set up the "isVisible", and as I said, I can't find any tutorials. I don't need the object to neither receive, nor cast shadows. Therefore, if I used "isVisible" with occlusion culling (which I currently have on), then that would work exactly how I need.

    If the object is fully culled, it won't render (if "isVisible" doesn't include culled objects), therefore "isVisible" won't be true, and so nothing will trigger, but if it's partially obstructed, it's still gonna render, therefore it will trigger. Which is exactly what I want.

    The only problem I see with this, is that if the object experiences occlusion culling problems, like disappearing when at the edge of the screen, then it's going to be a big problem, since in my case the object has to always be visible if possible. And something like it disappearing randomly would completely ruin the whole game.
     
    Last edited: May 25, 2017
  25. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, I too, can't think of a way to figure out if it's only partially visible on the screen. When I first suggested the visibility thing, I thought that included taking into account if it was blocked by another object, but that's not the case.
    And as you pointed out, you could raycast and maybe you'll hit the target or maybe it'll hit something else but the target is partially visible.
    I'm stumped, personally. I'm not sure how you'd figure this out. Could you have a few small box/sphere casts for the object, and if even one of them doesn't hit anything, that counts as okay? This is a pretty unique problem, I'd say :)

    Maybe someone else will have some more feedback.
     
    Denisowator likes this.
  26. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918
    Well I did suggest using only isVisible, and the occlusion culling would take care of the object being obstructed. But I don't know for sure if it will work, that's why I need to set up the isVisible. But I can't figure out how.

    Of course, that is if culled objects count as not seen by cameras in the backbone code of the engine.

    Here's a simple explanation of how I think it would work:

    Fully behind object = isVisible would be true, but object isn't rendered due to occlusion culling, so isVisible is false.

    Partly behind object = isVisible would be true, and object is rendered, so it's still true.

    Again, I can only be sure if I set up the isVisible and actually test it (which I don't know how to).
     
  27. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I looked at something new (for me) CullingGroup.. but after messing around with it for a bit, I couldn't get it to work, either :).
    Not sure what else there is, but you'd think there's something. Gotta go for a while. Good luck, though :)
     
    Denisowator likes this.
  28. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    By the way, if you ever do solve this.. it'll be cool to know.
    And then, and only then will I ever tell someone again that I know how to assist. lol :)
     
    Denisowator likes this.
  29. Denisowator

    Denisowator

    Joined:
    Apr 22, 2014
    Posts:
    918