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
0
Question by Rchd · Apr 04, 2021 at 04:46 PM · movementraycast2d gamephysics2ddragging

Need Help on Obj Movement via Mouse (particular physics rulles)

Greetings,


I'm working on a 2D Unity puzzle game in which user can drag blocks horizontally with the mouse and place them in correct positions one by one to solve the puzzles in each level. Therefore, I have some fixed-size blocks, each with a


1- Rigidbody2D (for Gravity stuff in case there is empty space that needs to be filled with another block)


2- BoxCollider2D (for the sake of Rigidbody2D , and collision stuff)


3- RayCast2D (to detect distance with other blocks and limit right-side and left-side movements)


4- Single C# script that controls the movement, collision detection and ...


For the dragging part, user clicks on a block (MouseDown) and starts dragging (OnMouseDrag). When released (MouseUp), the block Snaps To Grid ( I've attached a GIF file that illustrates both the movement, and the issue which I need help on)

For the movement part, a block's movement should be limited to available free area on the right and left side. It means that if a block is surrounded by 2 blocks on its right and left side, it shouldn't pass them at all. To do that, I use the Raycast2D functionality that helps me detect collision and limit the movement. Here is the C# script so far :


 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 public class blockProcess : MonoBehaviour
 {

     public Canvas cnv;

     [SerializeField] 
     private Vector3 gridsize = default;
     [SerializeField]
     Transform castPoint_right;
     [SerializeField]
     Transform castPoint_left;
     [SerializeField]
     Transform castPoint_BottomLeft;
     [SerializeField]
     Transform castPoint_Bottomright;
 
 
     float current_mouse_pos;
     bool is_mouse_to_right = false;
     float current_obj_pos;
     float next_obj_pos;
     bool ismovingRight;
 
     bool isClicked = false;
     Vector2 lastAllowedPos;
 
     public float speed;
     private float mZCoord;
     private Vector3 mOffset;
 
 
     void Start()
     {
 
         gridsize = new Vector3(cnv.scaleFactor, 1, 1);
 
     }
 
     string sideCheck_right_collided()
     {
     
         float laserLength = 0.2f;
       
         Vector2 endPos = castPoint_right.position + Vector3.right * laserLength ;
 
         RaycastHit2D hit = Physics2D.Linecast(castPoint_right.position, endPos,  1 << LayerMask.NameToLayer("Default"));
 
         if (hit.collider !=null)
         {
            return hit.collider.tag;
         }
         else
         {
             return "";
         }
     }
   
     string sideCheck_left_collided()
     {
 
    
         float laserLength = 0.2f;
         bool val = false;
         Vector2 endPos = castPoint_left.position + Vector3.left * laserLength;
 
         RaycastHit2D hit = Physics2D.Linecast(castPoint_left.position, endPos, 1 << LayerMask.NameToLayer("Default"));
 
         if (hit.collider != null)
         {
             return hit.collider.tag;
         }
         else
         {
             return "";
         }
 
     }
 
     bool is_mouse_moving_to_right ()
     {
         if (GetMouseAsWorldPoint().x < current_mouse_pos)
         {
             return false;
         }
         else
         {
             return true;
         }
 
     }
 
 
     bool is_obj_moving_to_right ()
     {
         if (next_obj_pos > current_obj_pos)
         {
             return true;
 
         }
         else
         {
             return false;
 
 
         }
     }
 
     private Vector3 GetMouseAsWorldPoint()
 
     {
   
         Vector3 mousePoint = Input.mousePosition;
 
         mousePoint.z = mZCoord;
 
         return Camera.main.ScreenToWorldPoint(mousePoint);
 
     }
 
 
     void OnMouseDrag()
 
     {
        
      
         next_obj_pos = transform.position.x;
 
 
         if (sideCheck_right_collided()=="" && sideCheck_left_collided() == "")
 
           
         {
 
             lastAllowedPos.x = 0;
 
             Vector3 ss = new Vector3(GetMouseAsWorldPoint().x, transform.position.y, GetMouseAsWorldPoint().z);
 
 
             transform.position = Vector3.MoveTowards(transform.position, ss, speed * Time.deltaTime);
 
 
 
         } else
         {
 
 
             lastAllowedPos = new Vector2(transform.position.x, transform.position.y);
 
 
             if (sideCheck_right_collided()!="" && sideCheck_left_collided() == "") {
 
 
                 if (GetMouseAsWorldPoint().x < lastAllowedPos.x && lastAllowedPos.x >0)
             {
 
            
                     Vector3 ss = new Vector3(GetMouseAsWorldPoint().x, transform.position.y, GetMouseAsWorldPoint().z);
                     transform.position = Vector3.MoveTowards(transform.position, ss, speed * Time.deltaTime);
             
            
             }
             }
 
             if (sideCheck_right_collided() == "" && sideCheck_left_collided() != "")
             
                 {
 
   
                 if (GetMouseAsWorldPoint().x > lastAllowedPos.x && lastAllowedPos.x > 0)
                 {
 
 
                     Vector3 ss = new Vector3(GetMouseAsWorldPoint().x, transform.position.y, GetMouseAsWorldPoint().z);
                     transform.position = Vector3.MoveTowards(transform.position, ss, speed * Time.deltaTime);
 
                 }
             }
         }
 }
 }
 }

     private void OnMouseDown()
     {
         isClicked = true;
        
 
         current_obj_pos = transform.position.x;
 
         current_mouse_pos = GetMouseAsWorldPoint().x;
 
         Rigidbody2D rd2 = GetComponent<Rigidbody2D>();
         rd2.gravityScale=0;
 
 
         mZCoord = Camera.main.WorldToScreenPoint(
         gameObject.transform.position).z;
         mOffset = gameObject.transform.position - GetMouseAsWorldPoint();
    
 
     }
 
     private void OnMouseUp()
     {
         isClicked = false;
    
         current_mouse_pos = 0;
 
         Rigidbody2D rd2 = GetComponent<Rigidbody2D>();
         rd2.gravityScale = 1;
 
         SnaptoGrid();
 
     }
 
     private void SnaptoGrid()
     {
        
         var position = new Vector3(Mathf.Round(this.transform.position.x / this.gridsize.x) * this.gridsize.x,
        transform.position.y,
        transform.position.z) ;
 
         this.transform.position = position  ;
     }
 }
 



The issue: As you can see in the GIF attached, If user drags the block normally (with normal reasonable speed), it works like a charm. BUT, when he drags it fast, blocks overlap each other visually and if the dragging is much faster, the Snap To Grid functionality places the moving block in wrong position (pushing another blocking block to the above position and place the moving block under it). I tired testing with different mouse dragging speeds (like 100,35,50 and ...); the less the value, the better the result, but still not Perfect!. I can't decrease the speed as much as I want, because with values less than 50, it affects dragging quality (block moves slower that the mouse).


What would be your approach to solve the issue? any fix to my code ?


Thanks for your attention.


P.S The CastPoints (Red dots) on the bottom of the blocks are for checking collision with specific area of the ground (These are other rules of the game that do not related to the issue in this thread, so no need to mention more)


alt text


movement.gif (366.3 kB)
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
0

Answer by Rchd · Apr 07, 2021 at 02:23 AM

P.S : I don't want to use BoxCollider2D for sides collision detection, because of rules of the game.

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

238 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 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

Need help with Raycast2D 0 Answers

Is there a standardized way for creating a 2D ball physics movement method? 0 Answers

How to move along slopes with a Rigidbody2D? 2 Answers

Big problem with movements and animations 1 Answer

Make EventSystem ignore a collider 0 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