
炸弹虫 (U6)
已为U7更新!孤身一人上路很危险,带上这个吧!来自《塞尔达传说》的炸弹虫,将它放置在地面上,它会移动直到撞上敌人,并自动追踪目标。然后爆炸。你可以在“陷阱”分类中找到它。
查看大图public class ItemBombchu : MonoBehaviour { protected Item item; private Transform bombchuTransform; private ParticleSystem explosionEffect; private MeshRenderer mesh; private Transform targetTransform = null; private AudioSource explosionSFX; private AudioSource startRunningSFX; private AudioSource runningSFX; private float timeOut = 1f; private float timerBombchu = 0f; private bool hasExploded = false; private bool isBombchuActive = false; private bool bombchuRunning = false; private bool hasTarget = false; private bool bombchuTurn = false; private float distNPC = 0f; private float expReductor = 0f; private Vector3 expForceDirection; private float detectionBubble = 20f; private float distanceToTarget = 0f; private float angleToTarget = 0f; private Vector3 vectorBombchuToTarget; private Creature nearestTarget; public float explosionRadius = 5f; public float expForceMultiplier = 50f; public float rotationSpeed = 0.2f;
protected void Awake()
{
item = this.GetComponent<Item>();
mesh = item.GetComponentInChildren<MeshRenderer>();
bombchuTransform = item.transform;
explosionEffect = item.GetComponentInChildren<ParticleSystem>();
explosionSFX = item.transform.Find("ExplosionSFX").GetComponent<AudioSource>();
startRunningSFX = item.transform.Find("StartRunningSFX").GetComponent<AudioSource>();
runningSFX = item.transform.Find("RunningSFX").GetComponent<AudioSource>();
item.OnCollisionEvent += OnBombchuCollisionEvent;
item.OnGrabEvent += OnBombchuGrabEvent;
item.OnTeleGrabEvent += OnBombchuTeleGrab;
item.OnUngrabEvent += OnBombchuUngrabEvent;
foreach (Collider col in item.GetComponentsInChildren<Collider>())
{
col.material.frictionCombine = 0f;
col.material.dynamicFriction = 0f;
col.material.staticFriction = 0f;
}
}
void OnBombchuCollisionEvent(ref CollisionStruct collisionInstance)
{
if (collisionInstance.targetType == CollisionStruct.TargetType.NPC && isBombchuActive)
{
Explode(explosionRadius);
item.enabled = false;
mesh.enabled = false;
hasExploded = true;
}
if (isBombchuActive && !bombchuRunning)
{
bombchuRunning = true;
startRunningSFX.Play();
}
}
void OnBombchuTeleGrab(Handle handle, Telekinesis teleGrabber)
{
DeactivateBombchu();
}
void OnBombchuGrabEvent(Handle handle, Interactor interactor)
{
DeactivateBombchu();
}
void OnBombchuUngrabEvent(Handle handle, Interactor interactor, bool thrown)
{
isBombchuActive = true;
}
void FixedUpdate()
{
if (bombchuRunning)
{
BombchuRunning();
}
if (hasExploded)
{
timerBombchu += Time.deltaTime;
}
if (timerBombchu > timeOut)
{
item.Despawn();
}
}
void DeactivateBombchu()
{
bombchuRunning = false;
isBombchuActive = false;
runningSFX.Stop();
RemoveTarget();
}
void Explode(float radius)
{
ExplosionEffect();
foreach (Creature npc in Creature.List)
{
if (npc != Player)
{
distNPC = Vector3.Distance(npc.gameObject.transform.position, bombchuTransform.position);
if (distNPC < radius)
{
expReductor = (radius - distNPC) / radius;
expForceDirection = npc.gameObject.transform.position - bombchuTransform.position;
expForceDirection.Normalize();
expForceDirection += Vector3.up;
expForceDirection.Normalize();
if (npc.state != Creature.State.Dead)
{
npc.ragdoll.SetState(BS.Ragdoll.State.Fallen);
}
foreach (RagdollPart ragdollPart in npc.ragdoll.parts)
{
ragdollPart.rb.AddForce(expForceDirection * expForceMultiplier * expReductor, ForceMode.Impulse);
}
npc.health.Kill();
}
}
}
}
void BombchuRunning()
{
item.rb.AddForce(bombchuTransform.forward * 10f, ForceMode.Force);
if (!startRunningSFX.isPlaying && !runningSFX.isPlaying && !hasExploded)
{
runningSFX.Play();
}
if (!hasTarget)
{
SetTarget();
}
if (hasTarget && (targetTransform != null))
{
distanceToTarget = Vector3.Distance(bombchuTransform.position, targetTransform.position);
if (distanceToTarget <= detectionBubble)
{
bombchuTurn = true;
}
else
{
bombchuTurn = false;
RemoveTarget();
}
}
if (bombchuTurn)
{
Turn();
}
}
void ExplosionEffect()
{
runningSFX.Stop();
explosionEffect.Play();
explosionSFX.Play();
}
void SetTarget()
{
foreach (Creature target in Creature.List)
{
if (target != Player)
{
if (target.state != Creature.State.Dead)
{
if (Vector3.Distance(bombchuTransform.position, target.transform.position) < detectionBubble)
{
vectorBombchuToTarget = target.transform.position - bombchuTransform.position;
vectorBombchuToTarget.y = 0f;
angleToTarget = Vector3.Angle(bombchuTransform.forward, vectorBombchuToTarget);
if (angleToTarget < 90f)
{
nearestTarget = target;
}
}
}
}
}
if (nearestTarget != null)
{
targetTransform = nearestTarget.transform;
hasTarget = true;
}
}
void RemoveTarget()
{
targetTransform = null;
nearestTarget = null;
hasTarget = false;
angleToTarget = 0f;
bombchuTurn = false;
}
void Turn()
{
vectorBombchuToTarget = targetTransform.position - bombchuTransform.position;
vectorBombchuToTarget.y = 0f;
angleToTarget = Vector3.SignedAngle(bombchuTransform.forward, vectorBombchuToTarget, bombchuTransform.up);
if (angleToTarget > 3f)
{
item.transform.Rotate(bombchuTransform.up, rotationSpeed);
}
else if (angleToTarget < -3f)
{
item.transform.Rotate(bombchuTransform.up, -1 * rotationSpeed);
}
}
}
还没有人评论,去客户端里说两句吧。
评论在新手盒子客户端中发表,这里同步展示。