DragRigidBody.js for the iphone?

hello,

I want to have the DragDigidbody script work on the iphone. I was wondering how to change the Input.mousePosition and Input.GetMouseButtonDown to a touch position.
really lost here any help would be great. Attach is the script for reference.

thanks
kcarriedo

var spring = 50.0;
var damper = 5.0;
var drag = 10.0;
var angularDrag = 5.0;
var distance = 0.2;
var attachToCenterOfMass = false;

private var springJoint : SpringJoint;

function Update ()
{
	// Make sure the user pressed the mouse down
	if (!Input.GetMouseButtonDown (0))
		return;

	var mainCamera = FindCamera();
		
	// We need to actually hit an object
	var hit : RaycastHit;
	if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition),  hit, 100))
		return;
	// We need to hit a rigidbody that is not kinematic
	if (!hit.rigidbody || hit.rigidbody.isKinematic)
		return;
	
	if (!springJoint)
	{
		var go = new GameObject("Rigidbody dragger");
		body = go.AddComponent ("Rigidbody");
		springJoint = go.AddComponent ("SpringJoint");
		//body.isKinematic = true;
	}
	
	springJoint.transform.position = hit.point;
	if (attachToCenterOfMass)
	{
		var anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position;
		anchor = springJoint.transform.InverseTransformPoint(anchor);
		springJoint.anchor = anchor;
	}
	else
	{
		springJoint.anchor = Vector3.zero;
	}
	
	springJoint.spring = spring;
	springJoint.damper = damper;
	springJoint.maxDistance = distance;
	springJoint.connectedBody = hit.rigidbody;
	
	StartCoroutine ("DragObject", hit.distance);
}

function DragObject (distance : float)
{
	var oldDrag = springJoint.connectedBody.drag;
	var oldAngularDrag = springJoint.connectedBody.angularDrag;
	springJoint.connectedBody.drag = drag;
	springJoint.connectedBody.angularDrag = angularDrag;
	var mainCamera = FindCamera();
	while (Input.GetMouseButton (0))
	{
		var ray = mainCamera.ScreenPointToRay (Input.mousePosition);
		springJoint.transform.position = ray.GetPoint(distance);
		yield;
	}
	if (springJoint.connectedBody)
	{
		springJoint.connectedBody.drag = oldDrag;
		springJoint.connectedBody.angularDrag = oldAngularDrag;
		springJoint.connectedBody = null;
	}
}

function FindCamera ()
{
	if (camera)
		return camera;
	else
		return Camera.main;
}

Anyone?

Im fairly certain that will work as is…

There is one major problem and that is that when I touch the rigidBody drag it does not react the same way has the mouse. Meaning that When I throw the object with the mouse it fly moves but when I trow it on the iphone it goes no where.

any help with this problem would be great.

thanks in advance
kcarriedo

I think that the the problem s with stationary touch is not calculated. Is there a way to work in stationary touch with this script?

Thanks
kcarriedo

I’m starting to get curious too. Can you post an working example scene that’s made in Unity free or Pro? :smile:

Peter.

Using Unity Pro. The scene is setup with this dragrigidbody script attached to a rigidbody but touch drag does not seem to work or touch flick. Please help this all i need left to script.

Thanks in advance
kcarriedo :lol:

http://forum.unity3d.com/viewtopic.php?t=18536&highlight=dragrigidbody :?:

Peter.

Hi,
I’m pretty sure if you run this code as is, then it will never work on iPhone as you can never click the mouse (as there isn’t one)

   // Make sure the user pressed the mouse down 
   if (!Input.GetMouseButtonDown (0)) 
      return;

For this line of code you could replace it with

//Make sure the user is touching the screen
if( iPhoneInput.touchCount == 0 )
return;

the next part…

var hit : RaycastHit; 
   if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition),  hit, 100)) 
      return;

can be replaced with

// We know we have a touch as we have got this far
// get the first touch
var touch = iPhoneInput.GetTouch(0);

var hit : RaycastHit; 
   if (!Physics.Raycast(mainCamera.ScreenPointToRay(touch.position),  hit, 100)) 
      return;

from then on, anywhere you see Input.mousePosition, simply use touch.position.

hope that helps.
[/code]

First of all I want to really Thank rawrman2381238 and Peter for there replies.

I have made the changes that rawman suggested and have the following questions.

  1. I can drag the object but when I flick to throw it, the object moves a little bit then dies. So my question is what are the settings that I should use to throw the object?

a screenshot is attached with the settings

My RigidBody settings are
Mass = 1
Drag = 1
Angular Drag 0.05
Use Gravity Checked

