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);
}
}