Поворот объекта к объекту

Рейтинг: 1Ответов: 1Опубликовано: 06.05.2023

Есть враг и помощник. Проблема: Помощник при использования кода из конца поста, работает неправильно, и поворачивается не так, как нужно.

Правильно

Не правильно

С тем кодом, который предложил KOTIK, сначала помощник действительно подходит к врагу, смотря на него, а подходя к нему происходит вот это: введите сюда описание изображения

Желаемое поведение: чтобы он подходил на достаточное расстояние к врагу, причём смотря на него, и уничтожал его, а не поворачивался и бежал за врагом.

Он поворачивается вокруг врага, а затем переходит на другую сторону. А вот это происходит когда он повернулся и идёт за врагом по другой стороне:

введите сюда описание изображения

Он уже смотрит левее врага. Напомню, когда он шёл к нему в начале, он смотрел чётко на него.

Фрагменты кода:

transform.LookAt(enemy);
transform.LookAt(enemy, Vector3.left);

Тут помощник хоть и повёрнут к врагу, но подходя к нему он переворачивается.

var q = Quaternion.LookRotation(nearest.transform.position - transform.position);
transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 20 * Time.deltaTime);

В этом фрагменте всё более-менее хорошо в начале, но в конце он наклоняется не туда. Наклон

Весь код из Update:

nearest = FindClosestEnemy().gameObject;
    var q = Quaternion.LookRotation(nearest.transform.position - transform.position);
    transform.rotation = Quaternion.RotateTowards(transform.rotation, q, 20 * Time.deltaTime);
    float distance = Vector3.Distance(transform.position, nearest.transform.position);
    Debug.Log(distance);
    if (distance >= 5f) transform.localPosition = Vector3.MoveTowards(transform.position, nearest.transform.position, 5 * Time.deltaTime);

Весь код:

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


public class KnifeHelperLogic : MonoBehaviour
{
    GameObject[] enemy;
    GameObject closest;

    public GameObject nearest;
    public float radian_angle = 10f;
    [SerializeField] private Transform point;

    void Start()
    {
        enemy = GameObject.FindGameObjectsWithTag("Enemy");
    }

    GameObject FindClosestEnemy()
    {
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;
        foreach (GameObject go1 in enemy)
        {
            Vector3 diff = go1.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance)
            {
                closest = go1;
                distance = curDistance;
            }
        }
        return closest;
    }
    public void LookAt(Vector3 point)
    {
        var direction = point - transform.position; // получить направление
        direction.y = 0f; // обнулить y, чтобы не смотреть вверх-вниз
        var rotation = Quaternion.LookRotation(-direction, Vector3.up); //первый аргумент - направление вперед, второй - направление вверх
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, 10f * Time.deltaTime); // либо вместо Slerp использовать RotateTowards
    }

    void Update()
    {
        nearest = FindClosestEnemy().gameObject;
        LookAt(nearest.transform.position);
        float distance = Vector3.Distance(transform.position, nearest.transform.position);
        Debug.Log(distance);
        if (distance >= 2.5f) transform.localPosition = Vector3.MoveTowards(transform.position, nearest.transform.position, 5 * Time.deltaTime);
    }
    void LookAtEnemy()
    {
        
    }
}

Ответы

▲ 2Принят

Обнули ось Y у вектора направления.

public class Something : MonoBehaviour
{
    [SerializeField] private Transform _point;
    [SerializeField] private float _speed = 10f;
        
    public void LookAt(Vector3 point)
    {
        var direction = point - transform.position; // получить направление
        direction.y = 0f; // обнулить y, чтобы не смотреть вверх-вниз
        var rotation = Quaternion.LookRotation(direction, Vector3.up); //первый аргумент - направление вперед, второй - направление вверх
        transform.rotation = Quaternion.Slerp(transform.rotation, rotation, _speed * Time.deltaTime); // либо вместо Slerp использовать RotateTowards
    }

    private void Update()
    {
        LookAt(_point.position);
    }
}