DragRigidbody.js
Spring = 500
Damper = 5
Drag = 10
Angular Drag = 5
Distance = 0.2
Attach to Center Mass = Checked

My second question is what are spring and distance used for?

Thanks in advance [/img]

287376--10286--$image_174.jpg

Any ideas?

Thanks
Kcarriedo

Please help :roll:

Thanks
Kcarriedo

Anyone?

Does anyone have some suggestions

Hi kcarriedo!

I was looking for that feature, so I played a little to solve that and last I also found a solution based on the first corrections posted by sBurgess (thanks :slight_smile: )
I’m not sure is the best one, but I tested it a little and it seems to work correctly :wink:

Basically the main point I found, is that there is the touch phase to manage. The coroutine DragObject must only be called when the touch phase begins, and while the phase is “stationary” or “moved”, the cycle in the coroutine has to continue cycling.

BTW I converted the code to C#, here it is:

using UnityEngine;
using System.Collections;

public class DragRigidbody : MonoBehaviour {

    public float spring = 50.0f;
    public float damper = 5.0f;
    public float drag = 10.0f;
    public float angularDrag = 5.0f;
    public float distance = 0.2f;
    public bool attachToCenterOfMass = false;
    
    private SpringJoint springJoint;
    private iPhoneTouch touch;
    
    void Update (){
        // Make sure the user touched the screen
        if (iPhoneInput.touchCount==0){
            return;
        }
        
        Camera mainCamera = FindCamera();
            
        // We need to actually hit an object
        RaycastHit hit = new RaycastHit();
    
        touch = iPhoneInput.GetTouch(0);
        
        if(touch.phase == iPhoneTouchPhase.Began){
                    
            if (!Physics.Raycast(mainCamera.ScreenPointToRay(touch.position),  out hit, 100.0f))
                    return;
            
            // We need to hit a rigidbody that is not kinematic
            if (!hit.rigidbody || hit.rigidbody.isKinematic)
                return;
            
            
            if (!springJoint){
                GameObject go = new GameObject("Rigidbody dragger");
                
                //Rigidbody is automatically added by SpringJoint
                
                springJoint = (SpringJoint)go.AddComponent ("SpringJoint");
                go.rigidbody.isKinematic = true;
            }
            
            springJoint.transform.position = hit.point;
              
            if (attachToCenterOfMass){
                Vector3 anchor = transform.TransformDirection(hit.rigidbody.centerOfMass) + hit.rigidbody.transform.position;
                anchor = springJoint.transform.InverseTransformPoint(anchor);
                springJoint.anchor = anchor;
            }else{
                springJoint.anchor = Vector3.zero;
            }
            
            springJoint.spring = spring;
            springJoint.damper = damper;
            springJoint.maxDistance = distance;
            springJoint.connectedBody = hit.rigidbody;
            
            StartCoroutine("DragObject", hit.distance);
        }
    }
    
    private int count;
    
    void start(){
        count = 0;
    }
    
    
    IEnumerator DragObject (float distance){
        if(touch.phase == iPhoneTouchPhase.Began){
            float oldDrag = springJoint.connectedBody.drag;
            float oldAngularDrag = springJoint.connectedBody.angularDrag;
            springJoint.connectedBody.drag = drag;
            springJoint.connectedBody.angularDrag = angularDrag;
            Camera mainCamera = FindCamera();
            
            while (touch.phase != iPhoneTouchPhase.Ended 
                   touch.phase != iPhoneTouchPhase.Canceled){
                               
                Ray ray = mainCamera.ScreenPointToRay (touch.position);
                springJoint.transform.position = ray.GetPoint(distance);
                yield return 0;
            }
            
            if (springJoint.connectedBody)
            {
                springJoint.connectedBody.drag = oldDrag;
                springJoint.connectedBody.angularDrag = oldAngularDrag;
                springJoint.connectedBody = null;
            }
        }
    }
    
    Camera FindCamera (){
        if (camera)
            return camera;
        else
            return Camera.main;
    }
}

tiz777 YOU ARE AWESOME!!! Thank you sooooo much I have been working on this problem for awhile now. I’m sure glad there are smart people out there!!!

Thanks again, i have tested your script and it works perfect!!

Thanks again
kcarriedo :lol: :lol: :lol: :lol: :lol: :lol: :lol:

Evening everyone! I’m new here and I’ve been looking for a functionality related to what’s discussed in this thread, namely touching an object and swiping the finger across the iPhone screen to throw it in a given direction.

