You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
65 lines
2.1 KiB
C#
65 lines
2.1 KiB
C#
5 days ago
|
using UnityEngine;
|
||
|
|
||
|
public class BallShooter : MonoBehaviour
|
||
|
{
|
||
|
public GameObject ballPrefab;
|
||
|
public Transform spawnPoint;
|
||
|
public float arcHeight = 2f;
|
||
|
|
||
|
void Update()
|
||
|
{
|
||
|
if (Input.GetMouseButtonDown(0))
|
||
|
{
|
||
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||
|
Vector3 target;
|
||
|
|
||
|
if (Physics.Raycast(ray, out RaycastHit hit))
|
||
|
{
|
||
|
target = hit.point;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
target = ray.GetPoint(10f); // fallback
|
||
|
}
|
||
|
|
||
|
if (Vector3.Distance(spawnPoint.position, target) < 0.1f)
|
||
|
return; // avoid NaN if click too close
|
||
|
|
||
|
GameObject ball = Instantiate(ballPrefab, spawnPoint.position, Quaternion.identity);
|
||
|
Rigidbody rb = ball.GetComponent<Rigidbody>();
|
||
|
rb.useGravity = true;
|
||
|
|
||
|
Vector3 velocity = CalculateArcVelocity(spawnPoint.position, target, arcHeight);
|
||
|
if (float.IsNaN(velocity.x) || float.IsNaN(velocity.y) || float.IsNaN(velocity.z))
|
||
|
{
|
||
|
Destroy(ball); // safety: don't throw broken ball
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
rb.velocity = velocity;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Vector3 CalculateArcVelocity(Vector3 start, Vector3 end, float height)
|
||
|
{
|
||
|
float gravity = Mathf.Abs(Physics.gravity.y);
|
||
|
|
||
|
Vector3 displacementXZ = new Vector3(end.x - start.x, 0, end.z - start.z);
|
||
|
float horizontalDist = displacementXZ.magnitude;
|
||
|
|
||
|
if (horizontalDist < 0.01f) horizontalDist = 0.01f; // prevent divide-by-zero
|
||
|
|
||
|
float heightDifference = end.y - start.y;
|
||
|
height = Mathf.Max(height, heightDifference + 0.1f); // ensure height is enough
|
||
|
|
||
|
float timeUp = Mathf.Sqrt(2 * height / gravity);
|
||
|
float timeDown = Mathf.Sqrt(2 * (height - heightDifference) / gravity);
|
||
|
float totalTime = timeUp + timeDown;
|
||
|
|
||
|
Vector3 velocityY = Vector3.up * Mathf.Sqrt(2 * gravity * height);
|
||
|
Vector3 velocityXZ = displacementXZ / totalTime;
|
||
|
|
||
|
return velocityXZ + velocityY;
|
||
|
}
|
||
|
}
|