unity如何能够像愤怒的小鸟那种抛物线一样发射一道轨迹,可以拖动轨迹调整轨迹落点。还可以显示落点与一个指定点的距离?

类似这种抛物线

img


可以自己调节抛物线落点,抛物线是实线的而且可以显示落点与一个物体的距离。最好能给出脚本,chatgpt的就算了,有很多小问题,而且我自己就查了。希望有真正会的朋友讲一讲。还有就是轨迹只能用粒子效果做吗,别的行不行。

您好,关于您提出的unity实现抛物线的问题,可以在unity使用transform进行位移模拟,让物体同时在两个方向产生位移就行了,一个是初速度方向,一个是垂直方向。对于直接的脚本,我觉得除非有哪位大神完全做过一模一样,才能直接给您提供脚本,否则都是chatgpt答案。所以挺难的,建议您根据网上的使用unity实现风怒的小鸟的案例,自己参考着来实现比较靠谱,比如:
unity抛物线_发射弓箭轨迹的实现(https://blog.csdn.net/lizhenxiqnmlgb/article/details/93760717
nity3D游戏-愤怒的小鸟游戏源码和教程:https://www.shuzhiduo.com/A/Ae5RQWLYJQ/
或者你自己找下资料都可以。

可以使用Unity的Physics组件来模拟物理效果,并使用Line Renderer来绘制抛物线轨迹。
首先,在场景中创建一个发射器和一个目标物体,然后创建一个空物体并将其作为抛物线轨迹的起点。
接下来,编写一个脚本来控制抛物线发射的行为。以下是一个示例脚本:


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

public class TrajectoryRenderer : MonoBehaviour
{
    public GameObject target;
    public Transform startPoint;
    public LineRenderer lineRenderer;
    public int segmentCount = 20;
    public float segmentScale = 1;
    public float yOffset = 0.5f;
    public float distanceThreshold = 0.5f;

    private Vector3 lastTargetPosition;

    void Start()
    {
        if (lineRenderer == null)
        {
            lineRenderer = GetComponent<LineRenderer>();
        }

        if (startPoint == null)
        {
            startPoint = transform;
        }

        lastTargetPosition = target.transform.position;
        lineRenderer.positionCount = segmentCount;
    }

    void Update()
    {
        if (target == null || lineRenderer == null || startPoint == null)
        {
            return;
        }

        // Check if the target has moved significantly
        if ((target.transform.position - lastTargetPosition).magnitude > distanceThreshold)
        {
            lastTargetPosition = target.transform.position;

            Vector3 start = startPoint.position;
            Vector3 end = target.transform.position;
            Vector3 dir = end - start;

            lineRenderer.enabled = true;

            // Calculate the parabolic trajectory and draw the line
            for (int i = 0; i < segmentCount; i++)
            {
                float t = (float)i / (float)segmentCount;
                Vector3 point = CalculatePoint(start, end, dir, t);
                point.y += yOffset;
                lineRenderer.SetPosition(i, point);
            }
        }
        else
        {
            lineRenderer.enabled = false;
        }
    }

    private Vector3 CalculatePoint(Vector3 start, Vector3 end, Vector3 dir, float t)
    {
        float x = start.x + dir.x * t;
        float y = start.y + dir.y * t + (Physics.gravity.y / 2) * t * t;
        float z = start.z + dir.z * t;

        return new Vector3(x, y, z);
    }

    public void SetTarget(GameObject newTarget)
    {
        target = newTarget;
        lastTargetPosition = target.transform.position;
    }
}

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
要实现像愤怒的小鸟那种抛物线轨迹效果,可以通过以下步骤进行:

  1. 创建一个空物体作为轨迹的父物体,将抛物线轨迹中的每个点作为该父物体下的子物体,在每个点上放置一个小球或粒子效果,为了方便操作,可以给每个点加上一个自定义的脚本。

  2. 为了实现可以拖动轨迹调整轨迹落点,可以使用鼠标在场景中点击来确定抛物线落点,根据点击位置计算出发射角度和发射速度,然后根据预设的时间间隔以及初始速度和角度计算出每个点的位置,将其作为子物体添加到轨迹父物体下。

  3. 为了显示落点与一个指定点的距离,可以在落点处添加一个新的小球或粒子效果,并在该小球或粒子效果上添加一个距离计算器脚本,该脚本可以计算出该小球或粒子效果与指定点的距离,并将该距离显示在该小球或粒子效果上。

以下是大致的实现思路及部分代码。

  1. 创建轨迹的父物体,将抛物线轨迹中的每个点作为该父物体的子物体,在每个点上放置一个小球或粒子效果。
public class TrajectoryPoint : MonoBehaviour
{
    // 自定义脚本,保存该点的参数和位置
    public Vector3 position;  // 该点的位置
    public float time;  // 发射该点时的时间
    public float speed;  // 发射该点时的速度
    public float angle;  // 发射该点时的角度
}
  1. 通过鼠标点击事件来修改轨迹的位置和参数。
// 在 Update 函数中监听鼠标点击事件
void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        // 获取鼠标点击的位置
        Vector3 clickPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        clickPosition.z = 0;

        // 计算抛物线发射角度,并更新轨迹
        trajectoryAngle = CalculateAngle(clickPosition);
        UpdateTrajectory();
    }
}

