using UnityEngine; using System.Collections; public class Bullet : MapObject { public int id; public string path; public float damage; public float speed = 0; public float speedAcc = 40f; public float maxSpeed = 20f; protected float startTime; protected ITarget target; protected Power power; protected Vector3 lastTargetPosition; public Transform shotTrans; public virtual void Init(Map map, Vector3 position, ITarget target, Power power) { this.map = map; this.target = target; this.power = power; this.transform.position = position; InitRotation(); } public virtual void Reset() { startTime = GameTime.time; BulletSettings settings = GetComponent(); if(settings != null) { speed = settings.speed; speedAcc = settings.speedAcc; maxSpeed = settings.maxSpeed; } } public IPowerOwner GetOwner() { return power.GetOwner(); } public Power GetPower() { return power; } public virtual void InitRotation() { if(target == null) return; Vector3 targetPos = target.position; float theta = NumberUtil.getRadianByATan(this.transform.position.x, this.transform.position.z, targetPos.x, targetPos.z); //updatae rotation float rotateAngle = -NumberUtil.radianToAngle(theta); Vector3 eulerAngles = transform.eulerAngles; eulerAngles.y = rotateAngle; transform.eulerAngles = eulerAngles; } // Update is called once per frame public virtual void Update () { if(target != null && !target.IsDead()) { lastTargetPosition = target.position; } if(lastTargetPosition == Vector3.zero) Remove(); float theta = NumberUtil.getRadianByATan(lastTargetPosition.x, lastTargetPosition.z, this.transform.position.x, this.transform.position.z); //updatae rotation float rotateAngle = -NumberUtil.radianToAngle(theta); Vector3 eulerAngles = transform.eulerAngles; eulerAngles.y = rotateAngle; transform.eulerAngles = eulerAngles; //update position speed += speedAcc*GameTime.deltaTime; if(speed > maxSpeed) { speed = maxSpeed; } float movDistance = Mathf.Abs(speed)*GameTime.deltaTime; float distance = 0; distance = NumberUtil.distanceVector2(new Vector2(transform.position.x, transform.position.z), new Vector2(lastTargetPosition.x, lastTargetPosition.z)); if(distance < movDistance) { MakeDamage(); } else { float movX = movDistance*Mathf.Cos(theta); float movY = movDistance*Mathf.Sin(theta); Vector3 position = transform.position; position.x += movX; position.z += movY; transform.position = position; } } protected virtual void MakeDamage() { DoDamage(target); Remove(); } protected virtual void DoDamage(ITarget target) { if(target == null || target.IsDead()) { return; } if(power.GetPowerEffect() == Power.PowerEffect.Damage) target.MakeDamage(this); else target.MakeHeal(this); if(!StringUtil.Empty(power.GetHitEffect())) { GameObject hitEffect = EffectUtil.CreateEffect(power.GetHitEffect()); if(hitEffect != null) { hitEffect.SetActive(false); HitEffectSettings settings = hitEffect.GetComponent(); if(settings == null) { Vector3 heartPos = target.heartPos; heartPos.x += Random.Range(-0.5f, 0.5f); heartPos.z += Random.Range(-0.5f, 0.5f); hitEffect.transform.position = target.heartPos; hitEffect.SetActive(true); } else { if(settings.isLocal) { GameObject targetObj = (target as Component).gameObject; hitEffect.transform.SetParent(targetObj.transform); hitEffect.transform.localPosition = settings.originPos; hitEffect.transform.eulerAngles = Vector3.zero; } hitEffect.SetActive(true); } } power.PlayHitSound(); } if(power.GetBuff() > 0) BuffManager.GetInstance().AddBuff(power.GetBuff(), target as BattleObject, power.GetOwner() as BattleObject); } public override void Remove () { BulletFactory.Recycle(path, this.gameObject); } public override string ToString () { return string.Format ("[Bullet] "+power.ToString()); } }