Files
daluandou/Assets/Script/Projectile.cs
T
huadexuan 0e7de5f885 ```
feat(materials): 更新材质贴图纹理和缩放参数

- 修改CoreBattleGround.mat材质的MainTex纹理GUID为4435756e5310e408fb125e8f4bcee9bd
- 调整CoreBattleGround.mat材质中EmissionMap和MainTex的缩放比例从{x: 1, y: 1}改为{x: 3, y: 3}

fix(models): 调整建筑模型全局缩放比例

- 将主要基地模型的globalScale从3调整为5
- 将水晶矿模型的globalScale从1调整为7,对应骨骼缩放从1调整为0.07
- 将机械出兵点模型的globalScale从1调整为7,对应骨骼缩放从1调整为0.07

feat(textures): 为模型添加纹理贴图

- 为水晶矿模型材质添加MainTex纹理,GUID为c24a978a0c9ad4dabb831e4b2bff0e2f
- 为机械出兵点模型材质添加MainTex纹理,GUID为fb52fc095c9554db895dde01ba8a8b6c
```
2026-09-18 18:06:09 +08:00

165 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
public class Projectile : MonoBehaviour
{
private GameObject target;
private GameObject owner;
private float damage;
private float speed;
private float lifetime;
private bool registerEnergyOnHit;
private bool initialized;
private bool hasHit;
public void Initialize(
GameObject targetObject,
float damageAmount,
GameObject ownerObject,
float moveSpeed,
float lifeTime,
bool registerEnergy = true)
{
target = targetObject;
damage = damageAmount;
owner = ownerObject;
speed = moveSpeed;
lifetime = lifeTime;
registerEnergyOnHit = registerEnergy;
initialized = true;
hasHit = false;
// The projectile uses its own raycast hit check. Disable the collider so
// it cannot be destroyed or disturbed by the owner's launch socket.
foreach (var collider in GetComponentsInChildren<Collider>(true))
{
collider.enabled = 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;
}
UnitBase targetUnit = hitObject.GetComponentInParent<UnitBase>();
CrystalMineCapture crystalMine = hitObject.GetComponentInParent<CrystalMineCapture>();
BuildingHealth targetBuilding = hitObject.GetComponentInParent<BuildingHealth>();
WorldHealthBar targetHealthBar = hitObject.GetComponentInParent<WorldHealthBar>();
if (targetUnit == null && crystalMine == null && targetBuilding == null && targetHealthBar == null)
{
return;
}
hasHit = true;
if (targetUnit != null)
{
targetUnit.ReceiveDamage(damage, owner);
}
else if (crystalMine != null)
{
crystalMine.ReceiveCaptureDamage(damage, owner);
}
else if (targetBuilding != null)
{
targetBuilding.ReceiveDamage(damage, owner);
}
else if (targetHealthBar != null)
{
// 召唤师等特殊单位(有 WorldHealthBar 但没有 UnitBase)
targetHealthBar.TakeDamage(damage, owner);
}
if (registerEnergyOnHit && 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);
}
}