Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by Metamalt · Apr 24, 2015 at 06:00 PM · c#unity 5movementtransformfollow

Moving a Game Object in a specific volume/area

Hello All. I am very new at Unity and C# and I think this is my first ever forum post. I have some beginner experience in Java but that's about it.

So I am writing... well lets be honest, trying to write a follow script to control a game object(Sphere) which is connected and relative to another game object.

Inputs touch and mouse.

The Sphere should follow the mouse as I navigate though the screen up and down left and right however the movement is constrained using mathf.clamp. When the mouse/ touch is in the center of the screen the Sphere moves on the z axis to -1 as to not visually collide with the relative game object.

Sphere following mouse/touch:

I have managed to get the Sphere to move on the Z axis from -1 to 0 so it moves in a gradual semicircle motion while being moved on the X Axis. However there is no movement on the Y Axis and the values which I am getting on the debug log don't really add up.

Can anyone shed some light please. I have attached the Script below. Thank you.

 using UnityEngine;
 using System.Collections;
 
 public class Follow_Script : MonoBehaviour {
 
     // Range of movement on X axis this will set from x to -x.
     public float clampForX = 2;
     //Value for minimum/lowest movement value on Y axis.
     public float clampForYmin = -5;
     //Value for maximum/highest movement value on Y axis.
     public float clampForYmax = 10;
     //Value for where the Game object starts off on the Z axis.
     public float startPositionOnZAxis = 0;
 
     
     void FixedUpdate ()
     {
         MoveUpdate ();
     }
 
 
     void MoveUpdate () {
 
         //Vector3 to store position of mouse or touch
         Vector3 pos;
         //keepUpWithPointX to store float value of X axis from pos for mathf.clamp
         float keepUpWithPointX;
         //keepUpWithPointY to store float value of Y axis from pos for mathf.clamp
         float keepUpWithPointY;
         // Variable used to hold mathf.clamp value of X axis
         float clampX;
         // Variable used to hold mathf.clamp value of Y axis
         float clampY;
 
         //if Android is running get touch input and store into Vector3 pos
         if (Application.platform == RuntimePlatform.Android) 
         {
 
             pos = Camera.main.ScreenToWorldPoint (new Vector3 (Input.GetTouch (0).position.x, 
                                                          Input.GetTouch (0).position.y, -1));
         } 
         // else to add in mouse input for testing mostly
         else 
         {
             pos = Camera.main.ScreenToWorldPoint (new Vector3(Input.mousePosition.x, 
                                                            Input.mousePosition.y, -1));
         }
 
         // Passing X Axis position of Game object value to keepUpWithPointX
         // Cursor was not following the mose properly and was lagging behind.
         // * by 30f seems to have solved it with the mouse as input
         // although I have not tried on a touch device yet.
         keepUpWithPointX = pos.x * 30f; 
         // Passing Y Axis position of Game object to keepUpWithPointY
         // This is giving a strange value and not working as expected.
         // Multiplying by 30f does not help.
         keepUpWithPointY = pos.y;
 
         // Added Debug to check what is happening when passing over values.
         Debug.Log ("pos.y " + pos.y + "  " + "keepUpWithPointY " + keepUpWithPointY);
 
         // Clamping X Axis Values into clampX
         clampX = Mathf.Clamp (keepUpWithPointX, -clampForX, clampForX);
 
         // Clamping Y Axis Values into clampY
         clampY = Mathf.Clamp (keepUpWithPointY, clampForYmin, clampForYmax);
 
         Debug.Log ("clampY " + clampY);
 
         /* Give object new position by passing X and Y as Clamp values and calling Rotation
          * in order to move the game object in fixed space on Z axis.
          */
         transform.position = new Vector3 ( -clampX, -clampY, Rotation (clampX)); 
     }
 
     /* create motion for Static Game Object.
      * When mouse/touch at center of sceen the game object moves out on the z axis to 1-
      * When mouse/touch is at max or min of mathf.clamp for movement them game object is
      * moved gradually to 0.
      * Basically Range 1 from 3 to 0
      *              Range 2 from 0 to -1
      * When Range 1 = 3 , Range 2 = 0
      */
     float Rotation(float clamp){
 
         // change from 0 to 1;
         float change;
         float rotation;
 
         float absVal = Mathf.Abs (clamp);
 
         change = absVal / clampForX;
 
         rotation = change - 1;
 
         return rotation;
     }
 }
 


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

