#c# #unity3d
#c# #unity3d
Вопрос:
Цель состоит в том, чтобы показать как скорость преобразования, так и скорость перемещения в text1 и text2.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Follow : MonoBehaviour
{
public Transform targetToFollow;
public Text text;
public Text text1;
public Text text2;
public float lookAtRotationSpeed;
public float moveSpeed;
private float minMoveSpeed = 0f;
private Vector3 originPos;
// Start is called before the first frame update
void Start()
{
originPos = targetToFollow.position;
}
// Update is called once per frame
void Update()
{
Vector3 lTargetDir = targetToFollow.position - transform.position;
lTargetDir.y = 0.0f;
transform.rotation = Quaternion.RotateTowards(transform.rotation,
Quaternion.LookRotation(lTargetDir), Time.time * lookAtRotationSpeed);
var distance = Vector3.Distance(transform.position, targetToFollow.position);
text.text = "Transform Distance From Target " distance.ToString();
float ms = moveSpeed;
if (distance > 5f)
{
ms = moveSpeed 0.5f; //move faster
}
else if (distance < 1.5f)
{
ms = Mathf.Max(minMoveSpeed, ms - 0.3f); // move slower
}
else
{
default value that equal moveSpeed here
transform.position = Vector3.MoveTowards(transform.position, targetToFollow.position, Time.deltaTime * ms);
}
if(distance < 0.5f amp;amp; originPos == targetToFollow.position)
{
ms = 0f;
}
transform.position = Vector3.MoveTowards(transform.position, targetToFollow.position, Time.deltaTime * ms);
originPos = targetToFollow.position;
}
}
Теперь я настраиваю текст на расстояние преобразования от цели.
Но теперь я хочу добавить к text1 и text2 скорость перемещения преобразования и цели.
В конце будет 3 текстовых интерфейса, которые будут показывать расстояние и скорость движения.
Я пробовал так для целевой скорости :
var speedPerSec = Vector3.Distance(originPos, targetToFollow.position) / Time.deltaTime;
text1.text = "Target Speed Per Second " speedPerSec.ToString();
но когда цель перемещает текст скорости, speedPerSec.toString() мигает быстро и не плавно, как расстояние в первом тексте.
может быть, он мигает, потому что он показывает скорость много после нулевой точки, например: 0.00656555?
Комментарии:
1. Когда вы нажимаете значение перемещения по умолчанию («значение по умолчанию, равное скорости перемещения здесь»), вы перемещаете свой объект дважды. Один раз в предложении else, а другой раз на 8 строк ниже. Просто назначьте
ms
в предложении else, и все в порядке.
Ответ №1:
Поскольку вы хотите отслеживать скорость нескольких объектов (вашего преобразования и цели), самый простой способ — ввести отдельный объект, обрабатывающий отслеживание, и использовать их массив.
[Serializable]
private class SpeedTracking
{
public Transform trackedObject;
public Text uiOutput;
private Vector3 _position;
private float _speed;
public void Update(float elapsedTime, float changeThreshold)
{
Vector3 newPos = trackedObject.position;
float newSpeed = Vector3.Distance(newPos, _position) / elapsedTime;
if ((newSpeed == 0 amp;amp; _speed != 0) || Mathf.Abs(newSpeed - _speed) > changeThreshold)
{
_speed = newSpeed;
uiOutput.text = $"speed: {newSpeed:F3}";
}
_position = newPos;
}
}
private const float SPEED_CHANGE_THRESHOLD = 0.001F;
[SerializeField]
private SpeedTracking[] _trackings;
void OnEnable()
{
if (_trackings.Any(t => t.trackedObject == null || t.uiOutput == null))
{
Debug.LogError("at least one invalid tracking found");
enabled = false;
}
}
void Update()
{
//[...]
UpdateTrackings();
}
void UpdateTrackings()
{
foreach (SpeedTracking tracking in _trackings)
{
tracking.Update(Time.deltaTime, SPEED_CHANGE_THRESHOLD);
}
}
Я также добавил формат к вашей выходной строке (F3), показывающий только 3 десятичные цифры. (Это само по себе решило бы проблему мерцания, но зачем обновлять пользовательский интерфейс чаще, чем необходимо?)
Комментарии:
1. @Ruzihm Спасибо, да
currentPos
, был неправ. Я также обновил ответ, чтобы поддержать запрошенную оценку скорости нескольких объектов.2. Томас, я попробовал ваше решение, и сначала я попробовал его только для цели, даже если цель стоит на месте, не двигаясь вообще, она показывает скорость. Скорость равна 2586.132, и она постоянно меняется, но остается в этом диапазоне значений для скорости, которую я создал одним элементом в массиве и перетащил в него text1 с целевым объектом. Это мой код с вашим решением по ссылке. pastebin.com/RmKfWfsR
3. Если я удалю эту строку transform.position = Vector3.MoveTowards(transform.position, targetToFollow.position, Time.deltaTime * мс); и оставлю ее только в else, преобразование вообще не будет перемещаться при запуске игры. Преобразование должно перемещаться при запуске игры к цели
4. Попробуйте изменить отслеживание скорости на класс. (Я обновил ответ)
5. Не удаляйте нижнюю строку перемещения, а ту, что указана в предложении else .
Ответ №2:
Если вы только хотите знать, какая скорость объекта за определенное время, вы можете сделать что-то вроде этого.
public class VelocityDisplayer : MonoBehaviour
{
public Transform Object; // your target gameobject
public Text View; // your text object
private Vector3 _position; // last position of target
private void OnEnable() {
_position = Object.transform.position;
}
private void Update() {
var dt = Time.deltaTime;
var current = Object.transform.position;
var delta = Vector3.Distance(current, _position);
var velocity = delta / dt;
View.text = (velocity).ToString("#,##0.000");
// replace current position
_position = current;
}
}
но это показывает фактическую скорость, которая зависит от игрового мира / физики объекта, а не от вашей установочной переменной скорости движения
ПС1. Я предпочитаю использовать обновление, потому что это область пользовательского интерфейса
PS2. Я предпочитаю разделить новый класс для отслеживания объекта