Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Find point on the edge of a collider from the inside

Discussion in 'Scripting' started by ChickenMission, Jan 16, 2023.

  1. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    Hey everyone,
    I have quite a niche problem. I have a gameobject (with no collider) inside of a tilemap with collision. I want to be able to shoot a raycast from this game object and find the edge of the tilemaps collider. Is there a way to do this?
    I've tried making the tilemap hollow on the inside but that causes physics objects to glitch through it sometimes.

    Any suggestions would be appreciated!

    Edit:
    Here is an image of what I'm trying to do so that it is clearer since my explanation isn't very good:


    The blue lines are raycasts that I am trying to shoot and as you can see, they travel through the tilemap collider, but stop when they leave the collision. What I'm am trying to find is the world positions of when they leave.
    Hope this makes everything a bit more clear!
     
    Last edited: Jan 21, 2023
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,757
    In what direction outward?
     
  3. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    depending on your situation you may be able to get away with just switching the source and destination points of your raycast, so you aren't "shooting from the inside" technically
     
    Owen-Reynolds and Kurt-Dekker like this.
  4. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    This would work but I don’t know the point on the collider that I would hit, that’s what I’m trying to find out from the raycast
     
  5. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    It would be from the game object in multiple different directions outwards
    the project is in 2D btw
     
  6. Juice-Tin

    Juice-Tin

    Joined:
    Jul 22, 2012
    Posts:
    232
    If you're trying to find the closest collider, you could do a for loop with a spherecast centered on your character moving up towards the camera. Each iteration of the for loop make the circle bigger.

    This way you get an expanding circle and can see which point it hit first, then of course stop the loop.
     
  7. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    like i said, it depends on your situation, but if certain conditions are met, it should hit the same point. some conditions would be that you know the collision (if it were to occur) would be within X distance of the original source. another condition would be that there wouldn't be another hit picked up along that path. but imagine a world with just a single box collider. shooting a raycast from within the cube (at point p1) to anywhere (call it p2) should hit the same point as shooting from p2 to p1.

    anyways, a better solution may be to just make your owns double-sided box collider composed of 6 box colliders (or an approximation of whatever shape you have). primitive colliders are a lot cheaper than they are usually assumed to be, especially when they are marked to not not interact with much around them.
     
    Kurt-Dekker likes this.
  8. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    Yes, I've used the "shoot from outside back to me" trick to simulate casting from inside of a box, and it works fine.

    As far as avoiding other objects, a slimy trick is to temporarily change that one box's layer, and cast against only that layer. Or I think Collider.Raycast does the same thing (it's only capable of hitting the collider that called it) (that's if your 2D is using thin 3D boxes. If you're using Collider2D's than Collider2D.raycast seems to do a competely different thing).
     
    TzuriTeshuba likes this.
  9. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    Here's an image showing what I need to do, and hopefully that will make it more clear:
    upload_2023-1-21_11-51-6.png

    The blue lines represent the raycasts I would like to fire, and the origin of those raycasts is the game object. As you can see, there is a 'ceiling' that is part of the same collider (as this is a tilemap collider) so the "shoot from the outside back at me" trick won't work here. Really, what I'm looking for is a way to shoot a raycast that detects the absence of a collider rather than a collider in itself.

    I understand that this may not be possible, but I hope that there is some solution that has the same effects. What I'm looking for is the position of those "collisions".
    Thank you for your help so far!
     

    Attached Files:

  10. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    Unfortunately that wouldn't work, if you look at the image in the reply above, you can see that I'm not trying to find the closest collider.
     
  11. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    I think if you look at my edited question it will become clearer what I'm trying to do, as I'm pretty sure these suggestions won't work. Since I'm using a tilemap collider, I can't split it into smaller colliders. I also don't know the distance to the collision or where p2 is so the first method wouldn't work either.
    Now that I've made my question more clear, do you haver any other suggestions?
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,529
    You cannot perform raycasts from the interior of closed physics shapes, only from the exterior.

    There are 3 closed physics shapes: circle, capsule & polygon and 1 open physics shape which is edge.

    You can perform a raycast against both sides of an open physics shape of which, as mentioned above, there is only a single type: edge.

    Unity has lots of colliders but they only create these 4 physics shapes. For instance, a PolygonCollider2D creates multiple Polygons, CircleCollider2D creates a single circle, CapsuleCollider2D a single capsule, BoxCollider2D a single polygon, EdgeCollider2D creates multiple edges, TilemapCollider2D creates multiple polygons, a CompositeCollider2D can create multiple polygons or edges.

    So if you want to perform a raycast from the "interior" then it has to be an open shape i.e. edges because there technically isn't an interior there.

    So, if you're using a TilemapCollider2D then you'd need to convert all those polygons it creates into edges and the only way to do that currently is to add a CompositeCollider2D and set its generation mode to "Outline" (edges).
     
  13. ChickenMission

    ChickenMission

    Joined:
    Jul 25, 2020
    Posts:
    18
    Hey everyone, I think I've found the solution.

    I set my tilemap to be used by composite, so that only the edges have collision, and now I can just check for collision with the tilemap. I didn't want to use this method before as it caused some objects to glitch through the map, but by changing the rigidbody collision detection from discrete to continuous fixed this.

    Thank you everyone!
     
  14. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,921
    It you're simply pretending to raycast against a flat plane then often a math solution will work better. For example, ray intersection with a plane. Or you may notice a pattern in the results and without even working out the math as to why, write them in a table (as in, the lower-left corner is always (startX-0.621, startY-0.621, 1)).
     
    TzuriTeshuba likes this.