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\$ – Digvijaysinh Gohil Jan 18 '19 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\$ – Nouman Khan Jan 18 '19 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 '19 at 9:25
  • \$\begingroup\$ so what should i do to detect collisions while dragging \$\endgroup\$ – Nouman Khan Jan 18 '19 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 '19 at 16:20
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\$ – Nouman Khan Jan 18 '19 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\$ – Nouman Khan Jan 18 '19 at 9:32
  • \$\begingroup\$ i have tried your solutions but not working \$\endgroup\$ – Nouman Khan Jan 18 '19 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 '19 at 17:23
  • \$\begingroup\$ @JeffUK Modified my answer thanks for pointing it out \$\endgroup\$ – Digvijaysinh Gohil Jan 19 '19 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.