Jumping game object

Hello
I’ve a problem with mu GameObjects. When i right click destination they go there but when there’re close they suddenly jump on clicked place. What’s more if i click on highland they dont “climb” up - they move trough the grounf and it seems that half is above ground lever and half under… Thanks for help

BasicUnitMovement.cs

using UnityEngine;
using System.Collections;

public class BasicUnitMovement : MonoBehaviour
{
	public float moveSpeed = 1.0f;
	public float goalRadius = 0.1f;
	private Vector3 goal;
	
	void Start()
	{
		goal = transform.position;
	}
	
	public void MoveOrder(Vector3 newGoal)
	{
		goal = newGoal;
	}
	
	void Update()
	{
		//Move towards our goal
		transform.position += (goal - transform.position).normalized*moveSpeed*Time.deltaTime;
		
		foreach(Collider obj in Physics.OverlapSphere(goal,goalRadius))
		{
			if(obj.gameObject == gameObject)
			{
				transform.position = goal;
			}
		}
	}
}

MoveSelectedUnitsOnRightClick

using UnityEngine;
using System.Collections;

public class MoveSelectedUnitsOnRightClick : MonoBehaviour
{
	private UnitManager unitManager;
	
	void Start()
	{
		GameObject unitManagerObject = GameObject.FindGameObjectWithTag("PlayerUnitManager");
		unitManager = unitManagerObject.GetComponent<UnitManager>();	
	}
	
	void RightClicked(Vector3 clickPosition)
	{
		foreach(GameObject unit in unitManager.GetSelectedUnits())
		{
			unit.SendMessage("MoveOrder",clickPosition);
		}
	}
}

Problem 1: Male goalRadius smaller so that it does not jump there.
Problem 2: Your object doesn’t detect collision with the ground and sounds like it is moving to centre of object. Create system to check for collision between unit and terrain. For second issue, if the unit is moving so that it’s position is the centre of the object, create y offset so that it goes to the bottom of the unit.

Forget to mention, if you use Unity terrain you can easily adjust your character position with Terrain.SampleHeight()

Thanks for Yours answer however I don’t know how to do that… No idea on system to check for collision. Neither with Y offset

I you want objects to collide with other objects and be dynamically moving around then:

Make sure each dynamic (moving) object has a Rigidbody component.
Instead of changing an objects position you should apply a force to the Rigidbody of the object in the direction of the goal position.

When I use the AddForce() function I usually pass it ForceMode.VelocityChange as it’s much easier to work with than calculating what forces you need to push objects of differing mass.

One last tip, when working with the physics engine it is a good idea to put all your physics code in the FixedUpdate() method instead of the Update method in your scripts.

Hope this helps.

Thanks, I will try.

Gigabeat - I made it 0 and even less than zero and still have a problem

Apparently this is issue with casting OverlapSphere.Look here. You could replace with

        if ((Vector3.Distance(transform.position, goal) < goalRadius))
        {
            transform.position = goal;
        }

but I do not know if this work for your implementation.

With centre of object problem, this is because of the object pivot. If you use default object like Sphere it will be in the centre of the object so when you move it will go to centre of object because it’s transform.position is there. To solve, you can move the pivot or shoot a ray down from centre of object and check distance to floor, then offset y position based on distance to floor.

To use Terrain.SampleHeight() you can do like this

    Vector3 myPos = transform.position;
    myPos.y = Terrain.activeTerrain.SampleHeight(transform.position);
    transform.position = myPos;

I am going bed now so I will not respond until tomorrow. I hope this helps! :slight_smile:

I have made something else - Simplified script to minimum and now when Object get to the destiny it starts shaking, like a cocktail

using UnityEngine;
using System.Collections;

public class BasicUnitMovement : MonoBehaviour
{
	public float moveSpeed = 1.0f;
	private Vector3 goal;
	
	void Start()
	{
		goal = transform.position;
	}
	
	public void MoveOrder(Vector3 newGoal)
	{
		goal = newGoal;
	}
	
