我有一个
但是,如果我的
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;
}
我该如何解决这个问题?
您的问题是由于屏幕空间坐标和世界空间坐标如何相互作用而产生的,尤其是当相机移动时。您的单击和拖动系统正在考虑鼠标在世界空间中的位置,但是如果您在拖动时相机正在移动,则光标的世界空间位置也会发生变化。
您正在使用 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);
}
}
这应该可以准确计算阻力,无论相机如何移动。