Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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 Z-ion · Oct 14, 2021 at 03:34 PM · raycastingrotate objectmousepositionrtsmouse-drag

Rotate Object with mouse in RTS style game

Hello everyone I wanted to try to make a RTS style game, but I have stuck at the problem for many days. I want to rotate the building using a mouse, eg : when you are in build mode you can place object at the current mouse position, when the player press SHIFT key and move the mouse horizontal then object should rotate according to it. You many be thinking its easy just check if SHIFT key is pressed or not and if it is then rotate it. Yes, you are correct I tried to store the object position when SHIFT is press and rotate accordingly at that position but when I let go of the SHIFT key the mouse position has change as you have rotate the object and it snaps the object position to the new position. Do you guys have any solution to this problem, like after you release SHIFT key mouse position snaps to the object position or some other alternative?

I also tried to create a virtual mouse but then I have to write a whole lot of code for that virtual mouse to interact with the UI elements, so I have left it for now.

For reference you can see Planet Coaster. There you can press down Z key and move mouse horizontal and object rotates and when you let go of the Z key mouse position doesn't change.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by andrew-lukasik · Oct 15, 2021 at 11:58 AM

Answer 1 "#LeaveCursorAlone"

alt text


 using UnityEngine;
 
 public class LetsSpawnAndRotate : MonoBehaviour
 {
     [SerializeField] GameObject _prefab = null, _prefabPreview = null;
     GameObject _instance = null;
     Vector3 _pos, _normal;
     Vector2 _click;
     void Update ()
     {
         var camera = Camera.main;
         var ray = camera.ScreenPointToRay( Input.mousePosition );
 
         if( Input.GetMouseButtonDown(0) )
         {
             if( Physics.Raycast(ray,out var hit) )
             {
                 _pos = hit.point;
                 _normal = hit.normal;
                 _instance = GameObject.Instantiate(
                     _prefabPreview ,
                     _pos ,
                     Quaternion.AngleAxis( 90 , Quaternion.LookRotation(_normal)*Vector3.right ) * Quaternion.LookRotation(_normal)
                 );
                 _click = Input.mousePosition;
             }
         }
 
         if( _instance!=null )
         {
             Vector2 mouseDelta = (Vector2) Input.mousePosition - _click;
             if( Physics.Raycast(ray,out var hit) && (mouseDelta).sqrMagnitude>0 )
             {
                 float yaw = -Mathf.Atan2( mouseDelta.y , mouseDelta.x );
                 Quaternion rotBase = Quaternion.AngleAxis( 90 , Quaternion.LookRotation(_normal)*Vector3.right ) * Quaternion.LookRotation(_normal);
                 Quaternion rotAux = Quaternion.AngleAxis( Mathf.Rad2Deg*yaw , _normal );
                 _instance.transform.rotation = rotAux * rotBase;
             }
             if( Input.GetMouseButtonUp(0) )
             {
                 GameObject.Instantiate( _prefab , _instance.transform.position , _instance.transform.rotation );
                 Destroy( _instance );
                 _instance = null;
             }
         }
     }
     void OnDrawGizmos ()
     {
         Gizmos.DrawRay( _pos , _normal );
     }
 }

Answer 2 "Plane & simple"

link text

 using UnityEngine;
 
 public class LetsRotateAndSpawn : MonoBehaviour
 {
     [SerializeField] GameObject _prefab = null, _prefabPreview = null;
     [SerializeField] Vector3 _planeOrigin = Vector3.zero , _planeNormal = Vector3.up;
     GameObject _instancePreview = null;
     Vector3 _cursorPos = Vector3.zero, _cursorDragPosStart = Vector3.zero;
     Quaternion _cursorRot = Quaternion.identity, _cursorDragRotStart = Quaternion.identity;
     Camera    _camera = null;
     void Start ()
     {
         _camera = Camera.main;
         _instancePreview = GameObject.Instantiate( _prefabPreview );
         _instancePreview.SetActive( false );
     }
     void Update ()
     {
         Plane plane = new Plane( inNormal:_planeNormal , inPoint:_planeOrigin );
         var ray = _camera.ScreenPointToRay( Input.mousePosition );
         if( plane.Raycast( ray , out var hitDist ) )
         {
             Vector3 hitPoint = ray.origin + ray.direction * hitDist;
             _cursorPos = hitPoint;
 
             // store rot pivot info
             if( Input.GetMouseButtonDown(1) )
             {
                 _cursorDragPosStart = hitPoint;
                 _cursorDragRotStart = _cursorRot;
             }
             
             // update rotation
             if( Input.GetMouseButton(1) )
             {
                 Vector3 vec = _cursorPos - _cursorDragPosStart;
                 float screenPxDist = Vector2.Distance( _camera.WorldToScreenPoint(_cursorDragPosStart) , _camera.WorldToScreenPoint(_cursorPos) );
                 if( vec.sqrMagnitude>0 )
                 _cursorRot = Quaternion.Slerp(
                     _cursorDragRotStart ,
                     Quaternion.LookRotation( vec , _planeNormal ) ,
                     Mathf.SmoothStep( 0 , 1 , screenPxDist / ( Mathf.Min(Screen.width,Screen.height) * 0.05f ) )
                 );
             }
 
             // update preview mesh
             if( !_instancePreview.activeSelf ) _instancePreview.SetActive( true );
             _instancePreview.transform.SetPositionAndRotation( hitPoint , _cursorRot );
 
             // spawn prefab
             if( Input.GetMouseButtonDown(0) )
                 GameObject.Instantiate( _prefab , hitPoint , _cursorRot );
         }
         else _instancePreview.SetActive( false );
     }
     void OnDrawGizmos ()
     {
         if( _camera!=null && Input.GetMouseButton(1) )
         {
             Gizmos.color = Color.yellow;
             Vector3 offset = new Vector3{ z=_camera.nearClipPlane*2f };
             Gizmos.DrawLine(
                 _camera.ScreenToWorldPoint( Vector3.Scale( _camera.WorldToScreenPoint(_cursorDragPosStart) , new Vector3{x=1,y=1} ) + offset ) ,
                 _camera.ScreenToWorldPoint( Vector3.Scale( _camera.WorldToScreenPoint(_cursorPos) , new Vector3{x=1,y=1} ) + offset )
             );
         }
         Gizmos.matrix = Matrix4x4.TRS( _planeOrigin , Quaternion.AngleAxis(0,_planeNormal) , Vector3.one );
         Gizmos.DrawWireCube( Vector3.zero , new Vector3{ x=100 , z=100 } );
     }
 }