	void Update()
	{
		//Move towards our goal
		transform.position += (goal - transform.position).normalized*moveSpeed*Time.deltaTime;	
	}
}

Any ideas? =)

You need to snap when close like I show in previous post, otherwise it will do that.

using UnityEngine;
using System.Collections;

public class BasicUnitMovement : MonoBehaviour
{
    public float moveSpeed = 1.0f;
    private Vector3 goal;
    private float goalRadius = 0.01f;
    
    void Start()
    {
        goal = transform.position;
    }
    
    public void MoveOrder(Vector3 newGoal)
    {
        goal = newGoal;
    }
    
    void Update()
    {
        // If we are close to our goal, snap there.
        if ((Vector3.Distance(transform.position, goal) < goalRadius))
        {
            transform.position = goal;
        }
        else
        {
            //Move towards our goal
            transform.position += (goal - transform.position).normalized*moveSpeed*Time.deltaTime;
         }   
    }
}

Well. I have changed my code with Yours version but there’s still a problem. Look at the Video

https://vimeo.com/75392291

If I use just that code (with small modification so that is click-to-move) it work how it should. I can upload video later today (8+ hour) when I get home if you want me to. Make sure any script that affect that object don’t interfere with your movement.

Edit:
I am back sooner. Here is video to show how it work for me in new scene just using BasicUnitMovement.cs.
http://videopasteus.s3.amazonaws.com/videos/0cc9818a0191436a90f3d71a50775320.html

On my GameObject I have two other codes:

SelectPlayerUnitOnClicked.cs

using UnityEngine;
using System.Collections;

public class SelectPlayerUnitOnClicked : MonoBehaviour
{
	private UnitManager unitManager;
	
	void Start()
	{
		GameObject unitManagerObject = GameObject.FindGameObjectWithTag("PlayerUnitManager");
		unitManager = unitManagerObject.GetComponent<UnitManager>();
	}
	
	void Clicked()
	{
			unitManager.SelectSingleUnit(gameObject);
	}
}

and FlashIfSelected.cs

using UnityEngine;
using System.Collections;

public class FlashIfSelected : MonoBehaviour 
{
	public float flashRate = 1.0f;
	public GameObject unitObject = null;
	
	private Color originalColor;
	
	private UnitManager unitManager;
	
	private bool coroutineRunning = false;

	// Use this for initialization
	void Start () 
	{
		if(unitObject == null)
		{
			unitObject = gameObject;
		}
		GameObject unitManagerObject = GameObject.FindGameObjectWithTag("PlayerUnitManager");
		unitManager = unitManagerObject.GetComponent<UnitManager>();
		originalColor = renderer.material.color;
	}
	
	void Update()
	{
		if(unitManager.IsSelected(unitObject))
		{
			if(!coroutineRunning)
			{
				coroutineRunning = true;
				StartCoroutine("Flash");
			}
		}
		else
		{
			coroutineRunning = false;
			StopAllCoroutines();
			renderer.material.color = originalColor;
		}
	}
	
	// Update is called once per frame
	IEnumerator Flash()
	{
		float t = 0;
		while(t < flashRate)
		{
			renderer.material.color = Color.Lerp(originalColor,Color.white,t/flashRate);
			t += Time.deltaTime;
			yield return null;
		}
		renderer.material.color = Color.white;
		StartCoroutine("Return");
	}
	
	IEnumerator Return()
	{
		float t = 0;
		while(t < flashRate)
		{
			renderer.material.color = Color.Lerp(Color.white,originalColor,t/flashRate);
			t += Time.deltaTime;
			yield return null;
		}
		renderer.material.color = originalColor;
		StartCoroutine("Flash");
	}
}

Maybe I have changed something in physics/gameobject options?

Don’t see anything there that should cause problem. If you use rigidbody there are things that cause similar problem but from video I do not see you use it. So I don’t know what can be problem, sorry. :frowning: