- Home /
Add force based on drag speed
Hey everyone, I'm wondering how you can add force to a kinematic object based on the drag speed. Say the user is dragging a cube, and it's going to hit another cube. The faster of his dragging speed, the more force will push to another cube.
Thanks!
Steven
Answer by Stardog · Aug 16, 2012 at 03:07 AM
It's not ideal, but this works. It will let you throw the object left/right/up/down in relation to the camera. Made for an FPS style view.
Camera theCam = GameObject.FindGameObjectWithTag("MainCamera").camera;
rigidbody.AddForce(theCam.transform.right * Input.GetAxis("Mouse X") * 10f, ForceMode.Impulse);
rigidbody.AddForce(theCam.transform.up * Input.GetAxis("Mouse Y") * 10f, ForceMode.Impulse);
Add inside an OnMouseUp function after dragging, or similar.
rigidbody.isKinematic should ideally be false when dragging, then make it true before this code.
Here's a rough ready to use script:
using UnityEngine;
using System.Collections;
public class DragDrop : MonoBehaviour {
private Camera theCam;
private bool dragging;
void Start ()
{
theCam = GameObject.FindGameObjectWithTag("MainCamera").camera;
}
void LateUpdate ()
{
// This draws a line (ray) from the camera at a distance of 3
// If it hits something, it moves the object to that point, if not, it moves it to the end of the ray (3 units out)
if (dragging)
{
Ray ray = theCam.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 3f))
{
transform.position = hit.point;
}
else
{
transform.position = ray.GetPoint(3f);
}
}
}
void OnMouseDown()
{
dragging = true;
rigidbody.isKinematic = true;
collider.enabled = false;
}
// Adds the force when you let go based on the Mouse X/Y values.
void OnMouseUp()
{
dragging = false;
rigidbody.isKinematic = false;
collider.enabled = true;
rigidbody.AddForce(theCam.transform.right * Input.GetAxis("Mouse X") * 10f, ForceMode.Impulse);
rigidbody.AddForce(theCam.transform.up * Input.GetAxis("Mouse Y") * 10f, ForceMode.Impulse);
}
}
To make it work without disabling the collider, you can use a LayerMask on the Raycast, or put the object onto the IgnoreRaycast layer.
Answer by Berenger · Feb 03, 2012 at 04:54 PM
You don't need to add the force yourself, the physic engine can take care of it. But of it to work, the cubes you're not dragging mustn't be kinematic, so I suggest you do the switch on mouse down. Also, as a mouse move can be pretty fast, use continuous dynamic collision detection on the dragged cube, and continuous on the others, so it won't just pass through.
If you really want to stick with all-kinematics, you can simulate a force by moving the object by a fading vector ( pos += forward * 5, *4, *3, *2.5 ... ), the vector being, on collision, pos - collider.pos. I doubt that it will be realistic though ...
I did, but it doesn't work, please see the post below. Thanks!
Answer by StevenNieh · Feb 04, 2012 at 06:09 PM
Hey Berenger,
Thanks for your reply.
I tried the code below:
if (theTouch.phase == TouchPhase.Ended || theTouch.phase == TouchPhase.Canceled) {
rigidbody.isKinematic = true;
return;
} else {
rigidbody.isKinematic = false;
var p:Vector3 = Camera.main.ScreenToWorldPoint(
new Vector3 (theTouch.position.x, theTouch.position.y, 300));
transform.position = p;
}
It looks like the dragging cube can pass through other objects. I'm using continuous dynamic collision detection.
Thanks!
Steven
Answer by OleP · Feb 07, 2012 at 02:47 PM
Did you find an answer yet? I'm looking for kinda the same solution. I got a sphere in 2D(x,y), and I'm controling it by touch. When I stop my drag on the sphere, I want it to continue in the angle and speed it had, at the point of release. Furthermore it should maintain a realistic speed/velocity, and eventually stop.
So if you found a solution, please share it :)
Your answer
Follow this Question
Related Questions
Touch controlled ice puck 0 Answers
How to negate this force? 2 Answers
Direction of rotation and ApplyForce 1 Answer
Shooting a cannonball. 6 Answers
How exactly does Rigidbody Drag works? 3 Answers