ourh4tliuqw3gtfg9ahergoihaerg9iuhrg978uguohfopipew.gif (433.7 kB)
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 Z-ion · Oct 15, 2021 at 05:01 PM 0
Share
     void Update()
     {
         if (buildMode)
         {
             if (Input.GetKeyDown(KeyCode.Z))
             {
                 initialRotation += mouseDelta;
                 if (initialRotation < -180) initialRotation += 360;
                 else if (initialRotation > 180) initialRotation -= 360;
             }
             Ray ray = cam.ScreenPointToRay(Input.mousePosition);
             if (Physics.Raycast(ray, out RaycastHit hit))
             {
                 placeholderTile.transform.position = hit.point;
                 placeholderTile.transform.eulerAngles = Vector3.up * initialRotation;
             }
 
         }
     }
 

mouseDelta is the mouse movement from last frame and placholderTile is the preview of the object.

Actually your solution works when you have decide the position and then you can set the rotation. I want to set position and rotation independent; eg: when your mouse is at position A then you can see the preview at that position, then you can change the rotation, then you can also check how it is at different position.

BTW thanks for your solution.

avatar image andrew-lukasik Z-ion · Oct 15, 2021 at 05:57 PM 0
Share

(sidenote) I would advise against using mouseDelta (pixel count) as angle delta because this will make your rotation speed highly dependent on screen resolution. A mere detail but it will come back in QA.

avatar image Z-ion andrew-lukasik · Oct 16, 2021 at 05:23 AM 0
Share

Thanks for the feedback I will try to normalize it and set accordingly.

Also I forget to tell you in preview reply that you can also change the height at which you can build. I am using Plane.Raycast, you can change where plane is and then I place the object at that height.

That's why I also want to set rotation independent. So that player can preview the object at certain height, rotation before actually placing the object.

avatar image andrew-lukasik Z-ion · Oct 18, 2021 at 04:39 PM 0
Share

I just added answer #2 in my main post. It adds fine rotation control before spawning a prefab (drag right mouse button). There is also rotation "undo" built-in as a kind of gesture (if you move mouse cursor back to the same position).

avatar image
0

Answer by Pangamini · Oct 14, 2021 at 10:43 PM

Check this answer on how to set the cursor position to a specific location. It's Windows only though, you'd have to find a specific soludion for different OS

Comment
Add comment · Show 2 · 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 Z-ion · Oct 15, 2021 at 07:52 AM 0
Share

Isn't there any unity API way to do that instead of doing manually for every OS. Like before there was a attribute called screen.lockcursor which lock the cursor at its current position. They made new class Cursor and in that there is a lockmode and when you set Cursor.lockmode to locked it set the mouse position to the center of the screen.

avatar image Pangamini Z-ion · Oct 15, 2021 at 08:51 AM 0
Share

Well, no, that's what is also discussed in that answer I linked you. I guess you could find the solution for the couple of other OSes with mice that you are planning to support

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

135 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 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 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 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 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 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 avatar image avatar image avatar image

Related Questions

Why is my Gameovject not at 0 in the z acis? 2 Answers

Selecting a tile with z as y isometric tilemaps? 3 Answers

Difficulties Clearing/Updating A Variable 0 Answers

Rotating the game object with direction of mouse move 0 Answers

How to rotate a child object vertically with the mouse ? 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