// 计算抛物线发射角度
float CalculateAngle(Vector3 targetPosition)
{
    Vector3 direction = targetPosition - transform.position;
    float horizontalDistance = direction.magnitude;
    float verticalDistance = transform.position.y - targetPosition.y;
    return Mathf.Atan((verticalDistance + Mathf.Sqrt(verticalDistance * verticalDistance +
           2 * gravity * horizontalDistance)) / (gravity * horizontalDistance)) * Mathf.Rad2Deg;
}

// 更新轨迹
void UpdateTrajectory()
{
    // 清空之前的轨迹点
    foreach (Transform child in trajectoryParent.transform)
    {
        Destroy(child.gameObject);
    }

    // 计算新的轨迹点
    for (float t = 0; t <= maxTime; t += timeStep)
    {
        float x = initialSpeed * Mathf.Cos(trajectoryAngle * Mathf.Deg2Rad) * t;
        float y = initialSpeed * Mathf.Sin(trajectoryAngle * Mathf.Deg2Rad) * t -
                0.5f * gravity * t * t;
        Vector3 position = new Vector3(transform.position.x + x, transform.position.y + y, 0);

        // 将每个点作为子物体添加到轨迹父物体下,并添加自定义脚本
        GameObject point = Instantiate(trajectoryPointPrefab, position, Quaternion.identity);
        point.transform.parent = trajectoryParent.transform;
        TrajectoryPoint trajectoryPoint = point.GetComponent<TrajectoryPoint>();
        trajectoryPoint.position = position;
        trajectoryPoint.time = t;
        trajectoryPoint.speed = initialSpeed;
        trajectoryPoint.angle = trajectoryAngle;
    }
}
  1. 添加距离计算器脚本,并在小球或粒子效果上显示距离。
public class DistanceCalculator : MonoBehaviour
{
    public Transform target;  // 指定点的位置

    void Start()
    {
        // 显示距离文本对象
        GameObject distanceTextObject = new GameObject("DistanceText");
        distanceTextObject.transform.parent = transform;
        distanceTextObject.transform.localPosition = Vector3.zero;
        TextMesh distanceText = distanceTextObject.AddComponent<TextMesh>();
        distanceText.color = Color.yellow;
        distanceText.characterSize = 0.1f;
        distanceText.alignment = TextAlignment.Center;
        distanceText.anchor = TextAnchor.MiddleCenter;
    }

    void Update()
    {
        // 计算当前小球或粒子效果与指定点的距离,并更新距离文本
        float distance = Vector3.Distance(transform.position, target.position);
        GetComponentInChildren<TextMesh>().text = distance.ToString("F2") + "m";
    }
}

最后,可以通过修改轨迹的小球或粒子效果的材质,使轨迹变为实线。另外,也可以通过更换轨迹的小球或粒子效果的预设,在显示距离的同时展示更多的效果。
如果我的回答解决了您的问题,请采纳!

贝塞尔曲线