- Home /
GameObject dropping and laging while dragging on Android
I am using touch.phase==TouchPhase.Moved
and touch.phase==TouchPhase.Ended
for moving Game Object. But sometimes in certain phones there is lag while moving objects though not much but still visible. And then sometimes while moving objects, they just stop moving at certain point and the i have to go back again for moving them . As for lag is concerned some of the post says its due to hardware and android OS ,can be considered but what about the dropping of objects. What causes them this to happens.
EDIT::
This question whichyou answered will give you an idea of what is happening.I know its a huge code so am describing what is happening.
First it checks if any GUI layout is visible or not. After that it checks the status of the sphere
.
If it is just created
or draggedBeforeBond
that means it is not involved in any bond formation. So when user drags it it checks if it isVisible
or not. If its value is true
then it deletes the sphere and all properties which are related to it which are saved in TestScript
.
If status
for the sphere
is neither of two then it is involved in some bond formation . Again it checks the same thing if the sphere is visible or not. If it is true
then it will delete the sphere and all the bond related to it. Deletes all the info of both sphere and the bond. If it is false
then it will disable the renderer
of the bonds.
And in the if(touch.phase==TouchPhase.Ended )
it enables
the renderer
of the bonds.
function Update()
{
if(!buttonsLayoutScript.guiVisible && bondScript.clickable)
{
for (var touch : Touch in Input.touches)
{
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, hit))
{
sphereIndex = testscript.sphereCollider.IndexOf ( hit.collider );
//Checking if the element selected is a sphere or not. -1 means that it is not the sphere
if ( sphereIndex!= -1 )
{
var element2:GameObject=testscript.elementArray[sphereIndex];
// checking if dragged has happened ..
if(touch.phase==TouchPhase.Moved)
{
inside=true;
elementNumber=testscript.count;
var elementStatus=testscript.elementStatus[sphereIndex];
//checking if the status is created or before bond is formed.. this is because if the element is dragged before bond is formed that
//means that i dont have to change the bond position and if delete occurs then just change the left side of the equation and
//not the right side.!
if(testscript.elementStatus[sphereIndex]=="Created" || testscript.elementStatus[sphereIndex]=="DraggedBeforeBond")
{
cameraTransform = Camera.main.transform.InverseTransformPoint(0, 0, 0);
element2.transform.position = Camera.main.ScreenToWorldPoint(new Vector3 (touch.position.x, touch.position.y, cameraTransform.z));
element2.transform.position.z=element2.transform.position.z-5f;
bondScript.touchCount=0;
moved=false;
elementPosition=element2.transform.position;
testscript.elementPosition[sphereIndex]=elementPosition.x.ToString()+","+elementPosition.y.ToString()+","+elementPosition.x.ToString();
if(!element2.renderer.isVisible)
{
elementSymbol=testscript.elementName[sphereIndex];
var t:TextMesh = testtext.GetComponent(TextMesh);
var oldtext=t.text;
var index=oldtext.IndexOf(">");
var rightSide=oldtext.Substring(index+1);
leftHandSide=leftSideCheck();
if(leftHandSide=="")
{
t.text="";
}
else
{
t.text=leftHandSide+" -> "+rightSide;
}
testscript.elementArray.RemoveAt(sphereIndex);
testscript.sphereCollider.RemoveAt(sphereIndex);
testscript.elementName.RemoveAt(sphereIndex);
testscript.elementStatus.RemoveAt(sphereIndex);
testscript.elementValency.RemoveAt(sphereIndex);
testscript.elementBondCount.RemoveAt(sphereIndex);
testscript.elementWithWhichBondFormed.RemoveAt(sphereIndex);
testscript.elementText.RemoveAt(sphereIndex);
testscript.elementPosition.RemoveAt(sphereIndex);
testscript.elementColor.RemoveAt(sphereIndex);
testscript.elementSphereName.RemoveAt(sphereIndex);
testscript.element_plane.RemoveAt(elementCount);
testscript.element_sphere.RemoveAt(elementCount);
Destroy(element2);
}
}
else
{
// If the element status is Dragged after bond then make all the bond invisible and
//If the element is dragged and it is deleted, then delete all the bond related to that element along with the element
//Change the text as well..
//And change the status of other element as draggedbeforebond
cameraTransform = Camera.main.transform.InverseTransformPoint(0, 0, 0);
element2.transform.position = Camera.main.ScreenToWorldPoint(new Vector3 (touch.position.x, touch.position.y, cameraTransform.z));
element2.transform.position.z=element2.transform.position.z+8f;
elementStatus="DraggedAfterBond";
testscript.elementStatus[sphereIndex]="DraggedAfterBond";
bondScript.touchCount=0;
elementPosition=element2.transform.position;
elementSymbol=testscript.elementName[sphereIndex];
testscript.elementPosition[sphereIndex]=elementPosition.x.ToString()+","+elementPosition.y.ToString()+","+elementPosition.x.ToString();
var ElementBondIds=testscript.elementWithWhichBondFormed[sphereIndex];
var individualId=new Array();
individualId=ElementBondIds.Split(","[0]);
var totalBond1= individualId.length;
if(!element2.renderer.isVisible)
{
if(totalBond1>0)
{
if(individualId[0]!="None")
{
leftHandSide=leftSideCheck();
for(var elementCount=0;elementCount<individualId.length;elementCount++)
{
var elementBondName:String=individualId[elementCount];
var seperatedArray=new Array();
seperatedArray = elementBondName.Split("+"[0]);
deletingElementBondIds.Add(seperatedArray[0]);
var elementGameObject=GameObject.Find(seperatedArray[1]);
var elementIndex=testscript.elementArray.IndexOf(elementGameObject);
var bondGameObject=GameObject.Find(seperatedArray[0]);
var bIndex=bondScript.bondarray.IndexOf(bondGameObject);
var bType=bondScript.bondCountArray[bIndex];
var bondTypeCount:int;
if(bType=="Single")
{
bondTypeCount=1;
}
else if(bType=="Double")
{
bondTypeCount=2;
}
else if(bType=="Triple")
{
bondTypeCount=3;
}
testscript.elementBondCount[elementIndex]=testscript.elementBondCount[elementIndex]-bondTypeCount;
var valencyString=elementGameObject.GetComponentInChildren(TextMesh).text;
var valencyText=valencyString.Substring(valencyString.Length-1);
if(valencyText==" ")
{
valencyText="0";
}
var valency=int.Parse(valencyText);
var updatedValencyText=valency+bondTypeCount;
valencyString=valencyString.Remove(valencyString.length-1);
valencyString=valencyString.Insert(valencyString.length,updatedValencyText.ToString());
elementGameObject.GetComponentInChildren(TextMesh).text=valencyString;
OtherElementBondInfoDeletion(elementIndex,seperatedArray[0]);
rightHandSide=RightSideText(elementIndex,bIndex);
DisplayText(leftHandSide,rightHandSide);
bondScript.bondarray.RemoveAt(bIndex);
bondScript.bondCollider.RemoveAt(bIndex);
bondScript.nameOfElementsInBondArray.RemoveAt(bIndex);
bondScript.bondbetween.RemoveAt(bIndex);
bondScript.bondCountArray.RemoveAt(bIndex);
bondScript.bondRelatedRightSideIndex.RemoveAt(bIndex);
bondScript.cylinderIdList.RemoveAt(bIndex);
bondScript.bondTypeList.RemoveAt(bIndex);
bondScript.bondName.RemoveAt(bIndex);
GameObject.Destroy(bondGameObject);
}
testscript.elementArray.RemoveAt(sphereIndex);
testscript.sphereCollider.RemoveAt(sphereIndex);
testscript.elementName.RemoveAt(sphereIndex);
testscript.elementStatus.RemoveAt(sphereIndex);
testscript.elementValency.RemoveAt(sphereIndex);
testscript.elementBondCount.RemoveAt(sphereIndex);
testscript.elementWithWhichBondFormed.RemoveAt(sphereIndex);
testscript.elementText.RemoveAt(sphereIndex);
testscript.elementPosition.RemoveAt(sphereIndex);
testscript.elementColor.RemoveAt(sphereIndex);
testscript.elementSphereName.RemoveAt(sphereIndex);
testscript.element_plane.RemoveAt(elementCount);
testscript.element_sphere.RemoveAt(elementCount);
Destroy(element2);
}
else
{
var t1:TextMesh = testtext.GetComponent(TextMesh);
oldtext=t1.text;
index=oldtext.IndexOf(">");
rightSide=oldtext.Substring(index+1);
leftHandSide=leftSideCheck();
if(leftHandSide=="")
{
t1.text="";
}
else
{
t1.text=leftHandSide+" -> "+rightSide;
}
testscript.elementArray.RemoveAt(sphereIndex);
testscript.sphereCollider.RemoveAt(sphereIndex);
testscript.elementName.RemoveAt(sphereIndex);
testscript.elementStatus.RemoveAt(sphereIndex);
testscript.elementValency.RemoveAt(sphereIndex);
testscript.elementBondCount.RemoveAt(sphereIndex);
testscript.elementWithWhichBondFormed.RemoveAt(sphereIndex);
testscript.elementText.RemoveAt(sphereIndex);
testscript.elementPosition.RemoveAt(sphereIndex);
testscript.elementColor.RemoveAt(sphereIndex);
testscript.elementSphereName.RemoveAt(sphereIndex);
testscript.element_plane.RemoveAt(elementCount);
testscript.element_sphere.RemoveAt(elementCount);
Destroy(element2);
}
}
}
else
{
if(totalBond1>0)
{
if(individualId[0]!="None")
{
for(var bondCount2=0;bondCount2<individualId.length;bondCount2++)
{
var ELnBdIDs1:String=individualId[bondCount2];
var ElementNBondID=new Array();
ElementNBondID=ELnBdIDs1.Split("+"[0]);
var DisabledBondId=ElementNBondID[0];
var bond1=GameObject.Find(DisabledBondId);
bond1.renderer.enabled=false;
}
moved=true;
}
}
}
}
}
}
}
}
}
}
come on guys.. no hint or answer regarding this.. ! So much has been said about this problem hope some one will help me with this question.. !
Posting your code would have help someone answer your question. I've seen this behavior with the structure of some drag/drop scripts where a raycast is used to move the object. If the finger leaves the object (in your case do to lag), then the raycast fails and the dragging stops. I don't know if this is the issue in your case. Anyway, code will likely help answer this question.
Answer by robertbu · Dec 14, 2013 at 05:52 AM
The problem is as I expect. Your movement code is inside the Raycast(). This means that if your finger gets out ahead of the object, the raycast fails, and the object will no longer move. Here is some code I wrote for another answer (slightly modified):
#pragma strict
private var dist : float;
private var toDrag : Transform;
private var dragging = false;
private var offset : Vector3;
function Update() {
if(Input.GetMouseButtonDown(0)) {
var hit : RaycastHit;
var v3 : Vector3;
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray,hit) && (hit.collider.tag == "Drag"))
{
toDrag = hit.transform;
dist = hit.transform.position.z - Camera.main.transform.position.z;
v3 = Vector3(Input.mousePosition.x, Input.mousePosition.y, dist);
v3 = Camera.main.ScreenToWorldPoint(v3);
offset = toDrag.position - v3;
dragging = true;
}
}
if (Input.GetMouseButton(0) && dragging) {
v3 = Vector3(Input.mousePosition.x, Input.mousePosition.y, dist);
v3 = Camera.main.ScreenToWorldPoint(v3);
toDrag.position = v3 + offset;
}
if (Input.GetMouseButtonUp(0)) {
dragging = false;
}
}
Notice how the original hit detection code is inside the Raycast(), but the dragging code is outside and uses ScreenToWorldPoint() to place the object. You need to restructure your code so that the ' if(touch.phase==TouchPhase.Moved)' is outside the Raycast. That probably means saving some state like what to drag and the fact that you are dragging (like I've done in the code above).
Just one thing. So all the thing that i was doing in mouse down will be done in raycasting and just the dragging & placing the gameobject will be done in if(touch.phase==TouchPhase.$$anonymous$$oved)
part. ? a lot of code is put in this part and it would be quite confusing to rearrange the code now. So some pointer would be really helpful do you want me to mail you the code ?
Just edit your question to include the rest of the script that contains the above code, and I'll take a look as I have time. We use Finger Gestures to abstract our touch input, so I'm not the best one to be (re)writing native touch code.
I have edited the script. Well as of now it is working in an acceptable way.. though sometimes spheres drops while dragging. Though i would have to do it in next version of app though. So its better to do it now. I can wait for sometime and will carry on with some other stuff and yeah will give it a try once more. ! if I am able to do it on my own..!
This code is pretty ugly. It needs a rewrite including pulling much of the interior code out into separate functions for maintainability. Based just on the structure, you could do something like this:
private var is$$anonymous$$oving = false;
private var element2:GameObject;
function Update()
{
if(!buttonsLayoutScript.guiVisible && bondScript.clickable)
{
for (var touch : Touch in Input.touches)
{
if (touch.phase==TouchPhase.Began)
{
ray=Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast (ray, hit))
{
sphereIndex = testscript.sphereCollider.IndexOf ( hit.collider );
//Checking if the element selected is a sphere or not. -1 means that it is not the sphere
if ( sphereIndex!= -1 )
{
element2=testscript.elementArray[sphereIndex];
is$$anonymous$$oving = true;
}
}
}
if(is$$anonymous$$oving && touch.phase==TouchPhase.$$anonymous$$oved)
{
// ########## All your existing code ##############
}
if (is$$anonymous$$oving && touch.phase==TouchPhase.Ended || Touch.phase==TouchPhase.Canceled)
{
is$$anonymous$$oving = false;
}
}
}
}
Note I've introduced 'is$$anonymous$$oving', and pulled out 'element2' so that it is persistent across calls. In addition, I'd probably do a bit of rewriting so that it only works with a single finger.