Предел масштабирования в Unity Mobile. Перспективная камера - PullRequest
0 голосов
/ 16 июня 2020

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

В любом случае, вот код, который я использую и был бы признателен, если бы кто-то мог помочь!

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

class ScrollAndPinch : MonoBehaviour
{
#if UNITY_IOS || UNITY_ANDROID
  public Camera Camera;
  public bool Rotate;
  protected Plane Plane;

  public float scrollSpeed;
  public float rotateSpeed;
  public float zoomSpeed;

  public float zoomMinY;
  public float zoomMaxY;

  public float camsummer;

  Vector3 pos;
  private Vector3 velocity = Vector3.zero;


  private void Awake()
  {
    if (Camera == null)
      Camera = Camera.main;

    Rotate = true;

    scrollSpeed = 50f;
    rotateSpeed = 50f;
    zoomSpeed = 1f;

    zoomMinY = 50f;
    zoomMaxY = 200f;

    camsummer = 0.1f;

    pos = new Vector3(0f, 0f, 0f);

  }

  private void Update()
  {

    //Update Plane
    if (Input.touchCount >= 1)
      Plane.SetNormalAndPosition(transform.up, transform.position);

    var Delta1 = Vector3.zero;
    var Delta2 = Vector3.zero;

    //Scroll
    if (Input.touchCount == 1)
    {
      Delta1 = PlanePositionDelta(Input.GetTouch(0));
      if (Input.GetTouch(0).phase == TouchPhase.Moved)
        Camera.transform.Translate(Delta1 * scrollSpeed * Time.deltaTime, Space.World);
    }

    //Pinch
    if (Input.touchCount == 2)
    {
      var pos1 = PlanePosition(Input.GetTouch(0).position);
      var pos2 = PlanePosition(Input.GetTouch(1).position);
      var pos1b = PlanePosition(Input.GetTouch(0).position - Input.GetTouch(0).deltaPosition);
      var pos2b = PlanePosition(Input.GetTouch(1).position - Input.GetTouch(1).deltaPosition);

      //calc zoom to be done relative to the distance moved between the fingers
      var zoom = (Vector3.Distance(pos1, pos2) /
                 Vector3.Distance(pos1b, pos2b));

      //edge case (Bad calculation)
      if (zoom == 0 || zoom > 10)
        return;

      //Move cam amount the mid ray. This is where the zoom is applied

      // Vector3 pos = Camera.transform.position;
      // pos.y = Mathf.Clamp(pos.y, zoomMinY, zoomMaxY);
      // Camera.transform.position = Vector3.Lerp(pos1, Camera.transform.position, (1 / zoom));
      // Camera.transform.position = pos;



      if (Camera.transform.position.y < zoomMinY | Camera.transform.position.y > zoomMaxY)
      {
        // Camera.transform.position = pos;
        Camera.transform.position = Vector3.SmoothDamp(Camera.transform.position, pos, ref velocity, camsummer);
        // Camera.transform.position = Vector3.LerpUnclamped(Camera.transform.position, pos, camsummer);
        // for (int i = 0; i < 1000; i++)
        // {
        // }

      }
      else if (Camera.transform.position.y >= zoomMinY && Camera.transform.position.y <= zoomMaxY)
      {
        pos = Camera.transform.position;
        Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
        //This is where the rotation is applied
        if (Rotate && pos2b != pos2)
          Camera.transform.RotateAround(pos1, Plane.normal,
            Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal) * rotateSpeed * Time.deltaTime);
      }
      // pos.y = zoomMinY;
    }



    // if (Camera.transform.position.y > 200)
    // {
    //   zoomMaxY.y = 200;
    //   Camera.transform.position = zoomMaxY;
    // }
    // else if (Camera.transform.position.y < 50)
    // {
    //   zoomMinY.y = 50;
    //   Camera.transform.position = zoomMinY;
    // }
    // else if (Camera.transform.position.y >= 50 && Camera.transform.position.y <= 200)
    // {
    //   Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
    // }


    // Vector3 Cam = Mathf.Clamp(Camera.transform.position.y, zoomMinY.y, zoomMaxY.y);


    // if (Camera.transform.position.y > zoomMaxY || Camera.transform.position.y < zoomMinY)
    // {
    //   Vector3 camLimit = Camera.transform.position;
    //   camLimit.y = Mathf.Clamp(Camera.transform.position.y, zoomMinY, zoomMaxY);
    //   Camera.transform.position = camLimit;



    //   // Vector3 camLimit = Camera.transform.position;
    //   // camLimit = (transform.position.);
    //   // Camera.transform.position = camLimit;
    // }
    // else if (Camera.transform.position.y >= zoomMinY && Camera.transform.position.y <= zoomMaxY)
    // {
    //   Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
    // }





  }

  protected Vector3 PlanePositionDelta(Touch touch)
  {
    //not moved
    if (touch.phase != TouchPhase.Moved)
      return Vector3.zero;

    //delta: How far have we moved from A to B by sliding the finger
    var rayBefore = Camera.ScreenPointToRay(touch.position - touch.deltaPosition);
    var rayNow = Camera.ScreenPointToRay(touch.position);
    if (Plane.Raycast(rayBefore, out var enterBefore) && Plane.Raycast(rayNow, out var enterNow))
      return rayBefore.GetPoint(enterBefore) - rayNow.GetPoint(enterNow);

    //not on plane
    return Vector3.zero;
  }

  protected Vector3 PlanePosition(Vector2 screenPos)
  {
    //position
    var rayNow = Camera.ScreenPointToRay(screenPos);
    if (Plane.Raycast(rayNow, out var enterNow))
      return rayNow.GetPoint(enterNow);

    return Vector3.zero;
  }

  private void OnDrawGizmos()
  {
    Gizmos.DrawLine(transform.position, transform.position + transform.up);
  }
#endif
}

И чтобы было легче увидеть, это та часть, которую я изо всех сил пытаюсь заставить работать.

if (Camera.transform.position.y < zoomMinY | Camera.transform.position.y > zoomMaxY)
      {
        Camera.transform.position = Vector3.SmoothDamp(Camera.transform.position, pos, ref velocity, camsummer);


      }
      else if (Camera.transform.position.y >= zoomMinY && Camera.transform.position.y <= zoomMaxY)
      {
        pos = Camera.transform.position;
        Camera.transform.position = Vector3.LerpUnclamped(pos1, Camera.transform.position, (1 / zoom));
        //This is where the rotation is applied
        if (Rotate && pos2b != pos2)
          Camera.transform.RotateAround(pos1, Plane.normal,
            Vector3.SignedAngle(pos2 - pos1, pos2b - pos1b, Plane.normal) * rotateSpeed * Time.deltaTime);
      }

1 Ответ

0 голосов
/ 17 июня 2020

Это происходит, когда камера приближается к объекту? Если это так, измените расстояние ближней плоскости клипа на вашей камере на .near = 0

Это должно помешать ему не отображать игровой объект, если ваша камера продолжает двигаться, это может вызвать мерцание, потому что оно защелкивается и выходит из около плоскости зажима

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