1
\$\begingroup\$

Hello i am making a game in which i have to drag a sphere on x axis and z axis on a plane with my mouse and i have created walls from cubes so that my sphere not go anywhere else in the game but while dragging my sphere is not detecting collisions with the wall i also added rigidbody but nothing is working ths is my code thanks

using UnityEngine;
using System.Collections;


public class Ball : MonoBehaviour
{
    Rigidbody r;
    private void Start()
    {

        r = GetComponent<Rigidbody>();

    }

    void OnMouseDrag()
    {

        float distance_to_screen = 
Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
        Vector3 pos_move = Camera.main.ScreenToWorldPoint(new 
Vector3(Input.mousePosition.x, Input.mousePosition.y,  distance_to_screen));
        transform.position = new Vector3(pos_move.x, transform.position.y, 
pos_move.z);

    }

  }
\$\endgroup\$
9
  • \$\begingroup\$ Please elaborate, "not detecting collision" is the sphere going through wall??, Have you forgot to add collider for wall?, Have you accidentally assign is Trigger to one your colliders?? \$\endgroup\$ Jan 18, 2019 at 9:20
  • \$\begingroup\$ @DigvijaysinhGohil i have a default plane and a sphere with ( sphere collider and rigidbody on it) and i have 2 walls on the left and right side of the plane and these walls(cubes) have colliders and rigidbodies with them and is trigger is unchecked but still when i drag my sphere on the plane with my mouse my sphere goes through walls not detecting collisions \$\endgroup\$ Jan 18, 2019 at 9:25
  • \$\begingroup\$ Because you're using transform.position you're basically teleporting your object around, so it's possible it will be able to teleport into or through a wall without any problem. \$\endgroup\$
    – JeffUK
    Jan 18, 2019 at 9:25
  • \$\begingroup\$ so what should i do to detect collisions while dragging \$\endgroup\$ Jan 18, 2019 at 9:27
  • 1
    \$\begingroup\$ @DigvijaysinhGohil Anything you do with the Transform component is still teleportation from the perspective of the physics engine. If you want to avoid teleporting, you need to either "look before you leap" using a physics query to check that the desired travel path is clear before you move, or else route all movement through the Rigidbody and let the physics engine integrate it and handle collisions appropriately. \$\endgroup\$
    – DMGregory
    Jan 19, 2019 at 16:20

3 Answers 3

2
\$\begingroup\$

This is an old thread, but maybe someone wants to do the same..

I found a nice way on the internet to do this:

This thread

https://forum.unity.com/threads/collision-detection-while-dragging-object.182493/

links to this video

https://www.youtube.com/watch?v=ZfjVR-0ZFHU

which explains a solution.

If you don't want to watch or read too much:

Basically you should stop setting the transform, because this cancels physics!

This is all you need:

private void Update()
{
    rb.velocity = (getWorldPosition() - transform.position) * followSpeed;
}

private Vector3 getWorldPosition()
{
    lastMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    lastMousePos.z = 0;
    return lastMousePos - offset;
}

private void OnMouseDown()
{
    lastMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    lastMousePos.z = 0;
    offset = lastMousePos - transform.localPosition;
}
\$\endgroup\$
1
\$\begingroup\$

Because you're using transform.position you're basically teleporting your object around, so it's possible it will be able to teleport into or through a wall without any problem.

You can still detect collisions using the OnCollision event, as this will be triggered when your object rematerialises, but the physics engine won't stop the objects intersecting.

If you want your movement to be limited by physics, you need to use something like either Rigidbody.MovePosition or Rigidbody.AddForce

\$\endgroup\$
3
  • \$\begingroup\$ can u edit my code to give me better idea \$\endgroup\$ Jan 18, 2019 at 9:28
  • \$\begingroup\$ i have added this line of code in my OnMouseDrag() " r.velocity = (pos_move - transform.position) * 1; " this is working now its detecting collisions but now my sphere is also dragging in y axis which i dont need \$\endgroup\$ Jan 18, 2019 at 9:32
  • \$\begingroup\$ i have tried your solutions but not working \$\endgroup\$ Jan 18, 2019 at 9:35
-1
\$\begingroup\$

As @JeffUK points out my mistake a have changed the code a bit

public class Ball : MonoBehaviour
{
    public float speed = 10f;
    Rigidbody r;
    private void Start()
    {
        r = GetComponent<Rigidbody>();
    }

    void OnMouseDrag()
    {
        float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
        Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen));
        // here we are adding force on X and Z axis and i put normalized so the magnitude will be 1
        // It will prevent the super fast moving of the ball
        r.AddForce(new Vector3(pos_move.x, 0f, pos_move.z).normalized * speed * Time.deltaTime, ForceMode.VelocityChange);
    }

    private void OnMouseUp()
    {
        // it will stop moving the ball as soon as you lift the left mouse button up
        r.velocity = Vector3.zero;
        r.angularVelocity = Vector3.zero;
    }
}

I also add the float called speed, you can tweak its value to get your desired speed.

Now the only problem we have is the ball will not move to the mouse pointer, but it will gradually follow it.

And yes this time i have tested it myself. :)

\$\endgroup\$
2
  • \$\begingroup\$ That won't work, once it's collided once it will get stuck and never move again. \$\endgroup\$
    – JeffUK
    Jan 18, 2019 at 17:23
  • \$\begingroup\$ @JeffUK Modified my answer thanks for pointing it out \$\endgroup\$ Jan 19, 2019 at 6:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .