399 lines
10 KiB
C#
399 lines
10 KiB
C#
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BF
|
|
{
|
|
public class BattleControlBullet : MonoBehaviour
|
|
{
|
|
protected BattleControlUnit admin;
|
|
protected int bulletType = 0;
|
|
protected int bulletFinishType = 0;
|
|
protected int bulletOriginType = 0;
|
|
protected int searchType = 0;
|
|
protected float radius = 0.0f;
|
|
protected float duration = 0.0f;
|
|
protected float width = 0.0f;
|
|
protected float height = 0.0f;
|
|
protected float speed = 0.0f;
|
|
protected float offsetX = 0.0f;
|
|
protected float offsetZ = 0.0f;
|
|
protected float checkInterval = 0.0f;
|
|
protected float checkDuration = 0.0f;
|
|
protected int skillId = 0;
|
|
protected int cloneIndex = 0;
|
|
protected int skillEffectIndex = 0;
|
|
protected Vector3 offset = Vector3.zero;
|
|
protected Vector3 targetPosition = Vector3.zero;
|
|
protected BattleControlUnit targetUnit;
|
|
protected HashSet<int> CheckTargetDict = new HashSet<int>();
|
|
protected List<GameObject> CheckTargetList = new List<GameObject>();
|
|
protected List<BattleContinuousTarget> ContinuousTargetsList = new List<BattleContinuousTarget>();
|
|
[System.NonSerialized]
|
|
public float CacheX = 0.0f;
|
|
[System.NonSerialized]
|
|
public float CacheY = 0.0f;
|
|
[System.NonSerialized]
|
|
public float CacheZ = 0.0f;
|
|
[System.NonSerialized]
|
|
public bool IsRecycle = false;
|
|
private bool endWithTime = false;
|
|
private bool endWithArrive = false;
|
|
private bool waitNextFixedFrame = false;
|
|
private bool nextFixedFrameTakeEffect = false;
|
|
private bool isOver = false;
|
|
private bool lockTarget = false;
|
|
private int fxId = 0;
|
|
private float fxDelayTime = 0.0f;
|
|
private bool checkFx = false;
|
|
public virtual void SetColliderEnabled(bool enabled) {}
|
|
public virtual void Recycle() {}
|
|
public virtual void SetupBoxCollisionBody(float collisionWidth, float collisionHeight) {}
|
|
public virtual void SetupSphereCollisionBody(float collisionRadius) {}
|
|
public void SetAdmin(BattleControlUnit unit)
|
|
{
|
|
admin = unit;
|
|
if (admin.Side == 1)
|
|
{
|
|
gameObject.layer = BattleConst.LAYER_ATK_BULLET;
|
|
}
|
|
else
|
|
{
|
|
gameObject.layer = BattleConst.LAYER_DEF_BULLET;
|
|
}
|
|
}
|
|
|
|
public void CachePosition()
|
|
{
|
|
var position = transform.position;
|
|
CacheX = position.x;
|
|
CacheY = position.y;
|
|
CacheZ = position.z;
|
|
}
|
|
|
|
public void CacheTargetPosition()
|
|
{
|
|
CacheX = targetPosition.x;
|
|
CacheZ = targetPosition.z;
|
|
}
|
|
|
|
public void InitSphereBullet(int skillId, int cloneIndex, int skillEffectIndex, int bulletType, int bulletFinishType, int bulletOriginType, int searchType, float radius, float duration, float speed, float offsetX, float offsetZ)
|
|
{
|
|
this.skillId = skillId;
|
|
this.cloneIndex = cloneIndex;
|
|
this.skillEffectIndex = skillEffectIndex;
|
|
this.bulletType = bulletType;
|
|
this.bulletFinishType = bulletFinishType;
|
|
this.bulletOriginType = bulletOriginType;
|
|
this.searchType = searchType;
|
|
this.radius = radius;
|
|
this.duration = duration;
|
|
this.speed = speed;
|
|
this.offsetX = offsetX;
|
|
this.offsetZ = offsetZ;
|
|
offset = new Vector3(offsetX, 0.0f, offsetZ);
|
|
if (bulletFinishType == 1) // 飞到目标点才算完成,此时有速度和时间互斥
|
|
{
|
|
if (speed < 0.000001f)
|
|
{
|
|
endWithTime = true;
|
|
endWithArrive = false;
|
|
}
|
|
else
|
|
{
|
|
endWithTime = false;
|
|
endWithArrive = true;
|
|
}
|
|
}
|
|
else // 按时间算结束
|
|
{
|
|
endWithTime = true;
|
|
endWithArrive = false;
|
|
}
|
|
SetupSphereCollisionBody(radius);
|
|
InitBase();
|
|
StartSearch();
|
|
}
|
|
|
|
public void InitBoxBullet(int skillId, int cloneIndex, int skillEffectIndex, int bulletType, int bulletFinishType, int bulletOriginType, int searchType, float w, float h, float duration, float speed, float offsetX, float offsetZ)
|
|
{
|
|
this.skillId = skillId;
|
|
this.skillEffectIndex = skillEffectIndex;
|
|
this.bulletType = bulletType;
|
|
this.bulletFinishType = bulletFinishType;
|
|
this.bulletOriginType = bulletOriginType;
|
|
this.searchType = searchType;
|
|
this.width = w;
|
|
this.height = h;
|
|
this.duration = duration;
|
|
this.speed = speed;
|
|
this.offsetX = offsetX;
|
|
this.offsetZ = offsetZ;
|
|
offset = new Vector3(offsetX, 0.0f, offsetZ);
|
|
if (bulletFinishType == 1) // 飞到目标点才算完成,此时有速度和时间互斥
|
|
{
|
|
if (speed < 0.000001f)
|
|
{
|
|
endWithTime = true;
|
|
endWithArrive = false;
|
|
}
|
|
else
|
|
{
|
|
endWithTime = false;
|
|
endWithArrive = true;
|
|
}
|
|
}
|
|
else // 按时间算结束
|
|
{
|
|
endWithTime = true;
|
|
endWithArrive = false;
|
|
}
|
|
SetupBoxCollisionBody(w, h);
|
|
InitBase();
|
|
StartSearch();
|
|
}
|
|
|
|
private void InitBase()
|
|
{
|
|
CheckTargetDict.Clear();
|
|
CheckTargetList.Clear();
|
|
ContinuousTargetsList.Clear();
|
|
waitNextFixedFrame = false;
|
|
nextFixedFrameTakeEffect = false;
|
|
isOver = false;
|
|
targetUnit = null;
|
|
lockTarget = false;
|
|
checkFx = false;
|
|
}
|
|
|
|
private void StartSearch()
|
|
{
|
|
if (bulletOriginType == 2)
|
|
{
|
|
transform.position = admin.transform.position;
|
|
}
|
|
else
|
|
{
|
|
if (!ReferenceEquals(admin.Target, null))
|
|
{
|
|
transform.position = admin.Target.transform.position;
|
|
}
|
|
}
|
|
switch (searchType)
|
|
{
|
|
case 1: // 以目标为目标点
|
|
SearchWithTarget();
|
|
break;
|
|
case 2: // 以自身为目标点
|
|
SearchWitchSelf();
|
|
break;
|
|
case 3: // 以目标为目标
|
|
lockTarget = true;
|
|
targetUnit = admin.Target;
|
|
targetPosition = targetUnit.transform.position;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (endWithTime && speed < 0.000001f)
|
|
{
|
|
speed = (targetPosition - transform.position).magnitude / duration;
|
|
}
|
|
if (bulletType == 1) // 立即开始检测碰撞
|
|
{
|
|
SetColliderEnabled(true);
|
|
}
|
|
}
|
|
|
|
private void SearchWithTarget()
|
|
{
|
|
if (admin.Direction == 1)
|
|
{
|
|
targetPosition = admin.Target.transform.position + new Vector3(offsetX, 0.0f, offsetZ);
|
|
}
|
|
else
|
|
{
|
|
targetPosition = admin.Target.transform.position + new Vector3(-offsetX, 0.0f, offsetZ);
|
|
}
|
|
}
|
|
|
|
private void SearchWitchSelf()
|
|
{
|
|
if (admin.Direction == 1)
|
|
{
|
|
targetPosition = admin.transform.position + new Vector3(offsetX, 0.0f, offsetZ);
|
|
}
|
|
else
|
|
{
|
|
targetPosition = admin.transform.position + new Vector3(-offsetX, 0.0f, offsetZ);
|
|
}
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
var id = other.gameObject.GetInstanceID();
|
|
if (!CheckTargetDict.TryAdd(id))
|
|
{
|
|
return;
|
|
}
|
|
admin.OnHitTarget(other.gameObject, skillId, cloneIndex, skillEffectIndex);
|
|
CheckTargetList.Add(other.gameObject);
|
|
if (checkInterval > 0.000001f) // 持续型范围技能,进入范围的时候立即生效一次
|
|
{
|
|
var target = BF.BFMain.Instance.BattleMgr.PoolHelper.GetContinuousTarge();
|
|
target.Unit = other.gameObject;
|
|
target.Time = checkInterval;
|
|
ContinuousTargetsList.Add(target);
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
var gameObject = other.gameObject;
|
|
var id = gameObject.GetInstanceID();
|
|
if (CheckTargetDict.Contains(id))
|
|
{
|
|
CheckTargetList.Remove(gameObject);
|
|
if (checkInterval > 0.000001f) // 持续型范围技能,进入范围的时候立即生效一次
|
|
{
|
|
var count = ContinuousTargetsList.Count;
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
if (gameObject == ContinuousTargetsList[i].Unit)
|
|
{
|
|
ContinuousTargetsList.RemoveAt(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public int GetSearchTargetsCount()
|
|
{
|
|
return CheckTargetList.Count;
|
|
}
|
|
|
|
public int GetTargetId(int index)
|
|
{
|
|
if (index >= 0 && index < CheckTargetList.Count)
|
|
{
|
|
return CheckTargetList[index].GetInstanceID();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (checkFx)
|
|
{
|
|
fxDelayTime -= Time.deltaTime*BattleConfigure.TimeScale;
|
|
if (fxDelayTime < 0.0f)
|
|
{
|
|
checkFx = false;
|
|
BF.BFMain.Instance.BattleMgr.PlayFx(fxId, admin.Direction, transform.position.x, transform.position.z);
|
|
}
|
|
}
|
|
|
|
if (endWithTime) // 按时间结束
|
|
{
|
|
duration -= Time.deltaTime*BattleConfigure.TimeScale;
|
|
if (duration < 0.0f)
|
|
{
|
|
if (bulletType == 1)
|
|
{
|
|
Recycle();
|
|
}
|
|
else if(bulletType == 2)
|
|
{
|
|
if (waitNextFixedFrame)
|
|
{
|
|
if (nextFixedFrameTakeEffect)
|
|
{
|
|
Recycle();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
waitNextFixedFrame = true;
|
|
SetColliderEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // 按飞行速度到达目标点后结束
|
|
{
|
|
if (!isOver)
|
|
{
|
|
if ((transform.position - targetPosition).sqrMagnitude < 0.0001f)
|
|
{
|
|
isOver = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (bulletType == 1)
|
|
{
|
|
Recycle();
|
|
}
|
|
else if(bulletType == 2)
|
|
{
|
|
if (waitNextFixedFrame)
|
|
{
|
|
if (nextFixedFrameTakeEffect)
|
|
{
|
|
Recycle();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
waitNextFixedFrame = true;
|
|
SetColliderEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (waitNextFixedFrame)
|
|
{
|
|
nextFixedFrameTakeEffect = true;
|
|
}
|
|
Vector3 moveToPosition;
|
|
if (lockTarget)
|
|
{
|
|
targetPosition = admin.Target.transform.position;
|
|
moveToPosition = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.fixedDeltaTime * BattleConfigure.TimeScale);
|
|
}
|
|
else
|
|
{
|
|
moveToPosition = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.fixedDeltaTime * BattleConfigure.TimeScale);
|
|
}
|
|
if (moveToPosition.x < BattleConfigure.SceneMinX) // 撞左边墙了
|
|
{
|
|
moveToPosition.x = BattleConfigure.SceneMinX;
|
|
}
|
|
else if (moveToPosition.x > BattleConfigure.SceneMaxX) // 撞右边墙了
|
|
{
|
|
moveToPosition.x = BattleConfigure.SceneMaxX;
|
|
}
|
|
if (moveToPosition.z < BattleConfigure.SceneMinZ) // 撞下面墙了
|
|
{
|
|
moveToPosition.z = BattleConfigure.SceneMinZ;
|
|
}
|
|
else if (moveToPosition.z > BattleConfigure.SceneMaxZ) // 撞上面墙了
|
|
{
|
|
moveToPosition.z = BattleConfigure.SceneMaxZ;
|
|
}
|
|
transform.position = moveToPosition;
|
|
}
|
|
|
|
public void PlayTargetPointFx(int id, float delay)
|
|
{
|
|
checkFx = true;
|
|
fxId = id;
|
|
fxDelayTime = delay;
|
|
}
|
|
}
|
|
} |