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 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;
}
}
}