Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Jack-Mariani · Jul 11, 2015 at 03:31 PM · c#2draycast

Raycast - arrow stopped by walls (layer) but not by units (layer)

Hi everyone.

I've a unit in 2d game. An archer that can shoot arrows to other units. We've the following entities, each with a specific layer:

  • UNITS

  • OBSTACLES

  • TARGET (that is a UNIT)

When the archer tries to shoot it check the distance with a racast.

 RaycastHit2D hit = Physics2D.Raycast(shootRayOrigin, headingNormalized, Unit.attackRange - colliderSize, layerMaskRanged);


Then I simply check if hit == Target.

It works as supposed, and when I fire I check if the enemy is in range, and if the ray is not blocked. => If so the Archer shoots.

BUT my other UNITS currently stops the ray.

I'd like to have a ray that is blocked by the OBSTACLE layer, but sends back all the UNITS hit before this OBSTACLE (then I'll check if TARGET is one of these UNITS).

Is it possible to achieve this with a single raycast? Or do I need to make 2 of them, one to check for OBSTACLES, and the second to check for UNITS?

Ray Example: ----U1----U2-----O-----U3--> MAX RANGE ----- U4

The raycast should be able to hit both hit U1 and U2, but shouldn't hit U3 and U4. (Currently my ray can hit just U1, that stops the ray).

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by zach-r-d · Jul 11, 2015 at 10:37 PM

The easiest way to do this is to use Physics2D.RaycastAll. It may be necessary sort the results by distance; I know that the 3D equivalent doesn't return the results sorted.

With the sorted results, it's simply a matter of iterating through them until hitting an obstacle or the end of the array. So in the example provided, the sorted array would contain U1, U2, O, U3 (U4 would not be in it due to the max distance parameter). Iterating through with a loop would perform the desired operation on U1, then U2, and then break out of the loop upon reaching O.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Jack-Mariani · Jul 12, 2015 at 09:18 AM 0
Share

Yes I knew about the Raycast non-sorted results. I didn't thought about sorting them myself. It's a nice solution but it can use some efficiency if I've to sort out too many objects caught by the ray. If there's a more efficient solution it would be great. Thank you very much for your answer.

avatar image zach-r-d · Jul 12, 2015 at 10:29 AM 0
Share

Sorting arrays is actually quite fast. Using the built-in array sorting function:

 System.Array.Sort(hitResults, (r1, r2) => r1.distance - r2.distance);

will sort based on the Introsort algorithm, which runs in O(n log n) time. Furthermore, depending on the spatial partitioning strategy of Unity's physics engine, a method involving multiple raycasts will likely be slower than a single RaycastAll, and will be more error prone in either case. It is possible to implement a custom spatial acceleration data structure, but this should only be a last resort.

avatar image Jack-Mariani · Jul 12, 2015 at 10:54 AM 0
Share

I made as follows, using linq:

 tokenHits = tokenHits.OrderBy(tokenHit => DistanceFromTargetSqr(tokenHit)).ToArray();

The DistanceFromTargetSqr simply returns the sqrmagnitude. I thought it would be faster in this way.

 private float DistanceFromTargetSqr(TokenView$$anonymous$$odel tokenHit)
 {
     return Vector2.Sqr$$anonymous$$agnitude(tokenHit.position - Target.position);
 }

I tested and it worked. Not sure here. I'm not an expert. Is System.Array.Sort quicker? If so I'll use it.

avatar image zach-r-d · Jul 12, 2015 at 11:40 AM 0
Share

Array.Sort will be faster than LINQ since it's in-place rather than having to go from array to enumerator and back to an array. It's also worth noting that the distances are already precomputed in a RaycastHit2D, so there is actually less overhead in using them versus manually computing two square magnitudes.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

22 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Cast multiple rays from an object between two angles? 0 Answers

Raycasting not working? 1 Answer

Reverse object position order 1 Answer

Upon shooting, Raycast target moves infinitely 1 Answer

How to make a simple line of sight in a 2D top down shooter. 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges