Restrict object movement (see inside)

alt text

So, I’ve got this cube (player) and two points (spheres). There is a script on player, which is basically char controller:

using UnityEngine;
using System.Collections;

public class MoveToPoint1 : MonoBehaviour
{
	public float smooth = 2;
	private Vector3 newPosition;

	
	void Awake ()
	{
		newPosition = transform.position;
	}
	
	
	void Update ()
	{
		Vector3 point1Position = GameObject.Find("Point1").transform.position;
		Vector3 point2Position = GameObject.Find("Point2").transform.position;
		PositionChanging();

		if (Input.GetMouseButtonDown(0))
		{
			RaycastHit hitInfo = new RaycastHit();
			bool hit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo);
			if (hit) 
			{
				Debug.Log("Hit " + hitInfo.transform.gameObject.name);
				if (hitInfo.transform.gameObject.name == "Point1")
				{
					newPosition = point1Position;
					transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);

				} 
				if (hitInfo.transform.gameObject.name == "Point2")
				{
					newPosition = point2Position;
					transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
					
				}
				else {
					Debug.Log ("nopz");
				}
			} else {
				Debug.Log("No hit");
			}

		} 
	}



	void PositionChanging ()
	{


		Vector3 positionB = new Vector3(-5, 3, 0);
		
		if(Input.GetKeyDown(KeyCode.B))
			newPosition = positionB;
		
		transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
	}

} 

So, when I click on either of the points, the cube lerps there. It’s okay and it’s cool.

The cube (some other model in the future) uses a rigidbody (to ‘walk’ upon the terrain, not just float through it), and the spheres use colliders, so the raycasthit would work.
You get my problem already, right?
If not, then the big problem is:
The cube, after clicking on one of the spheres, will try to place itself in the center of the sphere, which is impossible, since both of them have physic colliders, and they start colliding and cube acting all shaky and stuff (which is obvious).

What I want from you is: Help me somehow avoid this and suggest something. The only thing I have in mind is hang the spheres above the terrain (higher than the height of the cube) and somehow restrict the cube to fly up, when I click the sphere (it will try to go up, to where the sphere is), but the cube should be still able to go up and down upon the terrain…

I guess that’s complicated, but suggest me some variants, please, maybe it can be done easier!

I think you need to look into NavMeshAgent.

By using the NavMeshAgent you can set the player destination, and once that is set, the player character will avoid obstacles and move to the click position.
Let me know if you need help setting up and I’ll draft some code for you :slight_smile:

Alternatively, you COULD continue with your solution, although, you’d need to set a sphere at every single point the player can click. If you don’t Lerp the Y position of the Cube/player character, then it won’t go up to the sphere.

But, I do STRONGLY urge the use of Nav Mesh. It’s extremely simple to use and it gives better performance.

If you only want station and you don’t want the player to stop between them, and you don’t want to use NavMesh, then this is what I would do:

I don’t like CS, and I only use it when I don’t have a choice. So my solution example will be in JS. For each station create a box collider that encompasses the entire station, and make sure it doesn’t have a renderer. As soon as the player clicks on a station, you can turn the collider into a trgger, so the player doesn’t collide with the station, and as soon as the player object exits the trigger, you turn it back into a collider. And each station should be tagged “Staion”.

This is the main script that is NOT attached to the staion.

var MoveSpeed = 1.0;

private var Player : GameObject;
private var MainCamera : GameObject;

private var CurrentStation : Vector3;
private var NewStation : Vector3;
private var transfer = false;
private var counter = 0.0;

function Start ()
	{
	Player = GameObject.FindGameObjectWithTag("Player"); //This will find the player object at start
	MainCamera = GameObject.FindGameObjectWithTag("Main Camera"); //Finds the main camera object
	}

function Update ()
	{
	var hit : RaycastHit;
	var ray : Ray = MainCamera.camera.ScreenPointToRay(Input.mousePosition);
	if (Physics.Raycast(ray, hit) && Input.GetMouseButtonDown(0) && !transfer)
		{
		if (hit.transform.tag == "Station")
			{
			NewStation = hit.transform.position;
			hit.transform.gameObject.collider.isTrigger = true; //When a Collider is a Trigger it doesn't collide with other collider anymore
			transfer = true;
			counter = 0.0;
			}
		}
	//Lerp the Player to the NewStation position
	if (transfer && counter < 1.0)
		{
		Player.transform.position.x = Mathf.Lerp(CurrentStation.x, NewStation.x, counter);
		Player.transform.position.z = Mathf.Lerp(CurrentStation.z, NewStation.z, counter);
		counter += Time.deltaTime * MoveSpeed;
		}
	else if (counter >= 1.0 && transfer) // When the counter is equal to or grater than 1.0 the Lerp is finished
		{
		transfer = false;
		}
	}

And this is the script for the Stations:

function OnTriggerExit (other : Collider)
	{
	if (other.tag == "Player")
		{
		gameObject.collider.isTrigger = false; // Turns the Trigger back into a collider as soon as the Player EXITS the Station
		}
	}