Search Unity

Raycast Alpha Information

Discussion in 'Scripting' started by mrittman, Jun 1, 2009.

  1. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Okay guys here is what I'm trying to do. We are creating a skydiving kind of game where the player falls and tries to avoid obstructions. All the obstructions are, is basically a plane with a texture on it that contains alpha information.

    So basically the areas that are black will be completely transparent and the areas that are white will have a visible texture. Instead of creating geometry, we want the texture to actually do the collision work. So I want to be able to cast a ray off the player and depending on if it sees a texture, it will turn on collision for the plane, in which the player would collide with. If it doesn't see the texture (the ray travels through the transparent alpha) then collision is disabled and the player can fall through.

    I know I would use RaycastHit.textureCoord but not exactly sure how to go about this whole process. If anyone has done something similar to this or might be able to point me in the right direction, it would be extremely appreciated!

    Thanks!
    Matt
     
  2. melmonkey

    melmonkey

    Joined:
    Mar 31, 2009
    Posts:
    373
    Quite honestly, I would think that building the geometry to match the outline of the texture you want, and making that an object with a mesh collider would be a whole lot easier.

    That would be the first path I would go down.
     
  3. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Well from a production standpoint, it's going to be a lot quicker in the long run to do it with textures. Once I get the initial one figured out, then it will be a breeze to do the rest.
     
  4. zigs

    zigs

    Joined:
    May 27, 2009
    Posts:
    145
    That is, if you ever get it done with textures, ofcourse. Don't wanna turn it into project duke nukem forever :)
    I don't know how you would do it with textures only and if its even possible. I would be surprised if it was a standard feature.
    I would go with building geometry aswell. :)

    - Chris
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yep...for an example, see the bunker script in this project.

    --Eric
     
  6. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Hey thanks a lot Eric5h5! I'll definitely check that out! That just might be what I was looking for! =)
     
  7. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Okay here's the code I got from that Invader game:

    Code (csharp):
    1. private var newTexture : Texture2D;
    2. var hole : Texture2D;
    3. private var holeTexArray : Color[];
    4.  
    5. // Check to see if a point intersects with a solid color
    6. function CheckPoint (hitpoint : Vector3, other : Collider) {
    7.     var hit : RaycastHit;
    8.     if (Physics.Raycast (hitpoint, Vector3.forward, hit, 5) ) {
    9.         var tex : Texture2D = renderer.material.mainTexture;
    10.         var pixelUV = hit.textureCoord;
    11.         var uvX : int = pixelUV.x * tex.width;
    12.         var uvY : int = pixelUV.y * tex.height;
    13.  
    14.         // If the hit point isn't transparent, copy the hole texture alpha to an area around that point
    15.         var hitColor = tex.GetPixel(uvX, uvY);
    16.         if (hitColor.a != 0) {
    17.             var dir = 1;
    18.             // Half the time, overlay the hole alpha upside-down  backwards just for variety
    19.             if (Random.value > .5) {
    20.                 uvX -= hole.width/2;
    21.                 uvY -= hole.height/2;
    22.             }
    23.             else {
    24.                 dir = -1;
    25.                 uvX += hole.width/2;
    26.                 uvY += hole.height/2;
    27.             }
    28.             var startX = uvX;
    29.             for (y = 0; y < hole.height; y++) {
    30.                 uvX = startX;
    31.                 for (x = 0; x < hole.width; x++) {
    32.                     // If we didn't want anti-aliasing from the hole texture, we could not bother with thisPix,
    33.                     // and use tex.SetPixel(uvX, uvY, Color.clear);
    34.                     var holeAlpha : float = holeTexArray[x + (y*hole.width)].a;
    35.                     var thisPix : Color = tex.GetPixel(uvX, uvY);
    36.                     if (holeAlpha != 1  thisPix.a != 0) {
    37.                         thisPix.a = holeAlpha;
    38.                         tex.SetPixel(uvX, uvY, thisPix);
    39.                     }
    40.                     uvX += dir;
    41.                 }
    42.                 uvY += dir;
    43.             }
    44.             tex.Apply();
    45.  
    46.             return true;
    47.         }
    48.         else {return false;}
    49.     }
    50.     else {return false;}
    51. }
    But I'm not really sure what to do next. I need to create a declaration that says, if it touches color, then make the plane a collider, if it doesn't touch color, then make it a non-collider. Any ideas!?
     
  8. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Basically you're writing your own collision detection here, which means that you'll also need to write the corresponding collision response yourself.

    Enabling the collider, as you suggested, will not work, because you cannot expect whatever collider you attach to the quad to give a response appropriate to the shape of the texture.
     
  9. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    So are you saying what I'm trying to do will not work? Will I have to create actual geometry for each plane?
     
  10. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    No, I'm saying that you won't be able to rely on Unity for doing the response to the collision. The pixel based approach pretty much bypasses the Unity physics system, replacing it with your own.

    In other words, once you detect a collision using the texture method, you will also have to program how both colliding objects respond to the collision. Whether or not that's worth it, i don't know. That's your decision :p
     
  11. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Ahhh I see. Yeah I think once I get this system working, then building the rest of the planes will be a breeze. And I'm not a programmer so this may take some time :(
     
  12. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Okay guys here is an update on my code:

    Code (csharp):
    1. // Check to see if a point intersects with a solid color
    2. function CheckPoint (hitpoint : Vector3) {
    3.     var hit : RaycastHit;
    4.     if (Physics.Raycast (hitpoint, -Vector3.up, hit, 2) ) {
    5.          Debug.Log(hit.collider.name);
    6.         if (hit.collider.name != "Obstruction")
    7.         return;
    8.         var tex = hit.collider.renderer.material.mainTexture;
    9.         var pixelUV = hit.textureCoord;
    10.         var uvX : int = pixelUV.x * tex.width;
    11.         var uvY : int = pixelUV.y * tex.height;
    12.  
    13.         // If the hit point isn't transparent...
    14.         var hitColor = tex.GetPixel(uvX, uvY);
    15.          if (hitColor.a > 0.05) {
    16.             return true;
    17.         }
    18.         else {return false;}
    19.     }
    20.     else {return false;}
    21. }
    It's still not working properly however. I need it to only report that it touched the object when the player touches a pixel and not the transparent part of each plane. Can anyone help me out?
     
  13. zigs

    zigs

    Joined:
    May 27, 2009
    Posts:
    145
    Did you mean to say
    Code (csharp):
    1. return true;
    ?
     
  14. playemgames

    playemgames

    Joined:
    Apr 30, 2009
    Posts:
    438
    Just wondering if this script indeed works, I am very interested in this development as well since I am using 2D sprites for characters and want to create my own collision system just for those characters.
     
  15. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Oh yeah we got it working =) It works really good actually. There was no need to use actual geometry for the effect we were trying to achieve.
     
  16. playemgames

    playemgames

    Joined:
    Apr 30, 2009
    Posts:
    438
    Great I'll have to try this out then cause it is exactly what I need, will save me time from creating bounding boxes in the interim, and to detect the transparent elements of the texture on the sprite.
     
  17. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Yeah let me know if you need any help! =)
     
  18. playemgames

    playemgames

    Joined:
    Apr 30, 2009
    Posts:
    438
    Thanks I will, btw are you using SpriteManager or just a GameObject with a textured plane? Is that the final script you have in the previous post or is it edited further?
     
  19. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    We're using just a GameObject with a textured plane. No, that is not the final script in the previous example.
     
  20. playemgames

    playemgames

    Joined:
    Apr 30, 2009
    Posts:
    438
    Maybe you can PM me the script or post what you changed so I can see how it is done, I'll see if I can add to it then and post it back after editing. Basically I am using the SpriteManager with some added code to flip through textures to make animations. Since my sprites are huge, I cannot do it as a UV animation, so I have to iterate different collision states per frame.
     
  21. Mazuho

    Mazuho

    Joined:
    Apr 10, 2008
    Posts:
    37
    I just wanted to give my kudos for getting this done despite the negative energy in the early posts =P

    I just had a whim and wanted to know if I could make texture-based collision for a thing I want to do. This (of all the things to search for) was the first post I found and immediately gave me an answer!

    So well done and thanks for sharing!
     
  22. mrittman

    mrittman

    Joined:
    May 11, 2009
    Posts:
    40
    Hey not a problem! We'll have our game done within a couple weeks. I'll post a link to either the online version or a video of gameplay =)
     
  23. AshleyMeah

    AshleyMeah

    Joined:
    Sep 29, 2013
    Posts:
    2
    This is an old article/post, but as no one had a solution to this problem i was looking into - one solution would be to use the method above to detect the alpha/color and such, and then create a second ray cast in the same direction and such from that hit point if you want it to not collide.