使用移动相机拖动并拍摄unity2d

问题描述 投票:0回答:1

我有一个

  • 基于玩家的点击和拖动移动系统
  • 跟随玩家的摄像机

但是,如果我的

 Camera
正在移动,并且我按住鼠标按钮,通过单击和拖动系统来移动播放器,它会认为我正在将光标拖动到与相机移动相反的方向。

using UnityEngine;
using UnityEngine.EventSystems;


public class DragAndShoot : MonoBehaviour
{
    MusicManager musicmanager;
    private void Awake()
    {
        musicmanager = GameObject.FindGameObjectWithTag("SFX").GetComponent<MusicManager>();
    }
    [Header("Movement")]
    public float maxPower;
    float shootPower;
    public float gravity = 1;

    public bool IsColliding;


    void OnCollisionEnter2D(Collision2D col)
    {
        
        if (col.gameObject.tag == "ground")
        {
            IsColliding = true;
            
        }
    }

    void OnCollisionExit2D(Collision2D col)
    {
        IsColliding = false;
    }


    public bool shootWhileMoving = false;
    public bool forwardDraging = true;
    public bool showLineOnScreen = false;

    Transform direction;
    Rigidbody2D rb;
    LineRenderer line;
    LineRenderer screenLine;

    // Vectors // 
    Vector2 startPosition;
    Vector2 targetPosition;
    Vector2 startMousePos;
    Vector2 currentMousePos;

    bool canShoot = true;



    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        rb.gravityScale = gravity;
        line = GetComponent<LineRenderer>();
        direction = transform.GetChild(0);
        screenLine = direction.GetComponent<LineRenderer>();
    }

    void Update()
    {
        

        if (Input.GetMouseButtonDown(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseClick();
        }
        if (Input.GetMouseButton(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseDrag();

            

        }

        if (Input.GetMouseButtonUp(0))
        {
             if (EventSystem.current.currentSelectedGameObject) return;  //ENABLE THIS IF YOU DONT WANT TO IGNORE UI
            MouseRelease();
        }


        if (shootWhileMoving)
            return;

        if (IsColliding == true)
        {
            //rb.velocity = new Vector2(0, 0); //ENABLE THIS IF YOU WANT THE BALL TO STOP IF ITS MOVING SO SLOW
            canShoot = true;
            
        }
        else
            canShoot = false;
    }

    // MOUSE INPUTS
    void MouseClick()
    {
        if (shootWhileMoving || canShoot)
        {
            Vector3 mousePosition = Input.mousePosition;
            Vector2 dir = transform.position - Camera.main.ScreenToWorldPoint(mousePosition);
            transform.right = dir * 1;
            startMousePos = Camera.main.ScreenToWorldPoint(mousePosition);
        }
    }
    void MouseDrag()
    {
        if (shootWhileMoving || canShoot)
        {
            LookAtShootDirection();
            DrawLine();

            if (showLineOnScreen)
                DrawScreenLine();

            float distance = Vector2.Distance(currentMousePos, startMousePos);
            if (distance > 1)
            {
                line.enabled = true;
                if (showLineOnScreen)
                    screenLine.enabled = true;
            }
        }
    }
    void MouseRelease()
    {
        if (shootWhileMoving /*&& !EventSystem.current.IsPointerOverGameObject()*/)
        {
            Shoot();
            screenLine.enabled = false;
            line.enabled = false;
        }
        else
        {
            if (canShoot /*&& !EventSystem.current.IsPointerOverGameObject()*/)
            {
                Shoot();
                screenLine.enabled = false;
                line.enabled = false;
            }
        }

    }


    // ACTIONS  
    void LookAtShootDirection()
    {
        Vector3 dir = startMousePos - currentMousePos;

        if (forwardDraging)
        {
            transform.right = dir * -1;
        }
        else
        {
            transform.right = dir;
        }


        float dis = Vector2.Distance(startMousePos, currentMousePos);
        dis *= 4;


        if (dis < maxPower)
        {
            direction.localPosition = new Vector2(dis / 6, 0);
            shootPower = dis;
        }
        else
        {
            shootPower = maxPower;
            direction.localPosition = new Vector2(maxPower / 6, 0);
        }

    }
    public void Shoot()
    {
        canShoot = false;
        rb.velocity = transform.right * shootPower;
        musicmanager.PlaySFX(musicmanager.shoot);

    }


    void DrawScreenLine()
    {



        screenLine.positionCount = 1;
        screenLine.SetPosition(0, startMousePos);


        screenLine.positionCount = 2;
        screenLine.SetPosition(1, currentMousePos);
    }

    void DrawLine()
    {

        startPosition = transform.position;

        line.positionCount = 1;
        line.SetPosition(0, startPosition);


        targetPosition = direction.transform.position;
        currentMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        line.positionCount = 2;
        line.SetPosition(1, targetPosition);
    }

    Vector3[] positions;


}

我该如何解决这个问题?

c# unity-game-engine scripting 2d game-development
1个回答
0
投票

您的问题是由于屏幕空间坐标和世界空间坐标如何相互作用而产生的,尤其是当相机移动时。您的单击和拖动系统正在考虑鼠标在世界空间中的位置,但是如果您在拖动时相机正在移动,则光标的世界空间位置也会发生变化。

您正在使用 Camera.main.ScreenToWorldPoint(mousePosition); 获取鼠标单击的世界位置。该函数将鼠标的屏幕位置转换为游戏世界中的位置。但是,如果相机在您开始拖动后移动,则即使屏幕位置没有变化,鼠标的世界位置也会发生变化。

解决此问题的一种方法是始终在屏幕空间而不是世界空间中计算鼠标拖动距离。也就是说,不要立即将鼠标位置转换为世界坐标,而是将其保留在屏幕坐标中,直到您准备好计算拖动力。

这是执行此操作的 MouseClick() 和 MouseDrag() 方法的一个版本:

void MouseClick()
{
    if (shootWhileMoving || canShoot)
    {
        Vector3 mousePosition = Input.mousePosition;
        Vector2 dir = transform.position - Camera.main.ScreenToWorldPoint(mousePosition);
        transform.right = dir * 1;
        startMousePos = mousePosition; // keep this in screen space
    }
}

void MouseDrag()
{
    if (shootWhileMoving || canShoot)
    {
        currentMousePos = Input.mousePosition; // also keep this in screen space
        LookAtShootDirection();
        DrawLine();

        if (showLineOnScreen)
            DrawScreenLine();

        float distance = Vector2.Distance(currentMousePos, startMousePos);
        if (distance > 1)
        {
            line.enabled = true;
            if (showLineOnScreen)
                screenLine.enabled = true;
        }
    }
}

那么你还需要修改LookAtShootDirection()函数:

void LookAtShootDirection()
{
    Vector3 dir = Camera.main.ScreenToWorldPoint(startMousePos) - Camera.main.ScreenToWorldPoint(currentMousePos);

    if (forwardDraging)
    {
        transform.right = dir * -1;
    }
    else
    {
        transform.right = dir;
    }

    float dis = Vector2.Distance(startMousePos, currentMousePos);
    dis *= 4;

    if (dis < maxPower)
    {
        direction.localPosition = new Vector2(dis / 6, 0);
        shootPower = dis;
    }
    else
    {
        shootPower = maxPower;
        direction.localPosition = new Vector2(maxPower / 6, 0);
    }
}

这应该可以准确计算阻力,无论相机如何移动。

© www.soinside.com 2019 - 2024. All rights reserved.