0
\$\begingroup\$

I am trying to have a missile seek its target once it has entered the target's trigger. The code should be fine, I think it has something to do with how the colliders are operating.

I want the blue missile to move towards the turret object once it is in turret object trigger collider. However this is sticking to the sphere trigger collider.

void Update()
{
    if (Time.time > timeCreated + timeToLive)
    {
        Destroy(this.gameObject);
    }
    if (inTurretTrigger == true)
    {
        StartCoroutine("MoveToTurret");
    }
}

public void OnCollisionEnter(Collision collision)
{
    //Debug.Log("Collided with " + collision.gameObject.name.ToString()); // All this logic needs to go in Trigger not collision
    /*
    TurretController t = collision.gameObject.GetComponentInParent<TurretController>(); // Returning null as this was not applied in Prefab
    Debug.Log("Who am I? " + t.gameObject.name.ToString());

    if (t != null)
    {
        Debug.Log("This is coming from Bullet Script and t is not null " + t.gameObject.name.ToString());
        transform.position = Vector3.MoveTowards(transform.position, t.gameObject.transform.position, bulletVelocity * Time.deltaTime);
    }
    else {

    }
    */
    Destroy(this.gameObject);
}

public void OnTriggerEnter(Collider other) // over here above code should work, however the best case is find all instances, or through Raycase, and follow the object through hit target
{
    t = other.gameObject.GetComponentInParent<TurretController>(); // Returning null as this was not applied in Prefab
    Debug.Log("Who am I? - " + t.gameObject.name.ToString());

    if (t != null)
    {
        inTurretTrigger = true;
    }
    else
    {
        //
    }
}

IEnumerator MoveToTurret() // logic for coroutine provided from StackOverflow
{
    Debug.Log("This is coming from Bullet Script and t is not null");
    transform.position = Vector3.MoveTowards(transform.position, t.gameObject.transform.position, bulletVelocity * Time.deltaTime); // this needs to be handled in Update
    yield return new WaitForEndOfFrame();
}

Unity View

\$\endgroup\$
0
\$\begingroup\$

I think the answer to your question is present in your own code:

transform.position = Vector3.MoveTowards(transform.position, t.gameObject.transform.position, bulletVelocity * Time.deltaTime); // this needs to be handled in Update

as you can see the comment says that the operation needs to be handled in Update, like in this example on unity's scripting API: https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html

Instead of calling a new coroutine every frame, you should call the MoveTowards operation directly in your Update function inside the if statement like this:

if (inTurretTrigger)
{
    transform.position = Vector3.MoveTowards(transform.position, t.gameObject.transform.position, bulletVelocity * Time.deltaTime);
}

[Notice: I omitted writing " == true" in the if's condition since inTurretTrigger returns a boolean value]

What you want to achieve can be done with a coroutine but it would just be pointless and resource wasting in this case, since "Coroutines are best employed when dealing with long asynchronous operations, such as waiting for HTTP transfers, Asset loads or file I/O to complete." as reported by UnityDoc here https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity3.html

I hope this can help you solve this issue.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.