Устранение дрожания камеры, вызванного изменением положения камеры в определенных пределах - PullRequest
0 голосов
/ 01 февраля 2019

enter image description here

Это изображение того, чего я пытаюсь достичь в трехмерном пространстве.Я хочу, чтобы объект следовал за моим пальцем в пределах зеленой зоны, но остался на краю зеленой зоны, если я вывожу палец за его пределы.Я добился этого с помощью приведенного ниже кода, но при перемещении пальца по красной зоне возникает много дрожаний и отсечений, поскольку объект продолжает возвращаться в свои границы.Дрожание, которое я вижу, возникает, когда я держу палец в красной зоне за пределами круга игроков.Вместо того, чтобы «застрять» в границах, игрок пытается продолжить, а затем снова оказывается в пределах границ, вызывая дрожь.Я ищу способ ограничить движение игрока в пределах границ без необходимости сбрасывать его позицию.Моя основная камера прикреплена к движущемуся объекту, поэтому важно устранить дрожание.Как я могу сгладить это?

public class Player : MonoBehaviour
{
    public Camera movementCam;
    readonly float radius = 0.45f;
    readonly float speed = 3f;
    Ray firstTouchPos;
    Vector2 playerPos;
    [SerializeField] Vector3 targetPosition;
    readonly float followDelay = 20f;

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) 
        {
            firstTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
            playerPos = transform.position;
        }

        if (Input.GetMouseButton(0)) 
        {
            Ray currentTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
            Vector2 direction = currentTouchPos.origin - firstTouchPos.origin;
            float distance = Vector3.Distance(transform.position, Vector3.zero);
            targetPosition = distance >= radius ? (Vector3) . (direction.normalized * radius) : (Vector3)(playerPos + direction * speed);
        }

        transform.position = Vector3.Lerp(transform.position, targetPosition, followDelay);
    }
}

1 Ответ

0 голосов
/ 01 февраля 2019

Ваша проблема неправильно фиксируется, простое исправление было бы:

    if (Input.GetMouseButton(0)) 
    {
        Ray currentTouchPos = movementCam.ScreenPointToRay(Input.mousePosition);
        Vector2 direction = currentTouchPos.origin - firstTouchPos.origin;
        float distance = Vector3.Distance(transform.position, Vector3.zero);
        targetPosition = (Vector3)(playerPos + direction * speed);
        if (targetPosition.sqrMagnitude > radius * radius) //if our calculated position is greater than the radius...
            targetPosition = targetPosition.normalized * radius; //set our calculated position to be exactly on the radius.
    }

Дрожание было вызвано тем, что ваш объект покинул радиус одного кадра, а в следующем кадре был бы зафиксирован обратно к радиусу,только для того, чтобы попытаться снова выйти за пределы радиуса в следующем кадре.

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

Вот несколько дополнительных советов по этой проблеме, как только вы исправите вышеуказанную проблему:

Вы должны умножить speed и followDelay на time.deltaTime, чтобы сгладить их по кадрамправильно.

Вы, вероятно, должны применять движение камеры во время LateUpdate () вместо Update (), LateUpdate () происходит после всех ваших обновлений, что может происходить во время перемещения объектов Update () до и послеВаш код камеры вызывается, заставляя его вести себя немного непоследовательно от кадра к кадруМне, применение движения в LateUpdate () к камере означает, что ваша камера перемещается только тогда, когда все ваши объекты «обосновались» на своем месте после их обновления, что делает ее более последовательной.

Кроме того, вы технически используете Lerp() здесь не так, это не должно вызывать дрожание, но это не совсем то, как следует использовать lerp.Вы уверены, что не хотите использовать Vector3.MoveTowards ()?

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