I’m trying to convert DragRigidbody into C# and I’ve encountered a problem. when I clicked my left mouse button I get the following error ArgumentException: get_main can only be called from the main thread. Following that Unity freezes and crashes. So I couldn’t read what was causing the error from the console. Any idea what is wrong with the script?
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;
public Camera mainCamera = Camera.main;
public RaycastHit hit;
private SpringJoint springJoint;
void Update ()
{
// Make sure the user pressed the mouse down
if (!Input.GetMouseButtonDown (0))
return;
// We need to actually hit an object
if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition), out hit, 100))
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 body = go.AddComponent ("Rigidbody") as Rigidbody;
springJoint = go.AddComponent("SpringJoint") as SpringJoint;
body.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);
}
void DragObject (float distance)
{
float oldDrag = springJoint.connectedBody.drag;
float oldAngularDrag = springJoint.connectedBody.angularDrag;
springJoint.connectedBody.drag = drag;
springJoint.connectedBody.angularDrag = angularDrag;
Camera mainCamera = Camera.main;
while (Input.GetMouseButton (0))
{
Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);
springJoint.transform.position = ray.GetPoint(distance);
}
if (springJoint.connectedBody)
{
springJoint.connectedBody.drag = oldDrag;
springJoint.connectedBody.angularDrag = oldAngularDrag;
springJoint.connectedBody = null;
}
}
}
Problem #1, you need to move the initialization of this variable to Start(). So you will declare the variable:
public Camera mainCamera;
Then you will add:
void Start()
{
mainCamera = Camera.main;
}
Problem #2 is that you’ve removed the ‘yield’ from line 68. That’s what is causing your script to hang Unity. So just below line 67, insert:
yield return null;
Now that you are using ‘yield’, ‘DragObject’ needs to be and IEnumerator. So line 57 becomes:
IEnumerator DragObject (float distance)
And I would change the StartCoroutine() call on line 54 to:
StartCoroutine (DragObject(hit.distance));
Make these changes, and your code will work.
excellent. been looking for this. the old js script sucks. Final working code below:
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;
public Camera mainCamera;
public RaycastHit hit;
private SpringJoint springJoint;
void Start()
{
mainCamera = Camera.main;
}
void Update ()
{
// Make sure the user pressed the mouse down
if (!Input.GetMouseButtonDown (0))
return;
// We need to actually hit an object
if (!Physics.Raycast(mainCamera.ScreenPointToRay(Input.mousePosition), out hit, 100))
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 body = go.AddComponent <Rigidbody>() as Rigidbody;
springJoint = go.AddComponent<SpringJoint>() as SpringJoint;
body.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));
}
IEnumerator DragObject (float distance)
{
float oldDrag = springJoint.connectedBody.drag;
float oldAngularDrag = springJoint.connectedBody.angularDrag;
springJoint.connectedBody.drag = drag;
springJoint.connectedBody.angularDrag = angularDrag;
Camera mainCamera = Camera.main;
while (Input.GetMouseButton (0))
{
Ray ray = mainCamera.ScreenPointToRay (Input.mousePosition);
springJoint.transform.position = ray.GetPoint(distance);
yield return null;
}
if (springJoint.connectedBody)
{
springJoint.connectedBody.drag = oldDrag;
springJoint.connectedBody.angularDrag = oldAngularDrag;
springJoint.connectedBody = null;
}
}
}