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 AndersonOrion · Oct 28, 2015 at 01:04 PM · c#unity 5distancemousepositionlimitation

How to limit mousePosition based on distance (2D)

Let's say I have a slingshot system that requires the player to pull to throw but I only manage to limit the player pull back distance by position on screen by using Mathf.Clamp which it will lock the mousePosition within the limited screen position.

 Vector2 mosPos = Input.mousePosition;
 Vector3 vel = GetForceFrom(_skills.transform.position, Camera.main.ScreenToWorldPoint(mosPos));
 Vector3 newLimit = new Vector3 (Mathf.Clamp (vel.x, -10, 10),Mathf.Clamp (vel.y, -10, 0));

How do I write a code that does the limitation on the mousePosition based on the distance? Which do I even use and how do I write it?

 Vector3.Distance
 Vector3.magnitude
 Vector3.sqrMagnitude

I want the limitation to be half circle at the bottom and only able to pull to a certain distance. alt text PS: Sorry if the word I used here are bad or confusing.

UPDATE: to the above code, here's what its look like in full for the Update() since it's void I had to modified the code to test around but it still doesn't limit the pull back range. Any thoughts?

         void Update ()
             {
                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                 RaycastHit hit;
         
                 if(isSkillsThrown)
                     return;
                 if (isPlayerTurn)
                 {
                     if (Input.GetMouseButtonDown(0))
                     {
                         if (Physics.Raycast(ray, out hit) && hit.collider.CompareTag("Player"))
                         {
                             isPressed = true;
                             if (!_skills)
                                 createSkills();
                             isClickOnObj = true;
                         }
                         else
                         {
                             isClickOnObj = false;
                         }
                     }
                     else if (Input.GetMouseButtonUp(0))
                     {
                         isPressed = false;
                         GameObject[] trajDes;
                         trajDes = GameObject.FindGameObjectsWithTag("Trajectory");
         
                         for (int i = 0; i < trajDes.Length; i++)
                         {
                             Destroy(trajDes[i].gameObject);
                         }
                         if (isClickOnObj == true)
                         {
                             if (!isSkillsThrown)
                             {
                                 throwSkills();
                             }
                         }
         
                         //isPressed = true;
                         //[Remove comment below for unlimited shots]
                         ManualStart();
                     }
                 }
                 // when mouse button is pressed, cannon is rotated as per mouse movement and projectile trajectory path is displayed.
         
                 if(isPressed)
                 {
     //I would like to add the limit here
                     Vector2 mosPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
                     Vector3 vel = GetForceFrom(_skills.transform.position, mosPos);
         
                     Vector3 newLimit = new Vector3 (Mathf.Clamp (vel.x, -10, 10),Mathf.Clamp (vel.y, -10, 0));
                     Debug.Log("VEL: "+vel+" newLimit: "+newLimit);
                     Vector3 newVel = newLimit * -1;
                     setTrajectoryPoints(transform.position, newVel/_skills.GetComponent<Rigidbody>().mass);
         
                 }
             }
     
     private Vector2 GetForceFrom(Vector3 fromPos, Vector3 toPos)
         {
             return (new Vector2(toPos.x, toPos.y) - new Vector2(fromPos.x, fromPos.y))* power;
         }

I had all the formula correct already but all I need to do left is to place the limit in that specific location which I only know by using Mathf.Clamp and use screen position.

capture.png (146.2 kB)
Comment
Add comment · Show 5
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 AndersonOrion · Nov 16, 2015 at 06:22 AM 0
Share

Still unable to find solution or ways to do it. Any ideas? also bumper road.

avatar image toromano · Nov 16, 2015 at 07:58 AM 0
Share

If we speak on picture, _skills.transform.position is your point A and mosPos is your point B and you just need a relationship as stated in the picture ?

avatar image AndersonOrion · Nov 16, 2015 at 08:25 AM 0
Share

@toromano _skill is my bullet/projectile which starts from A, I wanted to start dragging from point A to Point B (max) while limiting the drag area to half sphere as seen in the picture. Pardon my bad English.

avatar image toromano AndersonOrion · Nov 16, 2015 at 10:47 AM 0
Share

