1

I have been trying this for two days with no success. I cant figure out where I'm missing the point. All the missiles are moving towards the position of the target but not following it. The position remains fixed and all the newly created missiles come to this point instead of following the target.

Here is the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HomingMissile : MonoBehaviour
{
    private GameObject target; //changed to private
    private Rigidbody rb;
    public float rotationSpeed;
    public float speed;

Quaternion rotateToTarget;
Vector3 direction;

private void Start()
{
    target = GameObject.FindGameObjectWithTag("Player"); //uncommented this
    rb = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
    //made some modifications
    Vector3 direction = (target.transform.position - transform.position).normalized;
    float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;//interchanged x and z
    Quaternion rotateToTarget = Quaternion.Euler(0, angle, 0);
    transform.rotation = Quaternion.Slerp(transform.rotation, rotateToTarget, Time.deltaTime * rotationSpeed);
    Vector3 deltaPosition = speed * direction * Time.deltaTime;
    rb.MovePosition(transform.position + deltaPosition);

}

}

I selected the target(transform) using the inspector. I'm using Unity and C# obviously you know that.

What Im trying to achieve is that the missile should follow the position of the target in real time. And i can add the destroy code for the missile myself. Note : Please don't tag this as a duplicate. It is not. The game is 2D where Y is always constant. Vertical axis is X and Horizontal axis is X. The objects are 3D. That's why I can't use rigidbody2D.

EDIT: Code edited. The missile follows the target and also points to the direction of motion. How to make the missile make a circular rotation when it needs to rotate?

Joe_Vj _95
  • 29
  • 3
  • 9
  • it seems to me that the target transform is not correct. it refers to an unused game object – Bizhan Jun 04 '18 at 11:43
  • I tried both ways. Using inspector to drag and drop the target transform and using target = GameObject.FindGameObjectWithTag("Target"); But its not working. – Joe_Vj _95 Jun 04 '18 at 13:28
  • The code is fine. Try debugging the transform to see the position it is following – Bizhan Jun 04 '18 at 13:31
  • Debug Log: (0.0, 0.0, 0.0) UnityEngine.Debug:Log(Object) HomingMissile:FixedUpdate() (at Assets/Test/HomingMissile.cs:38). – Joe_Vj _95 Jun 04 '18 at 14:21
  • So you know now that the current target is always at zero. As I said this script is following a wrong target – Bizhan Jun 04 '18 at 14:40
  • Thanks for the great help. I still don't know what caused the problem. Now I made the target gameobject private and the script identifies the target with the tag. Is there some way to make the missile to make a circular turn ? – Joe_Vj _95 Jun 04 '18 at 15:35
  • you can use `transform.lookAt` on the missle in 3d. I'm not sure about 2d – Bizhan Jun 04 '18 at 15:39
  • Another weird behavior. The missile works as mentioned when manually instantiated. However when fired from the player this happens : `(0.0, 0.0, 5.6) UnityEngine.Debug:Log(Object) HomingMissile:FixedUpdate() (at Assets/Test/HomingMissile.cs:38) ` Does this mean something `NullReferenceException: Object reference not set to an instance of an object HomingMissile.FixedUpdate () (at Assets/Test/HomingMissile.cs:24) ` – Joe_Vj _95 Jun 04 '18 at 16:03
  • what is in HomingMissile.cs:24 – Bizhan Jun 04 '18 at 16:40
  • The above code is HomingMissile.cs – Joe_Vj _95 Jun 04 '18 at 16:42
  • I don't know the line numbers. What is in line 24 – Bizhan Jun 04 '18 at 16:43
  • Sorry, my bad. line 24 :`Vector3 direction = (target.transform.position - transform.position).normalized;` – Joe_Vj _95 Jun 04 '18 at 16:45
  • Target is null. It may have been destroyed – Bizhan Jun 04 '18 at 16:46
  • No. Here the target is the player ship. the player ship fires the missile and targets itself. I can see and control the ship. – Joe_Vj _95 Jun 04 '18 at 16:48

1 Answers1

3

Firstly, consider:

Use rigidbody.movePosition() and rigidbody.moveRotation() instead. Here's an example:

Vector3 dir = (target.transform.position - transform.position).normalized;
Vector3 deltaPosition = speed * dir * Time.deltaTime;
rb.MovePosition(transform.position + deltaPosition);

Try out rigidbody.MoveRotation() yourself for practice.

Finally, understand that there are many ways to implement homing for missiles. Here's one that is commonly used in real life.

Edit: I will not recommend using rb.addForce() because if u try it out u will realise it is too indeterministic.

Joe_Vj _95
  • 29
  • 3
  • 9
Lincoln Cheng
  • 2,263
  • 1
  • 11
  • 17
  • Thanks for the reply. But the problem is not solved. All instances of the missiles regardless of the position of the target comes to approximately near the origin(0.x, 0.x, 0.x). I made sure no other script is interfering with the Missile. Gravity is set off. And still there is no rotation for the missile. – Joe_Vj _95 Jun 04 '18 at 13:25
  • @Joe_Vj_95 update your question with the latest code u r using? – Lincoln Cheng Jun 04 '18 at 15:11
  • Added the modified code. I accept your answer. As it also helped to make it work. The missile rotation is not as expected. Is there some way to make the missile circular rotation when it needs to rotate? – Joe_Vj _95 Jun 04 '18 at 15:30
  • @Joe_Vj_95 don't modify `transform.rotation` if u r manipulating the `rigidbody`. In unity, **either** u manipulate the transform directly **or** u manipulate the rigidbody (physics). doing both is not recommended (check the docs). use rigidbody.moveRotation() instead. – Lincoln Cheng Jun 04 '18 at 15:34
  • Im new to unity and C#. Just 1 week of experience. Are you suggesting this? replacing `//transform.rotation = Quaternion.Slerp(transform.rotation, rotateToTarget, Time.deltaTime * rotationSpeed);` with `rb.MoveRotation(rotateToTarget);` – Joe_Vj _95 Jun 04 '18 at 15:39
  • @Joe_Vj_95 Check the docs: https://docs.unity3d.com/ScriptReference/Rigidbody.MoveRotation.html. In your case, that would be `rb.MoveRotation(transform.rotation + deltaRotation)` where `deltaRotation = rotateToTarget * Time.deltaTime` – Lincoln Cheng Jun 04 '18 at 15:52
  • Its difficult for me to understand. Especially how to declare deltaRotation can you suggest edit ? – Joe_Vj _95 Jun 04 '18 at 16:12
  • @Joe_Vj_95 Take a look at [this](https://docs.unity3d.com/Manual/QuaternionAndEulerRotationsInUnity.html), and a slightly more [light-hearted article](http://developerblog.myo.com/quaternions/) to understand more about `Quaternion`s and `Rotation`. Initially it might seem a little difficult to understand, but once you get it it helps alot with understanding 3D arithmetic. – Lincoln Cheng Jun 04 '18 at 16:18