///// <summary> ///// 将指定位置设置为可见 ///// </summary> ///// <param name="fieldData">视野</param> //public static void SetVisibleAtPosition(FOWFieldData fieldData) //{ // if (!Instance) // return; // if (!Instance.m_IsInitialized) // return; // if (fieldData == null) // return; // Instance.m_Map.SetVisible(fieldData); //} public static void UpdateFOWFieldData(FOWFieldData data) { if (!Instance) { return; } if (!Instance.m_IsInitialized) { return; } if (Instance.m_FieldDatas == null) { Instance.m_FieldDatas = new List <FOWFieldData>(); } if (!Instance.m_FieldDatas.Contains(data)) { Instance.m_FieldDatas.Add(data); } if (!Instance.m_IsFieldDatasUpdated) { //lock (Instance.m_FieldDatas) { Instance.m_Map.SetVisible(Instance.m_FieldDatas); Instance.m_IsFieldDatasUpdated = true; } } }
public override void Calculate(FOWFieldData field, FOWMap map) { Vector3 worldPosition = field.position; int rx = (int)(field.radius / map.deltaX); int rz = (int)(field.radius / map.deltaZ); float rs = rx * rx; int x = Mathf.FloorToInt((worldPosition.x - map.beginPosition.x) / map.deltaX); int z = Mathf.FloorToInt((worldPosition.z - map.beginPosition.z) / map.deltaZ); int beginx = Mathf.Max(0, x - rx); int beginy = Mathf.Max(0, z - rz); int endx = Mathf.Min(map.texWidth, x + rx); int endy = Mathf.Min(map.texHeight, z + rz); for (int i = beginx; i < endx; i++) { for (int j = beginy; j < endy; j++) { int dx = i - x; int dy = j - z; float rads = dx * dx + dy * dy; if (rads <= rs) { map.maskTexture.SetAsVisible(i, j); } } } }
void Start() { if (!isLocalPlayer) { return; } m_FieldData = new FOWFieldData(transform.position, radius); }
void OnDestroy() { if (m_FieldData != null) { FogOfWarEffect.ReleaseFOWFieldData(m_FieldData); } m_FieldData = null; }
public void Calculate(FOWFieldData field, FOWMap map) { if (map.mapData.isPregeneration) { UsePregenerationDataCalculate(field, map); } else { RealtimeCalculate(field, map); } }
void OnDestroy() { if (!isLocalPlayer) { return; } if (m_FieldData != null) { FogOfWarEffect.ReleaseFOWFieldData(m_FieldData); } m_FieldData = null; }
public sealed override void Calculate(FOWFieldData field, FOWMap map) { Vector3 worldPosition = field.position; float radiusSq = field.radiusSquare; int x = Mathf.FloorToInt((worldPosition.x - map.beginPosition.x) / map.deltaX); int z = Mathf.FloorToInt((worldPosition.z - map.beginPosition.z) / map.deltaZ); if (x < 0 || x >= map.texWidth) { return; } if (z < 0 || z >= map.texHeight) { return; } if (map.mapData[x, z] != 0) { return; } m_Queue.Clear(); m_Arrives.Clear(); m_Queue.Enqueue(new FOWMapPos(x, z)); m_Arrives.Add(z * map.texWidth + x); map.maskTexture.SetAsVisible(x, z); while (m_Queue.Count > 0) { var root = m_Queue.Dequeue(); if (map.mapData[root.x, root.y] != 0) { if (PreRayCast(map, root, x, z)) { int index = root.y * map.texWidth + root.x; if (!m_Arrives.Contains(index)) { m_Arrives.Add(index); } map.maskTexture.SetAsVisible(root.x, root.y); } else { RayCast(map, root, x, z, field); } continue; } SetVisibleAtPosition(map, root.x - 1, root.y, x, z, radiusSq); SetVisibleAtPosition(map, root.x, root.y - 1, x, z, radiusSq); SetVisibleAtPosition(map, root.x + 1, root.y, x, z, radiusSq); SetVisibleAtPosition(map, root.x, root.y + 1, x, z, radiusSq); } }
public static void ReleaseFOWFieldData(FOWFieldData data) { if (!instance) { return; } if (!instance.m_IsInitialized) { return; } //lock (instance.m_FieldDatas) { if (instance.m_FieldDatas != null && instance.m_FieldDatas.Contains(data)) { instance.m_FieldDatas.Remove(data); } } }
public abstract void Calculate(FOWFieldData field, FOWMap map);
/// <summary> /// TODO:使用预生成FOV数据计算(暂未实现) /// </summary> /// <param name="field"></param> /// <param name="map"></param> private void UsePregenerationDataCalculate(FOWFieldData field, FOWMap map) { }
/// <summary> /// 实时计算 /// </summary> /// <param name="field"></param> /// <param name="map"></param> protected abstract void RealtimeCalculate(FOWFieldData field, FOWMap map);
protected override void RayCast(FOWMap map, FOWMapPos pos, int centX, int centZ, FOWFieldData field) { int x = pos.x - centX; int z = pos.y - centZ; float corner1x, corner1z, corner2x, corner2z; GetCornersPos(x, z, out corner1x, out corner1z, out corner2x, out corner2z); RaycastLine(map, pos, centX, centZ, corner1x, corner1z, field); RaycastLine(map, pos, centX, centZ, corner2x, corner2z, field); }
void Start() { m_FieldData = new FOWFieldData(transform.position, radius); }
protected override void RayCast(FOWMap map, FOWMapPos pos, int centX, int centZ, FOWFieldData field) { float radiusSq = field.radiusSquare; int x = pos.x - centX; int z = pos.y - centZ; m_SortAngle[0] = Mathf.Atan2((z * map.deltaZ + map.deltaZ / 2), (x * map.deltaX - map.deltaX / 2)) * Mathf.Rad2Deg; m_SortAngle[1] = Mathf.Atan2((z * map.deltaZ - map.deltaZ / 2), (x * map.deltaX - map.deltaX / 2)) * Mathf.Rad2Deg; m_SortAngle[2] = Mathf.Atan2((z * map.deltaZ + map.deltaZ / 2), (x * map.deltaX + map.deltaX / 2)) * Mathf.Rad2Deg; m_SortAngle[3] = Mathf.Atan2((z * map.deltaZ - map.deltaZ / 2), (x * map.deltaX + map.deltaX / 2)) * Mathf.Rad2Deg; float curAngle = Mathf.Atan2((z * map.deltaZ), (x * map.deltaX)) * Mathf.Rad2Deg; SortAngle(); m_RayCastQueue.Clear(); m_RayCastQueue.Enqueue(pos); int index = pos.y * map.texWidth + pos.x; m_Arrives.Add(index); while (m_RayCastQueue.Count > 0) { FOWMapPos root = m_RayCastQueue.Dequeue(); if (root.x - 1 >= 0 && (curAngle >= 90 || curAngle < -90)) { SetInvisibleAtPosition(map, root.x - 1, root.y, centX, centZ, radiusSq); } if (root.x - 1 >= 0 && root.y - 1 >= 0 && curAngle <= -90 && curAngle >= -180) { SetInvisibleAtPosition(map, root.x - 1, root.y - 1, centX, centZ, radiusSq); } if (root.y - 1 >= 0 && curAngle <= 0 && curAngle >= -180) { SetInvisibleAtPosition(map, root.x, root.y - 1, centX, centZ, radiusSq); } if (root.x + 1 < map.texWidth && root.y - 1 >= 0 && curAngle <= 0 && curAngle >= -90) { SetInvisibleAtPosition(map, root.x + 1, root.y - 1, centX, centZ, radiusSq); } if (root.x + 1 < map.texWidth && curAngle >= -90 && curAngle <= 90) { SetInvisibleAtPosition(map, root.x + 1, root.y, centX, centZ, radiusSq); } if (root.x + 1 < map.texWidth && root.y + 1 < map.texHeight && curAngle >= 0 && curAngle <= 90) { SetInvisibleAtPosition(map, root.x + 1, root.y + 1, centX, centZ, radiusSq); } if (root.y + 1 < map.texHeight && curAngle >= 0 && curAngle <= 180) { SetInvisibleAtPosition(map, root.x, root.y + 1, centX, centZ, radiusSq); } if (root.x - 1 >= 0 && root.y + 1 < map.texHeight && curAngle >= 90 && curAngle <= 180) { SetInvisibleAtPosition(map, root.x - 1, root.y + 1, centX, centZ, radiusSq); } } }
protected abstract void RayCast(FOWMap map, FOWMapPos pos, int centX, int centZ, FOWFieldData field);
private void RaycastLine(FOWMap map, FOWMapPos pos, int centX, int centZ, float px, float pz, FOWFieldData field) { Vector2 dir = new Vector2(px, pz) * 10; int x = centX + (int)dir.x; int y = centZ + (int)dir.y; SetInvisibleLine(map, pos.x, pos.y, x, y, centX, centZ, field.radiusSquare); }
protected override void RayCast(FOWMap map, FOWMapPos pos, int centX, int centZ, FOWFieldData field) { float r = field.radius * map.invDeltaX; Vector2 dir = new Vector2(pos.x - centX, pos.y - centZ); float l = dir.magnitude; if (r - l <= 0) { return; } dir = dir.normalized * (r - l); int x = pos.x + (int)dir.x; int y = pos.y + (int)dir.y; SetInvisibleLine(map, pos.x, pos.y, x, y, centX, centZ, field.radiusSquare); }
void OnEnable() { m_FieldData = new FOWFieldData(transform.position, radius); first_time = false; }