c1_unity/Assets/Scripts/Component/Battle/BattleControlCollider.cs
2023-04-03 11:04:31 +08:00

488 lines
11 KiB
C#

using UnityEngine;
using System.Collections.Generic;
namespace BF
{
public class BattleContinuousTarget
{
public GameObject Unit;
public float Time;
}
public class BattleControlCollider : MonoBehaviour
{
protected BattleControlUnit admin;
public int uniqueId = 0;
protected bool isActive = false;
protected int checkType = 0;
protected float checkInterval = 0.0f;
protected float checkDuration = 0.0f;
protected int skillId = 0;
protected int cloneIndex = 0;
protected int skillEffectIndex = 0;
protected bool unlimitCount = false;
protected float delayAimTime = 0.0f;
protected float aimFollowTime = 0.0f;
protected float aimFollowSpeed = 0.0f;
protected bool aimFollow = false;
protected bool delayAim = false;
protected bool effectOver = false;
protected bool waitRecycle = false;
protected Vector3 offset = Vector3.zero;
protected Vector3 targetPosition = Vector3.zero;
protected BattleControlUnit lockTarget;
protected bool isLockTarget = false;
protected HashSet<int> CheckTargetDict = new HashSet<int>();
protected List<GameObject> CheckTargetList = new List<GameObject>();
protected bool IsSearchByCollider = false;
protected List<BattleContinuousTarget> ContinuousTargetsList = new List<BattleContinuousTarget>();
protected BattleControlColliderContainer container;
private bool updatePositionWithLockTarget = false;
[System.NonSerialized]
public float CacheX = 0.0f;
[System.NonSerialized]
public float CacheY = 0.0f;
[System.NonSerialized]
public float CacheZ = 0.0f;
[System.NonSerialized]
private static Vector2 Vector2A = Vector2.zero;
private static Vector2 Vector2B = Vector2.zero;
[System.NonSerialized]
public bool IsRecycle = false;
public virtual void SetColliderEnabled(bool enabled) {}
public virtual void Recycle() {}
public void SetContainer(BattleControlColliderContainer container)
{
this.container = container;
}
public void RemoveFromContainer()
{
this.container = null;
}
public void SetIsSearchByCollider(bool isSearchByCollider)
{
IsSearchByCollider = isSearchByCollider;
}
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 int GetUniqueId()
{
return uniqueId;
}
public void SetTargetPosition(Vector3 position)
{
targetPosition = position;
}
public void SetLockTarget(BattleControlUnit unit)
{
lockTarget = unit;
isLockTarget = true;
}
public void SetUpdatePositionWithLockTarget(bool updatePositionWithLockTarget)
{
this.updatePositionWithLockTarget = updatePositionWithLockTarget;
}
public void InitPosition(float x, float y, float z)
{
if (admin.Direction == 1)
{
transform.position = new Vector3(x, y, z) + offset;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
transform.position = new Vector3(x, y, z) - offset;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
private void MoveToLockTargetPosition(float deltaTime)
{
if (admin.Direction == 1)
{
var position = lockTarget.transform.position + offset;
var moveToPosition = Vector3.MoveTowards(transform.position, position, aimFollowSpeed * deltaTime);
transform.position = moveToPosition;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
var position = lockTarget.transform.position - offset;
var moveToPosition = Vector3.MoveTowards(transform.position, position, aimFollowSpeed * deltaTime);
transform.position = moveToPosition;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
private void MoveToTargetPosition(float deltaTime)
{
if (admin.Direction == 1)
{
var position = targetPosition + offset;
var moveToPosition = Vector3.MoveTowards(transform.position, position, aimFollowSpeed * deltaTime);
transform.position = moveToPosition;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
var position = targetPosition - offset;
var moveToPosition = Vector3.MoveTowards(transform.position, position, aimFollowSpeed * deltaTime);
transform.position = moveToPosition;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
private void UpdatePositionByTargetPosition()
{
if (admin.Direction == 1)
{
transform.position = targetPosition + offset;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
transform.position = targetPosition - offset;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
private void UpdatePositionByLockTargetPosition()
{
if (admin.Direction == 1)
{
transform.position = lockTarget.transform.position + offset;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
transform.position = lockTarget.transform.position - offset;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
private void UpdatePositionByAdminPosition()
{
if (admin.Direction == 1)
{
transform.position = admin.transform.position + offset;
transform.localEulerAngles = new Vector3(0.0f, 0.0f, 0.0f);
}
else
{
transform.position = admin.transform.position - offset;
transform.localEulerAngles = new Vector3(0.0f, 180.0f, 0.0f);
}
}
public void CachePosition()
{
var position = transform.position;
CacheX = position.x;
CacheY = position.y;
CacheZ = position.z;
}
private void FollowTarget(float deltaTime)
{
if (isLockTarget)
{
MoveToLockTargetPosition(deltaTime);
}
else
{
MoveToTargetPosition(deltaTime);
}
}
public void InitBase()
{
CheckTargetDict.Clear();
CheckTargetList.Clear();
ContinuousTargetsList.Clear();
effectOver = false;
waitRecycle = false;
lockTarget = null;
isLockTarget = false;
updatePositionWithLockTarget = false;
}
public void Search(int checkType, float interval, float duration, int skillId, int cloneIndex, int skillEffectIndex, bool unlimitCount, float delayAimTime, float aimFollowTime, float aimFollowSpeed, bool disposable)
{
this.checkType = checkType;
this.checkInterval = interval;
this.checkDuration = duration;
this.skillId = skillId;
this.cloneIndex = cloneIndex;
this.skillEffectIndex = skillEffectIndex;
this.unlimitCount = unlimitCount;
this.delayAimTime = delayAimTime;
this.aimFollowTime = aimFollowTime;
this.aimFollowSpeed = aimFollowSpeed;
if (aimFollowTime > 0.0f)
{
aimFollow = true;
}
else
{
aimFollow = false;
}
if (isLockTarget)
{
UpdatePositionByLockTargetPosition();
}
else
{
UpdatePositionByTargetPosition();
}
if (disposable)
{
delayAim = false;
StartSearch();
}
else
{
if (delayAimTime > 0.0f) // 延迟
{
delayAim = true;
}
else // 立即
{
delayAim = false;
}
}
}
public void StartSearch()
{
if (IsSearchByCollider)
{
isActive = true;
effectOver = false;
waitRecycle = false;
SetColliderEnabled(true);
}
}
private void OnTriggerEnter(Collider other)
{
var id = other.gameObject.GetInstanceID();
if (!CheckTargetDict.TryAdd(id))
{
return;
}
CheckTargetList.Add(other.gameObject);
if (checkInterval > 0.000001f) // 持续型范围技能,进入范围的时候立即生效一次
{
admin.OnHitTarget(other.gameObject, skillId, cloneIndex, skillEffectIndex);
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 void AddCheckTargetList(GameObject gameObject)
{
CheckTargetList.Add(gameObject);
}
private void SearchNearestTarget()
{
var control = BF.BFMain.Instance.BattleMgr.GetNearestUnit(admin.Side);
if(ReferenceEquals(control, null))
{
Recycle();
return;
}
CheckTargetList.Add(control.gameObject);
}
private void SearchAllTargets()
{
var unitsList = BF.BFMain.Instance.BattleMgr.GetUnitsList(admin.Side);
for (int i = 0; i < unitsList.Count; i++)
{
CheckTargetList.Add(unitsList[i].gameObject);
}
}
protected void CheckCollider()
{
CheckSurroundingTargets();
}
private void CheckSurroundingTargets()
{
if (checkInterval <= 0.000001f)
{
if (effectOver)
{
if (waitRecycle)
{
if (!unlimitCount)
{
FindNearestAndHit();
}
else
{
HitTargets();
}
Recycle();
}
else
{
waitRecycle = true;
}
}
else
{
effectOver = true;
}
}
}
protected void FindNearestAndHit()
{
var count = CheckTargetList.Count;
if (count <= 0)
{
return;
}
GameObject unit = null;
var position = admin.transform.position;
Vector2A.Set(position.x, position.z);
float minDis = float.MaxValue;
for(int j = 0; j < count; j++)
{
var objB = CheckTargetList[j];
Vector2B.Set(objB.transform.position.x, objB.transform.position.z);
var dis = (Vector2B - Vector2A).sqrMagnitude;
if (dis < minDis)
{
minDis = dis;
unit = objB;
}
}
if (!ReferenceEquals(unit, null))
{
admin.OnHitTarget(unit, skillId, cloneIndex, skillEffectIndex);
}
}
private void HitTargets()
{
var count = CheckTargetList.Count;
if (count <= 0)
{
return;
}
for (int i = count - 1; i >= 0; i--)
{
admin.OnHitTarget(CheckTargetList[i], skillId, cloneIndex, skillEffectIndex);
}
}
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 (delayAim)
{
delayAimTime -= Time.deltaTime*BattleConfigure.TimeScale;
if (delayAimTime < 0.0f)
{
delayAim = false;
}
return;
}
if (aimFollow)
{
var deltaTime = Time.deltaTime*BattleConfigure.TimeScale;
aimFollowTime -= deltaTime;
if (aimFollowTime < 0.0f)
{
aimFollow = false;
}
FollowTarget(deltaTime);
}
if (!isActive)
{
return;
}
if (updatePositionWithLockTarget)
{
UpdatePositionByLockTargetPosition();
}
var count = ContinuousTargetsList.Count;
if (count <= 0)
{
return;
}
BattleContinuousTarget target = null;
var deltaTime2 = Time.deltaTime*BattleConfigure.TimeScale;
for (int i = count - 1; i >= 0; i--)
{
target = ContinuousTargetsList[i];
target.Time -= deltaTime2;
if (target.Time <= 0.0f)
{
target.Time = checkInterval;
admin.OnHitTarget(target.Unit, skillId, cloneIndex, skillEffectIndex);
}
}
}
}
}