unity曲线射击




b站教程

csharp 复制代码
using UnityEngine;
using System.Collections;

public class BallLauncher : MonoBehaviour {
    public float m_R;
	public NewBullet m_BulletPre;
	public Transform m_Target;
    private void Start()
    {
        StartCoroutine(Attack());
    }
    private void OnDestroy()
    {
        StopAllCoroutines();
    }
    private IEnumerator Attack()
    {
        while(true)
        {
            NewBullet bullet = Instantiate(m_BulletPre, transform.position, Quaternion.identity);
            bullet.Attack(transform.position, GetRandomPoint(m_R), m_Target);
            yield return new WaitForSeconds(0.1f);
            yield return null;
        }
    }
    private Vector3 GetRandomPoint(float r)
    {
        float x = Random.Range(-r, r);
        float ydis = m_Target.position.y - transform.position.y;
        float y = Random.Range(1, ydis);
        float z = Random.Range(-r, r);
        Vector3 vector3 = new Vector3(x, y, 0);
        return transform.position + vector3;
    }
}
	

第一种教程里面的

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{
    public float speed = 5f;
    private void Start()
    {
        Destroy(gameObject,15f);
    }
    private void OnDestroy()
    {
        StopAllCoroutines();
    }
    public void Attack(Vector3 start, Vector3 midPoint, Transform target)
    {
        StartCoroutine(Move(start, midPoint, target));
    }
    private IEnumerator Move(Vector3 start, Vector3 midPoint, Transform target)
    {
        for (float i = 0; i <= 1f; i += Time.deltaTime)
        {
            Vector3 p1 = Vector3.Lerp(start, midPoint, i);
            Vector3 p2 = Vector3.Lerp(midPoint, target.position, i);
            Vector3 p = Vector3.Lerp(p1, p2, i);
            //让子弹移动到p点
            yield return StartCoroutine(MoveToPoint(p));
        }

        yield return StartCoroutine(MoveToObject(target));
    }
    private IEnumerator MoveToPoint(Vector3 p)
    {
        yield return null;
        while (Vector3.Distance(transform.position, p) > 0.1f){
            Vector3 dir = p - transform.position;
            transform.up = dir;
            transform.position = Vector3.MoveTowards(transform.position, p, Time.deltaTime * speed);
            yield return null;
        }
    }
   private IEnumerator MoveToObject(Transform target)
    {
        yield return null;
        while (Vector3.Distance(transform.position, target.position) > 0.1f){
            Vector3 dir = target.position - transform.position;
            transform.up = dir;
            transform.position = Vector3.MoveTowards(transform.position, target.position, Time.deltaTime * speed);
            yield return null;
        }
    }
    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.name=="Target")
        {
            Destroy(gameObject);
        }
    }
}

第二种:教程发给DeepSeek后的

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBullet : MonoBehaviour
{
    public float speed = 5f;
    [SerializeField] private string targetTag = "Target"; // 使用标签检测目标

    private Transform target;
    private Coroutine moveCoroutine;

    private void Start() => Destroy(gameObject, 15f);

    public void Attack(Vector3 start, Vector3 midPoint, Transform target)
    {
        this.target = target;
        moveCoroutine = StartCoroutine(MoveCoroutine(start, midPoint, target));
    }

    private IEnumerator MoveCoroutine(Vector3 start, Vector3 midPoint, Transform target)
    {
        // 贝塞尔曲线阶段
        Vector3 endPosition = target.position;
        float duration = CalculateBezierDuration(start, midPoint, endPosition);
        float t = 0f;

        while (t < 1f)
        {
            if (target == null)
            {
                Destroy(gameObject);
                yield break;
            }

            endPosition = target.position; // 动态更新终点位置
            UpdatePositionAndRotation(t, start, midPoint, endPosition);

            t += Time.deltaTime / duration;
            yield return null;
        }

        // 精确追踪阶段
        while (target != null)
        {
            UpdatePositionAndRotation(target.position);
            if (Vector3.Distance(transform.position, target.position) <= 0.1f) break;
            yield return null;
        }

        Destroy(gameObject);
    }

    private float CalculateBezierDuration(Vector3 start, Vector3 mid, Vector3 end)
    {
        // 采样估算曲线长度
        float sampledLength = 0f;
        Vector3 prev = start;
        for (int i = 1; i <= 5; i++)
        {
            Vector3 point = CalculateBezierPoint(i / 5f, start, mid, end);
            sampledLength += Vector3.Distance(prev, point);
            prev = point;
        }
        return sampledLength / speed;
    }

    private Vector3 CalculateBezierPoint(float t, Vector3 start, Vector3 mid, Vector3 end) =>
        (1 - t) * (1 - t) * start + 2 * (1 - t) * t * mid + t * t * end;

    private void UpdatePositionAndRotation(float t, Vector3 start, Vector3 mid, Vector3 end)
    {
        Vector3 targetPos = CalculateBezierPoint(t, start, mid, end);
        Vector3 direction = targetPos - transform.position;
        transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
        if (direction != Vector3.zero)
            transform.up = direction;
    }

    private void UpdatePositionAndRotation(Vector3 targetPos)
    {
        Vector3 direction = targetPos - transform.position;
        transform.position = Vector3.MoveTowards(transform.position, targetPos, speed * Time.deltaTime);
        if (direction != Vector3.zero)
            transform.up = direction;
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag(targetTag))
            Destroy(gameObject);
    }

    private void OnDestroy()
    {
        if (moveCoroutine != null)
            StopCoroutine(moveCoroutine);
    }
}
相关推荐
qq_428639612 小时前
虚幻基础:碰撞&帧运算
游戏引擎·虚幻
JuicyActiveGilbert6 小时前
【C++游戏引擎开发】第9篇:数学计算库GLM(线性代数)、CGAL(几何计算)的安装与使用指南
c++·线性代数·游戏引擎
虾球xz8 小时前
游戏引擎学习第217天
c++·学习·游戏引擎
Lareina~9 小时前
【元表 vs 元方法】
unity·lua
虾球xz12 小时前
游戏引擎学习第215天
网络·学习·游戏引擎
Clank的游戏栈13 小时前
Unity IL2CPP内存泄漏追踪方案(基于Memory Profiler)技术详解
unity·游戏引擎
归海_一刀15 小时前
Unity跨平台输入系统
unity·游戏引擎·输入系统
虾球xz15 小时前
游戏引擎学习第197天
java·学习·游戏引擎
向宇it15 小时前
【unity游戏开发入门到精通——动画篇】Animator反向动力学(IK)
开发语言·unity·c#·编辑器·游戏引擎