Files
valheim/Assets/_Valheim/Scripts/RemoteButtlet.cs
2025-07-04 14:16:14 +08:00

130 lines
4.4 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 System.Collections;
using System.Collections.Generic;
using DragonLi.Core;
using DragonLi.Frame;
using Mirror;
using UnityEngine;
using Valheim;
public class RemoteButtlet : NetworkBehaviour
{
public int id;
[Header("飞行参数")]
// 子弹的飞行速度
public float speed = 10f;
public float rotateSpeed = 200f;
[Header("爆炸设置")]
// 爆炸粒子预制体
public GameObject explosionEffect;
public GameObject bulletEffect;
// 子弹爆炸后造成的伤害值(可根据需要调整)
public float damage = 10;
[Header("子弹来源")]
// 通过此参数区分是敌人发射的子弹还是玩家发射的子弹
// false 为玩家发射的子弹true 为敌人发射的子弹
public bool isEnemyBullet = false;
private bool isTrigger;
public GameObject target;
// 子弹实际飞行方向,由目标位置决定
private Vector3 moveDirection = Vector3.zero;
public void Init(bool isEnemy,float atk,GameObject curTarget)
{
isEnemyBullet = isEnemy;
damage = atk;
isTrigger = false;
bulletEffect.gameObject.SetActive(true);
explosionEffect.gameObject.SetActive(false);
target = curTarget;
MonoSingleton<CoroutineTaskManager>.Instance.WaitSecondTodo(() =>
{
if(!isTrigger)
Explode();
},10f);
// // 计算从当前子弹位置指向目标位置的单位向量
moveDirection =curTarget==null? transform.forward: (curTarget.transform.position+new Vector3(0,0.5f,0) - transform.position).normalized;
// // 同步设置子弹的旋转,使之看向目标方向
// transform.rotation = Quaternion.LookRotation(moveDirection);
}
void Update()
{
// 如果目标存在,则计算追踪方向,并平滑转向
if (target != null)
{
Vector3 targetDirection = (target.transform.position - transform.position).normalized;
// RotateTowards 的第三个参数接收弧度,所以需将 rotateSpeed 转换为弧度/秒
moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 30f);
transform.rotation = Quaternion.LookRotation(moveDirection);
}
// 如果目标消失,子弹将继续沿原方向飞行,不再调整旋转
// 沿当前方向进行移动
transform.position += moveDirection * (speed/2) * Time.deltaTime;
}
/// <summary>
/// 当子弹碰到其他对象时进行检测
/// </summary>
/// <param name="other">碰撞到的对象</param>
void OnTriggerEnter(Collider other)
{
// 判断如果是玩家发射的子弹,则碰到敌人时执行爆炸与扣血
if (!isEnemyBullet && other.CompareTag("Enemy"))
{
// 获取敌人的脚本组件,这里假设敌人对象有 EnemyHealth 脚本
IDamagable damagable = other.GetComponent<IDamagable>();
if (damagable != null)
{
damagable.ApplyDamage(damage, false, transform);
}
Explode();
}
// 如果是敌人发射的子弹,则碰到玩家时执行处理
else if (isEnemyBullet && other.CompareTag("Pet"))
{
// 获取玩家脚本组件,例如 PlayerHealth 脚本
IDamagable damagable = other.GetComponent<IDamagable>();
if (damagable != null)
{
damagable.ApplyDamage(damage, false, transform);
}
Explode();
}
// 碰撞到障碍物(或其他标记为 Obstacle 的物体)时也产生爆炸效果
else if (other.CompareTag("Ground"))
{
Explode();
}
// 根据需求,其他碰撞逻辑可以在此扩展
}
/// <summary>
/// 爆炸效果处理方法
/// </summary>
void Explode()
{
isTrigger = true;
bulletEffect.gameObject.SetActive(false);
explosionEffect.gameObject.SetActive(true);
// 销毁子弹对象
StartCoroutine(DelayedDestroy(3f));
}
IEnumerator DelayedDestroy(float delay)
{
yield return new WaitForSeconds(delay);
// 在销毁之前再检查一遍对象状态
if (this != null && gameObject != null && NetworkServer.active)
{
NetworkServer.Destroy(gameObject);
}
}
}