Files
daluandou/Assets/Script/Projectile.cs
T
huadexuan 2728c1d2cc ```
feat(game): 删除弓箭手相关资源文件

删除了弓箭手预制体(Arrow.prefab)及其元文件,
同时移除了对应的白色箭矢材质(ArrowProjectile_White.mat)及元文件,
清理了项目中不再使用的箭矢相关资源。
```
2026-08-28 18:10:47 +08:00

133 lines
3.0 KiB
C#

using UnityEngine;
public class Projectile : MonoBehaviour
{
private GameObject target;
private GameObject owner;
private float damage;
private float speed;
private float lifetime;
private bool initialized;
private bool hasHit;
public void Initialize(
GameObject targetObject,
float damageAmount,
GameObject ownerObject,
float moveSpeed,
float lifeTime)
{
target = targetObject;
damage = damageAmount;
owner = ownerObject;
speed = moveSpeed;
lifetime = lifeTime;
initialized = true;
hasHit = false;
if (lifetime > 0f)
{
Destroy(gameObject, lifetime);
}
}
private void Update()
{
if (!initialized)
{
return;
}
if (target == null)
{
Destroy(gameObject);
return;
}
// 目标根节点位于脚底,只取水平差值,让箭保持当前高度平行飞行。
Vector3 offset = target.transform.position - transform.position;
offset.y = 0f;
if (offset.sqrMagnitude <= 0.01f)
{
HitTarget(target);
return;
}
Vector3 direction = offset.normalized;
float distance = speed * Time.deltaTime;
if (distance >= offset.magnitude)
{
HitTarget(target);
return;
}
if (Physics.Raycast(transform.position, direction, out RaycastHit hit, distance))
{
TryHit(hit.collider.gameObject);
if (hit.collider.transform.root == target.transform.root)
{
return;
}
}
transform.forward = direction;
transform.position += direction * distance;
}
private void OnTriggerEnter(Collider other)
{
TryHit(other.gameObject);
}
private void OnCollisionEnter(Collision collision)
{
TryHit(collision.gameObject);
}
private void TryHit(GameObject hitObject)
{
if (!initialized || hitObject == null || target == null || IsOwner(hitObject))
{
return;
}
if (hitObject.transform.root == target.transform.root)
{
HitTarget(hitObject);
}
}
private void HitTarget(GameObject hitObject)
{
if (hasHit)
{
return;
}
WorldHealthBar healthBar = hitObject.GetComponentInParent<WorldHealthBar>();
if (healthBar == null)
{
return;
}
hasHit = true;
healthBar.TakeDamage(damage);
if (owner != null)
{
UnitBase unit = owner.GetComponent<UnitBase>();
if (unit != null)
{
unit.RegisterAttackHit();
}
}
Destroy(gameObject);
}
private bool IsOwner(GameObject hitObject)
{
return owner != null &&
(hitObject == owner || hitObject.transform.root == owner.transform.root);
}
}