Как я могу перемещать объект между наборами путевых точек с плавным медленным вращением в каждой путевой точке, обращенной к следующей путевой точке? - PullRequest
0 голосов
/ 04 мая 2020
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Waypoints : MonoBehaviour
{
    public List<Vector3> points = new List<Vector3>();

    // Start is called before the first frame update
    void Start()
    {
        points.Add(transform.position); 
    }

    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i < points.Count; i++)
        {
            transform.position = Vector3.Lerp(points[i], pos2, (Mathf.Sin(speed * Time.time) + 1.0f) / 2.0f);
        }
    }
}

Первая путевая точка - это позиция трансформации (движущегося объекта), поэтому при запуске игры трансформация переместится в первую путевую точку и, если необходимо, сначала она будет медленно вращаться лицом к первой путевой точке, а затем переместится к ней. Когда преобразование дойдет до следующей (первой) путевой точки, оно будет медленно вращаться лицом к следующей путевой точке при перемещении к следующей путевой точке. И так до конца путевых точек; затем снова с самого начала в следующих раундах первая путевая точка будет первой второй точкой в ​​списке, не передавая исходное положение. Исходное положение будет использоваться в качестве путевой точки только в первый раз.

Я пробовал это, но objectToPatrol движется с заиканием и не движется прямо к первой путевой точке, а движется к первой путевой точке, но также вверх.

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

public class Waypoints : MonoBehaviour
{
    public Transform[] waypoints;
    public float waypointRadius = 1.5f;
    public float damping = 0.1f;
    public bool loop = false;
    public float speed = 2.0f;
    public bool faceHeading = true;
    public GameObject objectToPatrol;

    private Vector3 currentHeading, targetHeading;
    private int targetwaypoint;
    private Transform xform;
    private bool useRigidbody;
    private Rigidbody rigidmember;


    // Use this for initialization
    protected void Start()
    {
        if (objectToPatrol == null)
        {
            xform = transform;
        }
        else
        {
            xform = objectToPatrol.transform;
        }

        currentHeading = xform.forward;
        if (waypoints.Length <= 0)
        {
            Debug.Log("No waypoints on " + name);
            enabled = false;
        }
        targetwaypoint = 0;
        if (GetComponent<Rigidbody>() != null)
        {
            useRigidbody = true;
            rigidmember = GetComponent<Rigidbody>();
        }
        else
        {
            useRigidbody = false;
        }
    }


    // calculates a new heading
    protected void FixedUpdate()
    {
        targetHeading = waypoints[targetwaypoint].position - xform.position;

        currentHeading = Vector3.Lerp(currentHeading, targetHeading, damping * Time.deltaTime);
    }

    // moves us along current heading
    protected void Update()
    {
        if (useRigidbody)
            rigidmember.velocity = currentHeading * speed;
        else
            xform.position += currentHeading * Time.deltaTime * speed;
        if (faceHeading)
            xform.LookAt(xform.position + currentHeading);

        if (Vector3.Distance(xform.position, waypoints[targetwaypoint].position) <= waypointRadius)
        {
            targetwaypoint++;
            if (targetwaypoint >= waypoints.Length)
            {
                targetwaypoint = 0;
                if (!loop)
                    enabled = false;
            }
        }
    }


    // draws red line from waypoint to waypoint
    public void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        if (waypoints == null)
            return;
        for (int i = 0; i < waypoints.Length; i++)
        {
            Vector3 pos = waypoints[i].position;
            if (i > 0)
            {
                Vector3 prev = waypoints[i - 1].position;
                Gizmos.DrawLine(prev, pos);
            }
        }
    }
}

Первая проблема заключается в том, что объект, который я хочу переместить между путевыми точками, имеет компонент Animator, и аниматор заставляет его заикаться. Есть ли способ оставить аниматор включенным и плавно перемещать его, я имею в виду, что он будет продолжать воспроизводить анимацию объекта в этом случае в режиме ожидания, но также плавно перемещать его?

object to move

1 Ответ

0 голосов
/ 05 мая 2020

Вы можете попробовать использовать Vector3.MoveTowards вместо targetHeading и currentHeading, например:

var newPosition = Vector3.MoveTowards(transform.Position, waypoints[targetwaypoint].position, Time.deltaTime * speed);

if (useRigidbody)
     rigidmember.MovePosition(newPosition);
else
     xform.position.position = newPosition;

Что касается второго вопроса, вы можете попробовать поставить анимированный gameobject в пустой gameobject и поместив скрипт на родительский.

Links:
https://docs.unity3d.com/ScriptReference/Rigidbody.MovePosition.html
https://answers.unity.com/questions/199744/how-would-i-move-a-rigidbody-towards-another-objec.html
https://docs.unity3d.com/ScriptReference/Vector3.MoveTowards.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...