Then you could try something like this:

 Vector2 mosPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 Vector2 pointA = new Vector2(_skills.transform.position.x,_skills.transform.position.y);
 Vector2 diff = mosPos - pointA;
 diff = new Vector2(diff.x, $$anonymous$$athf.$$anonymous$$ax(.0f, diff.y)); // make sure y is not positive
 
 float radius = 10.0f;
 
 if(diff.magnitude > radius)
 {
     diff = diff.normalized * radius;
 }
 Vector2 pointB = pointA + diff;
avatar image AndersonOrion toromano · Nov 17, 2015 at 04:27 AM 0
Share
 Vector2 pointA = new Vector2(_skills.transform.position.x, _skills.transform.position.y);
 Vector2 diff = mosPos - pointA;
 diff = new Vector2(diff.x, $$anonymous$$athf.$$anonymous$$ax(-5.0f, diff.y));
 float radius = 5.0f;
 if (diff.magnitude > radius)
 {
      diff = diff.normalized * radius;
 }
 Vector2 pointB = pointA + diff;
 Vector3 vel = GetForceFrom(_skills.transform.position, pointB);
         
 Vector3 newVel = vel * -1;
 setTrajectoryPoints(transform.position, newVel/_skills.GetComponent<Rigidbody>().mass);

@toromano The original code is the usable but opposite of what I expecting. Ins$$anonymous$$d of limiting at the bottom half of the sphere it limit to the top of the sphere. I modified the code a bit, replacing .0f to -5f makes it able to move the below but it also allow the mouse to move at top of the sphere making it a full circle.

2 Replies

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

Answer by Bunny83 · Nov 23, 2015 at 04:32 AM

All you need to use is Mathf.Min instead of Mathf.Max. Keep the second value to 0f. There's also Vector2.ClampMagnitude which directly does the clamping to a circle:

 Vector2 mosPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 Vector2 pointA = _skills.transform.position;
 Vector2 diff = mosPos - pointA;
 diff.y = Mathf.Min(0f, diff.y);
 
 float radius = 10.0f;
 
 diff = Vector2.ClampMagnitude(diff, radius);
 
 Vector2 pointB = pointA + diff;

Mathf.Max just returns the greater number while Mathf.Min returns the smaller number. They are implemented literally just like that:

 public static float Max(float a, float b)
 {
     if (a > b)
         return a;
     return b;
 }
 
 public static float Min(float a, float b)
 {
     if (a < b)
         return a;
     return b;
 }

When using screen coordinates as well as x-y-world coordinates the y value will grow when you go upwards. So you want to limit your y value of your direction to be 0 or less. So Mathf.Min with your y value will just return the y value when it's smaller than 0. If it's greater than 0 it's limited to 0.

A one side boundary could also simply be done like this:

 if (diff.y > 0f)
     diff.y = 0f;

This would be a tiny bit faster since you save a method call. However such differences are irrelevant.

Comment
Add comment · Show 1 · 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 AndersonOrion · Nov 23, 2015 at 05:01 AM 0
Share

@Bunny83 , many thanks. I didn't know there is Clamp$$anonymous$$agnitude which made the whole process much more simpler, since I have to replace so many other calculation. The code I provide is just s small part of it only.

Nevertheless, thanks again for the help and some explanation on how to use Clamp$$anonymous$$agnitude. Since the Documentation didn't really provide one and not sure what is going on with just description.

avatar image
0

Answer by JoshDangIt · Oct 28, 2015 at 04:47 PM

Try something like this (Untested):

         public Vector3 startingPos; //the starting position of the "slingshot" (you may be able to replace this with transform.position)
         public float maxPullDistance = 4f; //the max distance you can pull the "slingshot" from the startingPos
                 
         Vector3 GetMousePos()
         {
             Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); //get the current mousPos
             if(Vector3.Distance(startingPos, mousePos) <= maxPullDistance) 
             { 
                 return mousePos;
             }
             else
             {
                 //we need to make sure mousePos is within maxPullDistance
                 Vector3 dir = (mousePos - startingPos).normalized;
                 return startingPos + (dir * maxPullDistance);
             }
         }
Comment
Add comment · Show 1 · 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 AndersonOrion · Oct 29, 2015 at 04:51 AM 0
Share

It didn't work. Ins$$anonymous$$d it just release the limitation previously. Now it can pull back as far as your screen goes.

I updated the question with whole Update function.

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

MousePosition with Iso camera movement 1 Answer

What does bounds.sqrdistance do? 1 Answer

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Orbital cannon jitters while following/facing mouse position 1 Answer


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