Colliders detect collision too late - touch dragging problem
Hi, I'm making mobile game and I have a huuge problem with collision detection. I was looking for answer, but I haven't found any solution.
My game looks almost like "Unlock me". I have few blocks in the scene and player has to move these blocks. But sometimes when I drag block fast, 2 blocks overlap.
To move blocks I use: gameObjectTodrag.transform.position = new Vector3(GOcenter.x, newGOCenter.y, GOcenter.z); and maybe this method of changing block position is wrong.
I would like to stop dragging block exactly in a place of collision, but it detects collision too late. Do you have any idea how can I fix it?
I know there were many similar questions, but I haven't found any solution for my problem. Please help me :)
use your collider in conjunction with a rigidbody and move it in FixedUpdate with $$anonymous$$ovePosition.
You're teleporting your object right now, bypassing physics
Tried this, but it works the same as changing transform.position in my case.
Any other ideas?
is$$anonymous$$inematic is true? at the bottom
https://docs.unity3d.com/ScriptReference/Rigidbody.$$anonymous$$ovePosition.html
You're saying too late, what are you doing the moment the boxes collide? set them kinematic or something? I think I check with this tomorrow.
Answer by hexagonius · Nov 25, 2016 at 09:53 AM
I fiddled a bit with this problem now and must admit I'm confused and disappointed about MovePosition. It effectively only works if the collider you have has a Rigidbody not set to kinematic if you want the other collider be without one. Then you suffer from the velocity that get's applied to it on collision and the fact that the moved one does not stay out of what it collided with... really bad I might say, or at least, what is it even good for? So to deal with the problem velocity is the best way to go and it works like this:
using UnityEngine;
using UnityEngine.EventSystems;
public class MoveWithCursor : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler {
Rigidbody rb;
bool dragging;
Vector3 worldPosition;
void Awake(){
rb = GetComponent<Rigidbody> ();
}
void FixedUpdate(){
if (!dragging)
return;
rb.velocity = (worldPosition - transform.position) / Time.deltaTime;
}
public void OnBeginDrag (PointerEventData eventData)
{
dragging = true;
}
public void OnDrag (PointerEventData eventData)
{
worldPosition = Camera.main.ScreenToWorldPoint ((Vector3)eventData.position - Vector3.forward * Camera.main.transform.position.z);
}
public void OnEndDrag (PointerEventData eventData)
{
dragging = false;
}
}
You either translate it to whatever movement logic you have, or have a main Camera with PhysicsRaycaster and an EventSystem in a scene where the game happens at world z 0 and attach this to a cube with collider and non Kinematic rigidbody