- Home /
Move Object to location of Trigger?
Hi, I want to move my object to a trigger.
I want if I click on the trigger, my object will smoothly go to the trigger (NOT INSTANTLY), right now if I click my trigger the object will move slowly and then stop, and wait for me to click again so it can move. I dont want that. I want to click once on the trigger, and the object move smoothly all the way to the location of the trigger.
heres my code:
using UnityEngine; using System.Collections;
public class GreenEnvelope : MonoBehaviour { public Transform target; public float speed; public bool isMove;
void Start()
{
isMove = false;
}
void Update()
{
if (Input.GetMouseButton (0)) {
SetTargetPosition();
}
}
void SetTargetPosition()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if(Input.GetMouseButtonDown(0) && hit.collider.name == "GreenTrigger")
{
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards (transform.position, target.position, step);
isMove=true;
}
}
}
}
The SetTargetPosition method is only being called when you are holding the mouse button down. You will need to change your logic for it to work. Then in that method, you check again for the mouse button down. Again, it will not continue to execute unless your mouse button is down.
Answer by kalen_08 · Jul 20, 2018 at 10:00 PM
The best way to do this kind of thing is through a CoRoutine (IEnumerator) So basically the way it works is until its a certain distance from the target (which is a very small amount) then it will move towards it and when it reaches there it will stop and set the target to nothing. If say you were to click on a different target... It stops call coroutines and then starts the coroutine again. Ensuring that there aren't two scripts fighting to do the same thing.
[SerializeField] float speed = 1;
// generally identifying things by their name sucks!!
// if you change the name of the object then it no longer works.
// i think it would be best if you have all of these triggers on a Layer
// and if you click on something of that layer then what you click becomes
// becomes the target... but anyways...
[SerializeField] string triggerName = "Trigger";
GameObject target;
float stoppingDistance = 0.001f;
void Update()
{
if (Input.GetMouseButtonDown (0))
{
SetTarget();
}
MoveToTargetPosition();
}
void SetTarget()
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
if(hit.collider.name == triggerName)
{
target = hit.collider.gameObject;
// stop any existing coroutine that is running
// this way there won't be two running at the same time.
StopAllCoroutines();
StartCoroutine(MoveToTargetPosition());
}
}
}
IEnumerator MoveToTargetPosition ()
{
//while the target exists...
while (target != null)
{
transform.position = Vector3.MoveTowards (
transform.position,
target.transform.position,
speed * Time.deltaTime
);
// wait a frame
yield return new WaitForEndOfFrame();
// calculate the distance between the objects
// if its close enough then stop the process.
float distanceToTarget = Mathf.Abs(Vector3.Distance(transform.position, target.transform.position));
if (distanceToTarget <= stoppingDistance) {
target = null;
yield break;
}
}
}