- Home /
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.
Answer by Jiro-Ng · Apr 09, 2014 at 03:04 AM
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.
Thanks for the reply! Over the last couple of hours, I've actually tried something very similar. I ended up removing the velocity of the object, used transform.Translate, booleans, and OnTriggerEnter, and when the object collided into the blocks, the object stopped moving, but the object was overlapping and completely messed up the grid.
I'll definitely try doing what you mentioned with setting the velocity to 0.
This is actually beco$$anonymous$$g trickier than I thought!
Well then you need to reposition the object to the grid. Tough job.
Answer by Foose · Jul 29, 2014 at 07:38 PM
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 :D 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.cs
using 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 :) have a nice day.
Your answer
![](https://koobas.hobune.stream/wayback/20220613142253im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How to get transform.Translate to work with rigidbodies 2 Answers
Enemy Move towards object and hold it and use object 1 Answer
Mouse Swipe and Code Efficiency 0 Answers
Player glitching through wall when sprinting 1 Answer
2D Movement [HELP!] 0 Answers