Основная проблема заключается в том, что при использовании cam.ScreenToWorldPoint(Input.mousePosition);
с перспективной камерой всегда возвращается положение камеры (это очень распространенная ошибка), поэтому вместо работы с положением мыши относительно куба вы работаете с камера против куба.
Вам нужно использовать другой метод, чтобы использовать положение мыши, учитывая, где куб сравнивается с камерой.
Один из способов получить желаемое поведение - создать плоскость, проходящую через куб перпендикулярно направлению камеры, и посмотреть, где луч мыши пересекается с плоскостью. Кроме того, установите флаг cubeisClicked2
в значение false, установив его в значение true, пока мы фактически нажимаем на плоскость:
cubePosition = Player.transform.position;
if ((Input.GetKey(KeyCode.Mouse0) && cubeisClicked) && ((rb.velocity.x == 0f && rb.velocity.y == 0f)))
{
cubeisClicked2 = false;
Plane cubePlane = new Plane(cam.transform.position - cubePosition, cubePosition);
// reusing camRay
// Determine if we are even hitting the plane
float enter = 0.0f;
if (cubePlane.Raycast(camRay, out enter))
{
cubeisClicked2 = true;
fingerPosition = camRay.GetPoint(enter);
Кроме того, вам необходимо включить z-компоненты в ваши расчеты силы и траектории. Вероятно, вы можете просто использовать съемку PowerPowerX для питания компонента z. Также есть изменения, которые необходимо внести в расчеты траектории, о которых я упоминал в комментариях:
cubeFingerDiff = cubePosition - fingerPosition;
ShotForce = new Vector3(cubeFingerDiff.x * shootingPowerX , cubeFingerDiff.y * shootingPowerY, cubeFingerDiff.z * shootingPowerX );
if (cubeFingerDiff.magnitude>0.4f)
{
trajectoryDots.SetActive(true);
}
else
{
trajectoryDots.SetActive(false);
}
for (int dotNumber = 0; dotNumber < NumberOfDots; dotNumber++)
{
x1 = cubePosition.x + ShotForce.x * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
y1 = cubePosition.y + ShotForce.y * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift) + (Physics.gravity.y / 2f * Time.fixedDeltaTime * Time.fixedDeltaTime * (DotSeparation * dotNumber + dotShift) * (DotSeparation * dotNumber + dotShift));
z1 = cubePosition.z + ShotForce.z * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
Dots[dotNumber].transform.position = new Vector3(x1, y1, z1);
Затем вместо проверки GetKeyUp(KeyCode.Mouse0)
в том же if
, что и при определении траектории, он должен быть рядом с ним, а также проверить, была ли найдена траектория:
}
}
}
if (Input.GetKeyUp(KeyCode.Mouse0) && cubeisClicked2)
{
cubeisClicked2 = false;
trajectoryDots.SetActive(false);
rb.velocity = new Vector3 (ShotForce.x, ShotForce.y, ShotForce.z);;
}
В целом это может выглядеть так:
cubePosition = Player.transform.position;
if ((Input.GetKey(KeyCode.Mouse0) && cubeisClicked) && ((rb.velocity.x == 0f && rb.velocity.y == 0f)))
{
cubeisClicked2 = false;
Plane cubePlane = new Plane(cam.transform.position - cubePosition, cubePosition);
// reusing camRay
// Determine if we are even hitting the plane
float enter = 0.0f;
if (cubePlane.Raycast(camRay, out enter))
{
cubeisClicked2 = true;
fingerPosition = camRay.GetPoint(enter);
cubeFingerDiff = cubePosition - fingerPosition;
ShotForce = new Vector3(cubeFingerDiff.x * shootingPowerX , cubeFingerDiff.y * shootingPowerY, cubeFingerDiff.z * shootingPowerX );
if (cubeFingerDiff.magnitude>0.4f)
{
trajectoryDots.SetActive(true);
}
else
{
trajectoryDots.SetActive(false);
}
for (int dotNumber = 0; dotNumber < NumberOfDots; dotNumber++)
{
x1 = cubePosition.x + ShotForce.x * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
y1 = cubePosition.y + ShotForce.y * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift) + (Physics.gravity.y / 2f * Time.fixedDeltaTime * Time.fixedDeltaTime * (DotSeparation * dotNumber + dotShift) * (DotSeparation * dotNumber + dotShift));
z1 = cubePosition.z + ShotForce.z * Time.fixedDeltaTime * (DotSeparation * dotNumber * dotShift);
Dots[dotNumber].transform.position = new Vector3(x1, y1, z1);
}
}
}
if (Input.GetKeyUp(KeyCode.Mouse0) && cubeisClicked2)
{
cubeisClicked2 = false;
trajectoryDots.SetActive(false);
rb.velocity = new Vector3 (ShotForce.x, ShotForce.y, ShotForce.z);;
}
Так как это вычисляет мощность снимка на расстоянии, на которое вы указываете cubePlane
, когда камера находится дальше, вы сможете снимать сильнее.
Вероятно, это не то поведение, которое вам нужно, но если камера всегда находится на одном и том же расстоянии от куба, это не должно быть проблемой.
Если это неприемлемое ограничение, вы, вероятно, можете сделать что-то вроде деления ShotForce
на расстояние между кубом и камерой и увеличения shootingPowerX
и shootingPowerY
по мере необходимости. Если вы не можете найти хорошее решение самостоятельно, его лучше задать в отдельном вопросе.