Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 Ghosthowl · Nov 03, 2016 at 12:49 PM · editormathhandlestrigonometry

How to properly offset a Handles.DrawSolidArc by an angle in different axis?

I have spent far too long on this and I do not understand what is causing this. I have a direction vector that points forward on the Z axis. I would like for my entity to see plus or minus X degrees left or right in front of it.

This works fine the way I am doing it, but when trying to get this to work with Handles.DrawSolidArc instead of being straight, it curves in all sorts of ways, and I can't figure out why.

My code is as follows:

                     var forwardMinY = Quaternion.AngleAxis(-angleDegreesY, perceiver.Entity.CurrentTransform.right) * perceiver.Entity.CurrentTransform.forward;
                     Quaternion spreadAngle = Quaternion.AngleAxis(perceiver.senseOptics.viewOrientation, Vector3.up);
 
                     var angleNew = spreadAngle*forwardMinY;
 
                     Handles.DrawSolidArc(perceiver.Entity.CurrentTransform.position, perceiver.Entity.CurrentTransform.right, angleNew , angleDegreesY * 2,
                         perceiver.senseOptics.rangeMin);

What happpens (Sorry Image Upload is not working for me currently):

https://i.gyazo.com/183a71d7f02d11a3e2e17fd1fbcf7aee.png

What I want (offset in the same direction as up axis handle):

https://gyazo.com/aa953af71fc139d8794d7248dc1693d3

Thank you for your time and help!

Comment
Add comment · Show 3
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 Adam-Mechtley · Nov 03, 2016 at 01:09 PM 0
Share

When you say "I want to offset it by an angle on the Y axis" what exactly do you mean? To me, an angle on the Y-axis is a rotation around the Y-axis. From your image it looks like you want an arc that is in front of the entity and has its normal about the entity's X-axis. Is that correct? If so, can you clarify what the offset is supposed to be? Basically, something like "my entity can see directly in front of itself plus or $$anonymous$$us X degrees to the left/right" or "my entity can see directly in front of itself plus X degrees altitude"

avatar image Ghosthowl Adam-Mechtley · Nov 08, 2016 at 01:33 AM 0
Share

Hi Adam,

Sorry for the confusion. $$anonymous$$y entity can see directly in front of itself $$anonymous$$us X degrees to the left or right, is what I want.

avatar image BenWiller1989 · Sep 13, 2020 at 07:28 PM 0
Share

Its far from perfect, for i used only linear interpolations, but it fits my needs :

     Vector3 calculateVector3(Vector3 targetVector3) {
             if ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) <= 180f) {
                 targetVector3 = new Vector3 (-(1f + ((0f - 1f) / (0f - 180f)) * ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) - 180f)), 0f, (0f + ((1f - 0f) / (0f - 180f)) * ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) - 180f)));
     
             }
             if ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) > 180f) {
                 targetVector3 = new Vector3 (-(0f + ((1f - 0f) / (181f - 360f)) * ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) - 360f)), 0f, ((-1f) + ((0f - (-1f)) / (181f - 360f)) * ((float)$$anonymous$$athf.RoundToInt(scriptObject.viewAngle) - 360f)));
     
             }
             return targetVector3;
         }
 
 
 //Below for the Handles use :
 
 targetVector = calculateVector3 (targetVector);
             Handles.DrawSolidArc (scriptHolder.transform.position, scriptHolder.transform.up,targetVector , scriptHolder.viewAngle, scriptHolder.viewRadius);

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Adam-Mechtley · Nov 08, 2016 at 08:37 AM

The exact details will depend on exactly how your code handles your input parameters, but this is how I go about this sort of situation.

 // these values would actually come from your perceiver data
 // total arc of visiblity in degrees
 float visibilityArc= 30f;
 // how far the entity can see
 float range = 2f;
 Handles.DrawSolidArc (
     perceiver.Entity.CurrentTransform.position,
     Vector3.up,
     // start from rotation that is half of entire arc of vision
     Quaternion.AngleAxis(-0.5f * visibilityArc, Vector3.up) * (
         // subtract out vertical component of forward-facing vector if altitude is not used in visibility test
         transform.forward - Vector3.Dot(transform.forward, Vector3.up) * Vector3.up
     ),
     visibilityArc,
     range
 );

Note, too, that if you're interested in making an interactive version of this handle, I have a package on the Asset Store that might have some APIs that would interest you.

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 Ghosthowl · Nov 09, 2016 at 12:18 AM 0
Share

