Jerky motion and inconsistent collision detection with planes with rigid bodies

I have a prefab made up of a plane + rigid body + collider, a “selection tracking” script attached to the main camera and global gravity set to 0 in all directions. I’m trying to be able to instantiate prefabs on mouse / touch up and drag existing ones around.

Here’s my prefab:

[16511-screen+shot+2013-10-13+at+7.33.51+pm.png|16511]

And this is my “selection tracking” code:

using UnityEngine;

public class SelectionTracker : MonoBehaviour {
	public GameObject node;
	
	public class UniversalTouch {
		public Vector2 position;
		public TouchPhase phase;
		
		public UniversalTouch(Touch touch) {
			this.position = touch.position;
			this.phase = touch.phase;
		}
		
		public UniversalTouch(Vector2 position, TouchPhase phase) {
			this.position = position;
			this.phase = phase;
		}
	}
	
	UniversalTouch currentTouch;
	GameObject currentlySelectedObject = null;
	
	//	MonoBehaviour:--------------------------------------------------------------------------------------------------
	
	void Start() {
		currentTouch = null as UniversalTouch;
	}
	
	void FixedUpdate() {
		updateTouch();
		if (currentTouch != null) {
			switch (currentTouch.phase) {
				case TouchPhase.Began: {
					RaycastHit hit;
					if (Physics.Raycast(camera.ScreenPointToRay(currentTouch.position), out hit)) {
						GameObject node = hit.transform.gameObject;
						if (node != null) {
							currentlySelectedObject = node;
							currentlySelectedObject.rigidbody.isKinematic = true;
						}
		            }
					else {
						currentlySelectedObject = null as GameObject;
					}

					break;	
				}
				
				case TouchPhase.Moved: {
						if (currentlySelectedObject != null) {
							currentlySelectedObject.transform.position = camera.ScreenToWorldPoint(new Vector3(currentTouch.position.x, currentTouch.position.y, -camera.transform.position.z));
						}
					
					break;	
				}
				
				case TouchPhase.Stationary: {
					break;	
				}
				
				case TouchPhase.Ended: {
				if (currentlySelectedObject == null) {
					Vector3 newNodeLocation = camera.ScreenToWorldPoint(new Vector3(currentTouch.position.x, currentTouch.position.y, -camera.transform.position.z));
						GameObject newNode = (GameObject)Instantiate(node);
						newNode.transform.position = newNodeLocation;
				}
				else {
					currentlySelectedObject.rigidbody.isKinematic = false;
				}
					break;	
				}
			}
		}		
	}
	
	void updateTouch() {		
		if (Input.touchCount == 1) {
			 currentTouch = new UniversalTouch(Input.touches[0]);
		}
		
		Vector2 newScreenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
		if (Input.GetMouseButton(0)) {			
			if (currentTouch == null) {
				currentTouch = new UniversalTouch(newScreenPosition, TouchPhase.Began);
			}
			else if (currentTouch.phase == TouchPhase.Began || currentTouch.phase == TouchPhase.Stationary || currentTouch.phase == TouchPhase.Moved) {
				if (currentTouch.position == newScreenPosition) {
					currentTouch.phase = TouchPhase.Stationary;
				}
				else {
					currentTouch.phase = TouchPhase.Moved;
					currentTouch.position = newScreenPosition;
				}
			}
		}
		else if (currentTouch != null) {
			if (currentTouch.phase == TouchPhase.Stationary || currentTouch.phase == TouchPhase.Moved) {
				currentTouch.phase = TouchPhase.Ended;
				currentTouch.position = newScreenPosition;
			}
			else {
				currentTouch = null as UniversalTouch;
			}
		}	
	}
	
}

However, I have two problems with this approach:

  1. When I select an existing prefab and drag it around, it doesn’t feel smooth but somewhat jerky.
  2. If I drag whichever prefab I select around fast enough, it does intersect other prefabs. That is, for the one I’m dragging to repel off any other prefabs, I have to drag at a somewhat intermediate speed.

I tried solving these issues by:

  • Replacing Update with FixedUpdate
  • playing around with the different interpolation and collision detection modes in the rigid body
  • switching whichever prefab I am dragging to kinematic.

But I still have the same problems.
Any thoughts on what am I doing wrong?