Попытка написать код C#, чтобы ракета следовала за игроком в Unity

Я пробовал это в течение двух дней без успеха. Я не могу понять, где я упускаю суть. Все ракеты движутся к положению цели, но не следуют за ней. Позиция остается фиксированной, и все вновь создаваемые ракеты приходят в эту точку вместо того, чтобы следовать за целью.

Вот код:

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

}

}

Я выбрал цель (преобразование) с помощью инспектора. Я использую Unity и C#, очевидно, вы это знаете.

Я пытаюсь добиться того, чтобы ракета следовала за положением цели в режиме реального времени. И я могу сам добавить код уничтожения ракеты. Примечание. Не отмечайте это как дубликат. Нет. Игра 2D, где Y всегда постоянно. Вертикальная ось — это X, а горизонтальная ось — это X. Объекты трехмерные. Вот почему я не могу использовать hardbody2D.

РЕДАКТИРОВАТЬ: Код отредактирован. Ракета следует за целью, а также указывает направление движения. Как заставить ракету совершать круговое вращение, когда ей нужно вращаться?


person Joe_Vj _95    schedule 04.06.2018    source источник
comment
мне кажется, что целевое преобразование неверно. это относится к неиспользуемому игровому объекту   -  person Bizhan    schedule 04.06.2018
comment
Я пробовал оба способа. Использование инспектора для перетаскивания целевого преобразования и использование target = GameObject.FindGameObjectWithTag(Target); Но это не работает.   -  person Joe_Vj _95    schedule 04.06.2018
comment
Код в порядке. Попробуйте отладить преобразование, чтобы увидеть позицию, за которой оно следует.   -  person Bizhan    schedule 04.06.2018
comment
Журнал отладки: (0.0, 0.0, 0.0) UnityEngine.Debug:Log(Object) HomingMissile:FixedUpdate() (в Assets/Test/HomingMissile.cs:38).   -  person Joe_Vj _95    schedule 04.06.2018
comment
Итак, теперь вы знаете, что текущая цель всегда равна нулю. Как я уже сказал, этот скрипт следует за неправильной целью   -  person Bizhan    schedule 04.06.2018
comment
Спасибо за большую помощь. Я до сих пор не знаю, что вызвало проблему. Теперь я сделал целевой игровой объект приватным, и скрипт идентифицирует цель с помощью тега. Есть ли способ заставить ракету делать круговой разворот?   -  person Joe_Vj _95    schedule 04.06.2018
comment
вы можете использовать transform.lookAt на ракете в 3D. насчет 2д не уверен   -  person Bizhan    schedule 04.06.2018
comment
Еще одно странное поведение. Ракета работает, как упоминалось, при ручном запуске. Однако при выстреле из игрока происходит следующее: (0.0, 0.0, 5.6) UnityEngine.Debug:Log(Object) HomingMissile:FixedUpdate() (at Assets/Test/HomingMissile.cs:38) Означает ли это что-то NullReferenceException: Object reference not set to an instance of an object HomingMissile.FixedUpdate () (at Assets/Test/HomingMissile.cs:24)   -  person Joe_Vj _95    schedule 04.06.2018
comment
что находится в HomingMissile.cs:24   -  person Bizhan    schedule 04.06.2018
comment
Приведенный выше код — HomingMissile.cs.   -  person Joe_Vj _95    schedule 04.06.2018
comment
Номера строк не знаю. Что находится в строке 24   -  person Bizhan    schedule 04.06.2018
comment
Извините, это моя ошибка. строка 24 :Vector3 direction = (target.transform.position - transform.position).normalized;   -  person Joe_Vj _95    schedule 04.06.2018
comment
Цель нулевая. Возможно, он был уничтожен   -  person Bizhan    schedule 04.06.2018
comment
Нет. Здесь целью является корабль игрока. корабль игрока запускает ракету и нацеливается на себя. Я могу видеть и управлять кораблем.   -  person Joe_Vj _95    schedule 04.06.2018


Ответы (1)


Во-первых, подумайте:

Вместо этого используйте rigidbody.movePosition() и rigidbody.moveRotation(). Вот пример:

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

Попробуйте сами rigidbody.MoveRotation() для практики.

Наконец, поймите, что есть много способов реализовать самонаведение для ракет. Вот тот, который обычно используется в реальной жизни.

Изменить: я не буду рекомендовать использовать rb.addForce(), потому что, если вы попробуете это, вы поймете, что это слишком недетерминировано.

person Lincoln Cheng    schedule 04.06.2018
comment
Спасибо за ответ. Но проблема не решена. Все экземпляры ракет независимо от положения цели приближаются примерно к началу координат (0.x, 0.x, 0.x). Я убедился, что никакие другие скрипты не мешают работе Ракеты. Гравитация отключена. И до сих пор нет вращения для ракеты. - person Joe_Vj _95; 04.06.2018
comment
@Joe_Vj_95 обновите свой вопрос, указав последний код, который вы используете? - person Lincoln Cheng; 04.06.2018
comment
Добавлен измененный код. Я принимаю ваш ответ. Так как это также помогло заставить его работать. Вращение ракеты не такое, как ожидалось. Есть ли способ заставить ракету вращаться по кругу, когда ей нужно повернуться? - person Joe_Vj _95; 04.06.2018
comment
@Joe_Vj_95 не изменяйте transform.rotation, если вы манипулируете rigidbody. В единстве либо вы управляете преобразованием напрямую, или вы управляете твердым телом (физикой). делать и то, и другое не рекомендуется (проверьте документы). вместо этого используйте hardbody.moveRotation(). - person Lincoln Cheng; 04.06.2018
comment
Я новичок в единстве и С#. Всего 1 неделя опыта. Вы это предлагаете? замена //transform.rotation = Quaternion.Slerp(transform.rotation, rotateToTarget, Time.deltaTime * rotationSpeed); на rb.MoveRotation(rotateToTarget); - person Joe_Vj _95; 04.06.2018
comment
Мне трудно это понять. Особенно, как объявить deltaRotation, можете ли вы предложить изменить? - person Joe_Vj _95; 04.06.2018
comment
@Joe_Vj_95 Взгляните на это и немного больше беззаботная статья, чтобы узнать больше о Quaternions и Rotation. Сначала это может показаться немного сложным для понимания, но как только вы это поймете, это очень поможет в понимании трехмерной арифметики. - person Lincoln Cheng; 04.06.2018