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:
- When I select an existing prefab and drag it around, it doesn’t feel smooth but somewhat jerky.
- 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
withFixedUpdate
- 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?