Answer by maccabbe · Apr 24, 2015 at 07:16 PM

First, when you do Camera.ScreenPointToWorld with a negative z value you are getting a point behind the camera which you then need to fix by negating the x and y pos.

However the core of your problem is that when you get a point in world space and then modify the z value you also need to modify the x and y values to follow the mouse. That is why x needs to be multiplied by 30 to kind of follow the mouse and why y is also having a hard time when you modify the z to Rotation(clampX).

For instance the code

 void MoveUpdate() {
     Vector3 pos=Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
                                                         Input.mousePosition.y, 10));
 
     float clampX=Mathf.Clamp(pos.x, -clampForX, clampForX);
     float clampY=Mathf.Clamp(pos.y, clampForYmin, clampForYmax);
 
     transform.position=new Vector3(clampX, clampY, pos.z);
 }

But as soon as you modify the new position so z=Rotation(clampX) you'll also have to change clampX and clampY.

Here are a few possible solutions depending on the intended effect. Personally I would go with Physics.Raycast with a fallback since this would be the easiest way to get your object to "avoid" multiple objects.

1) You could take one ScreenToWorldPoint's x pos as an estimate of how far from the camera your point should be and input that value in another ScreenToWorldPoint. This wouldn't be entirely accurate but it might be good enough.

 void MoveUpdate() {
     Vector3 tempPos=Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
                                                         Input.mousePosition.y, 10));
 
     float tempClampX=Mathf.Clamp(tempPos.x, -clampForX, clampForX);
 
     Vector3 pos=Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
                                                         Input.mousePosition.y, Rotation(tempClampX)+5));
 
     float clampX=Mathf.Clamp(pos.x, -clampForX, clampForX);
     float clampY=Mathf.Clamp(pos.y, clampForYmin, clampForYmax);
 
     transform.position=new Vector3(clampX, clampY, pos.z);
 }

You could improve the following code with Plane.Raycast to define a plane z=estimate and intersect it with the ray from the mouse but it would still be inaccurate. You could also try using the screen coordinates to define a z distance from camera or z world position. http://docs.unity3d.com/ScriptReference/Plane.Raycast.html

2) Use Physics.Raycast (with a collider on the other object), Sphere.Raycast, or define your own Cylinder.Raycast. If the mouse ray intersects then use the position, otherwise just use Plane.Raycast with the plane z=value to get the new position.

http://docs.unity3d.com/ScriptReference/Physics.Raycast.html http://docs.unity3d.com/ScriptReference/Physics.SphereCast.html

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 Metamalt · Apr 25, 2015 at 12:28 PM 0
Share

Thank you very much for your answer. It's much more than I expected and it is exactly what I wanted.

Such an elegant solution compared to $$anonymous$$e :)

However if I may, when attaching the script the game object (ball) it is growing 3 times in size.

And I can't really figure out why.

Accuracy wise for my use I think it is since what I am trying to do is : Player holds a ball and the ball follows where the mouse pointer/touch is. So the ball needs to stay within scale with the player and also the ball needs to stay within the body limits since the player does not physically move (therefor using Clamp Values).

I can see I have so much to learn.

Yet again thanks for all the info :)

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

2 People are following this question.

avatar image avatar image

Related Questions

Move Object to location of Trigger? 1 Answer

Making a bubble level (not a game but work tool) 1 Answer

Modifying the Transform of a GameObject 1 Answer

FPSController NOT WORKING 3 Answers

How do I check where my character is moving before he moves there? 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