Thanks for the help Adam,

For the code provided the Handles.DrawSolidArc takes a float as a second to last parameter (which is the view cone) so I cannot apply the spreadAngle there. I tried using the math to subtract out the vertical component, but I get the same results as above. Also in the code provided the arc is on the X plane rather than the Y plane.

I actually own both of your assets, Custom Handles as well as Ragdoll Workshop and do have just this solution working with them. I am trying to achieve the same thing without it in a project that does not use assets.

avatar image Bunny83 Ghosthowl · Nov 09, 2016 at 12:53 AM 0
Share

Actually "DrawSolidArc" is defined as:

 public static void DrawSolidArc(Vector3 center, Vector3 normal, Vector3 from, float angle, float radius)

What Unity version do you use? Also keep in $$anonymous$$d that this is an editor class and can only be used inside the Editor. Apart from that the implementation is not very good ^^. It always creates a temp vector array with 60 elements, so it creates 720 bytes of garbage each time the arc is drawn. It might be better to draw the arc manually ^^.

btw: "normal" and "from" should be perpendicular to each other. Otherwise the resulting "arc" wouldn't be a flat arc, but like a sector of a "cone" (either positive or negative cone).

avatar image Adam-Mechtley Ghosthowl · Nov 09, 2016 at 09:02 AM 1
Share

Sorry I updated the code example--the second to last parameter should have been visibilityArc in my example, rather than spreadAngle. Again I don't know what your exact situation is, but your post above indicated "$$anonymous$$y entity can see directly in front of itself $$anonymous$$us X degrees to the left or right", which is what this example does (where X is actually 1/2 of visibilityArc).

avatar image Ghosthowl Adam-Mechtley · Dec 04, 2016 at 11:36 PM 0
Share

Sorry for some reason I never got an email response back letting me know there was a new reply.

I have tried the code and tried the changes many times editing and trying many things but the results are always the same, it is either a cone or completely flat on the X axis. I replaced the spreadAngle with the orientation (in degrees) it should be offset from forward (which was substituted for X or 1/2 the visibilityArc in the example given). The code for me currently displays flat on the X axis.

I think @Bunny83 is correct though in that the normal and from must always be perpendicular to stop the cone behavior. The problem is I can not get the math right needed to get this to work.

avatar image
0

Answer by Bunny83 · Dec 05, 2016 at 12:09 AM

Well, if you only have a forward axis there are basically two ways you could draw the view area:

  • Either the arc is always flat on the ground

  • or the arc is elevated according to the forward axis you specify

For the first case the normal vector is simply Vector3.up since it's the world up vector so the "arc plane" is world aligned (the world x-z-plane). Unity now has a dedicated method for projecting a vector onto a plane : Vector3.ProjectOnPlane. With this is't really easy to get your forward vector down onto the x-z-plane

 Vector3 newForward = Vector3.ProjectOnPlane(givenForward, Vector3.up).normalized;

For the second case you need a tilted normal vector so that your desired forward axis is inside the tilted plane. If your forward axis comes from a Transform the easiest way to get the according up vector is using transform.up. If the forward axis is elsewhere defined you can simply calculate it using the cross product. First we need the current "right" vector:

 Vector3 right = Vector3.Cross(Vector3.up, givenForward);

With that right vector we can calculate the tilted up vector:

 Vector3 up = Vector3.Cross(givenForward, right);

This will give you the tilted up vector that is perpendicular to the given forward vector.

Of course the starting vector "from" would simply be the forward vector rotated by half the visibility angle around the up vector:

 Vector3 fromVec = Quaternion.AngleAxis(-0.5f * visibilityArc, up) * givenForward;

Now you should have everything you need:

  • The position

  • the normal vector (our "up" vector)

  • the starting vector (our "fromVec")

  • the visibility angle (visibilityArc)

  • and your radius

Like this:

 Handles.DrawSolidArc( yourPosition, up, fromVec, visibilityArc, radius);



Comment
Add comment · 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

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

6 People are following this question.

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

Related Questions

Not so much a scripting problem - Just need smart peoples' help. 2 Answers

Editor Script Handles.Label problem. Labels don't move with gameobject 1 Answer

How to read the current PivotRotation or PivotMode ? 1 Answer

Rotate object's local up towards a vector. 1 Answer

Help Understanding Script 2 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