HELP! How to make an object move until colliding with another object.

Hello everyone. I’m trying to build a prototype where you swipe an object through a puzzle. The mechanic I’m trying to aim for is similar to that of the Ice Path in Pokemon Silver/Gold.

Here’s an exact example of what I’m trying to accomplish.

Right now, I’ve managed to get the swipe gesture working, but am having a hard time trying to get the mechanic working properly. I’m using a RigidBody with a velocity, but it’s just not doing what I want it to do. The object is either not fast enough and stops halfway along the path, or bounces off the object. Here is the script I’m using:

using UnityEngine;
using System.Collections;

public class SwipeMotionsMain : MonoBehaviour {

	public float minSwipeDistY;
	public float minSwipeDistX;
	

	//public GUIText Swipe;

	private Vector2 startPos;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {

		if (Input.touchCount > 0) {

			Touch touch = Input.touches[0];

			switch (touch.phase) 
			
			{

			case TouchPhase.Began:

				startPos = touch.position;

				break;

			case TouchPhase.Ended:

				Ray ray = Camera.main.ScreenPointToRay (touch.position);

				RaycastHit rayCastHit;

				float swipeDistVertical = (new Vector3(0, touch.position.y, 0) - new Vector3(0, startPos.y, 0)).magnitude;
				
				if(Physics.Raycast ( ray, out rayCastHit )) {

					if (rayCastHit.collider.gameObject.tag == "Player")	{

						rigidbody.isKinematic = false;

							if ( swipeDistVertical > minSwipeDistY) {

							float swipeValue = Mathf.Sign (touch.position.y - startPos.y);



							if (swipeValue > 0)	{

								//Swipe.text = "Up Swipe"; //Up Swipe
								rigidbody.velocity = new Vector3(0, 0, 20);


								Debug.Log ("Player Up");

							}
							else if (swipeValue < 0)	{

								//Swipe.text = "Down Swipe"; //Down Swipe
								rigidbody.velocity = new Vector3(0, 0, -20);

								Debug.Log ("Player Down");
							}

						}
					}
				}

				float swipeDistHorizontal = (new Vector3(touch.position.x, 0, 0) - new Vector3(startPos.x, 0, 0)).magnitude;

				if(Physics.Raycast ( ray, out rayCastHit )) {
					
					if (rayCastHit.collider.gameObject.tag == "Player")	{

						rigidbody.isKinematic = false;

							if ( swipeDistHorizontal > minSwipeDistX) {
				
							float swipeValue = Mathf.Sign (touch.position.x - startPos.x);
				
								
							if (swipeValue > 0)	{
					
								//Swipe.text = "Right Swipe"; //Right Swipe
								rigidbody.velocity = new Vector3(20, 0, 0);

								Debug.Log ("Player Right");

								}
								else if (swipeValue < 0)	{
						
								//Swipe.text = "Left Swipe"; //Left Swipe
								rigidbody.velocity = new Vector3(-20, 0, 0);

								Debug.Log ("Player Left");

								}
							}

						}
					}
				break;
			}	
		}
	}
}

I would greatly appreciate all the help I get. I will be checking back often to reply and help answer any questions.

Not the best solution but is an easy cheating way to do it. Add collider (if don’t have) to those moving object and the block. Tick isTrigger on all of it. On this script, add this function

void OnTriggerEnter(Collider collider)
	{
		if(collider.tag == blockTag)
		{
			//set velocity 0
			//adjust the object position (the object may overlap with the block)
		}
	}

But as i say, not the best solution… Hope someone may come out a better solution.

Hey. I don’t know if you actually handled your problem now because it’s been a while since you have asked. I pretty much had the same problem and I have to say I am a programming noob, but I finally found a solution even if it is a bit unorthodox and every programmer would hang me for that :smiley: So first of all, let’s say all blocks and your character are rigidbodies. You will need two kinds of script. One for your character that handles the movement and one for the blocks that handles the collision.

playerMovement.cs`
using System.Collections;

public class playerMovement : MonoBehaviour {

public int speed = 8;
KeyCode LeftArrow;
KeyCode RightArrow;
KeyCode UpArrow;
KeyCode DownArrow;

// Update is called once per frame
void FixedUpdate () {


	if (Input.GetKeyDown (KeyCode.LeftArrow) && rigidbody.isKinematic == true){
		rigidbody.isKinematic = false;
		rigidbody.velocity = new Vector3(0, 0, speed);
		rigidbody.angularDrag = 1;

	}
	if (Input.GetKeyDown (KeyCode.RightArrow) && rigidbody.isKinematic == true){
		rigidbody.isKinematic = false;
		rigidbody.velocity = new Vector3(0, 0, -speed);
		rigidbody.angularDrag = 2;

	}
	if (Input.GetKeyDown (KeyCode.UpArrow) && rigidbody.isKinematic == true){
		rigidbody.isKinematic = false;
		rigidbody.velocity = new Vector3(speed, 0, 0);
		rigidbody.angularDrag = 3;

	}
	if (Input.GetKeyDown (KeyCode.DownArrow) && rigidbody.isKinematic == true){
		rigidbody.isKinematic = false;
		rigidbody.velocity = new Vector3(-speed, 0, 0);
		rigidbody.angularDrag = 4;
		}

	}

}This one will handle the playerMovement and has a very unique clue. I set up a very low angular drag at the start of each movement to detect what kind of movement the player is doing currently. Now it is easy for the collider to know which kind of movement. So you have no problem with collision when the player is moving along a wall. Normally the collision detection would trigger then too. But not now. Next thing you have to do is write a collision detection script for the blocks. In my case I made 4. One for the upper wall, one for the left, and so on. So this is the example for the left one. ObjectCollisionLeft.csusing UnityEngine;
using System.Collections;

public class ObjectCollisionLeft : MonoBehaviour {

void OnCollisionEnter ( Collision collision) {
	if (collision.gameObject.CompareTag("Player") && collision.rigidbody.angularDrag == 1) {
		collision.rigidbody.isKinematic = true;
			}
	}

}`
I hope this example will help you as much with your problem as it did with mine :slight_smile: have a nice day.