I’ve got some of the functionality already worked out in a homegrown script, but I wouldn’t call it release-quality reliable, which is why I’ve been searching for an alternate script. I’d really appreciate it if the original poster could share the final revision of the DragRigidBody.js script, with all the corrections that were made during the discussion incorporated, thanks! (if available in JavaScript rather than in C#, so much the better!).

Also, what are the final characteristics of the game objects to which the script is attached…? E.g. rigid body characteristics, type of collider dimensions, etc.

Thank you very much in advance!

-jmpp

PS: My ultimate intent is making the touching-and-throwing functionality available in a 3D game (i.e. including depth in the gameplay), taking into consideration that the touching-and-swiping gesture is a 2D event by definition. Anyone ever done something similar?

Input.GetMouseButtonDown (0) works just fine. As long as you touch with at least one finger, it returns true. Also, mousePosition returns the center of all touches, so for many purposes this works just like a mouse.

So I went ahead and gave the DragRigidBody script a stab at adapting it for Unity iPhone, and here is the result (with some local modifications meant to improve performance a bit and consider all concurrent touches):

var spring : float = 50.0;
var damper : float = 5.0;
var drag : float = 10.0;
var angularDrag : float = 5.0;
var raycastDistance : float = 1000;
var maxDistance : float = 0.2;
var minDistance : float = 0;
var attachToCenterOfMass : boolean = false;
var mainCamera : Camera;

private var dragger : GameObject;
private var springJoint : SpringJoint;
private var touch : iPhoneTouch;


function Start() {
	
	if (!mainCamera) {
		mainCamera = Camera.main;
	}

}


//function Update() {
function FixedUpdate() {
	
	// Make sure the user thouched the screen at least once and then iterate through all the available touches to find a suitable one.
	var touchCount : int = iPhoneInput.touchCount;
	if (!touchCount) {
		return;
	}
	
	var hit : RaycastHit;
	for (var i : int = 0; i < touchCount; i++) {
		touch = iPhoneInput.GetTouch(i);

		// We need to actually hit an object, so lets cast a ray to the position of the touch.
		if (
		  Physics.Raycast(mainCamera.ScreenPointToRay(touch.position),hit,raycastDistance) 
		  touch.phase != iPhoneTouchPhase.Ended 
		  touch.phase != iPhoneTouchPhase.Canceled	  
		) {
		
			// We need to hit a rigidbody that is not kinematic, and if found we make it accessible to gravity
			if (!hit.rigidbody || hit.rigidbody.isKinematic) {
				return;
			}
			hit.rigidbody.useGravity = true;
			
			if (!springJoint) {
				// gotta find a way to destroy this object at some point 'cause once the rigidbody is out of touch it'll just linger there needlessley and possibly consume resources.
				dragger = new GameObject("Rigidbody dragger");
				springJoint = dragger.AddComponent(SpringJoint);
				dragger.rigidbody.isKinematic = true;
			}
			springJoint.transform.position = hit.point;

			if (attachToCenterOfMass) {
				springJoint.anchor = springJoint.transform.InverseTransformPoint(hit.rigidbody.transform.position + transform.TransformDirection(hit.rigidbody.centerOfMass));
			}
			else {
				springJoint.anchor = Vector3.zero;
			}
   
			springJoint.spring = spring;
			springJoint.damper = damper;
			springJoint.maxDistance = maxDistance;
			springJoint.minDistance = minDistance;
			springJoint.connectedBody = hit.rigidbody;
   
			StartCoroutine("DragObject",hit.distance);
			break;
		}
	}	
	
}


function DragObject(distance : float) {

	var oldDrag : float = springJoint.connectedBody.drag;
	var oldAngularDrag : float = springJoint.connectedBody.angularDrag;
	springJoint.connectedBody.drag = drag;
	springJoint.connectedBody.angularDrag = angularDrag;
	
	var ray : Ray;
	while (
	  touch.phase != iPhoneTouchPhase.Ended 
	  touch.phase != iPhoneTouchPhase.Canceled
	) {
		ray = mainCamera.ScreenPointToRay(touch.position);
		springJoint.transform.position = ray.GetPoint(distance);
		yield;
	}
	
	if (springJoint.connectedBody) {
		springJoint.connectedBody.drag = oldDrag;
		springJoint.connectedBody.angularDrag = oldAngularDrag;
		springJoint.connectedBody = null;
	}
//	Destroy(dragger);

}

As it turns out, it handles 3D movement just fine, but its usage of a SpringJoint to perform the dragging of the touched object renders the result a bit unphysical and strange looking when you want to perform actions like tossing the object, rather than dragging it through an always-on touch.

Anyone implemented proper tossing of an object in Unity iPhone? Thanks for any help!

  • jmpp
    [/quote]

Hi, all,

How would you go about constraining the above code to X axis only?

Thanks,

Greg