private void MarkVisible( int x, int y, int byAgentIndex, SignalAgents signalAgents, ref int[] fogVisionTemporary, ref Color32[] fogColorTemporary, Color32[] fogColor) { fogVisionTemporary[x + y * width] = 0; fogColorTemporary[x + y * width] = LerpColor(fogColor[x + y * width]); signalAgents.LocationsSeenTemporary[byAgentIndex].Add(x + y * width); }
private void Awake() { _fog = new Texture2D(width, length, TextureFormat.ARGB32, false); for (int x = 0; x < width; x++) { for (int y = 0; y < length; y++) { _fog.SetPixel(x, y, hidden); } } _fog.Apply(); var miniMapObj = GameObject.Find("MiniMap"); if (miniMapObj) { map = miniMapObj.GetComponent <MiniMap>(); } if (map) { map.fogTexture = _fog; } terrainMat.SetTexture("_FOWTex", _fog); //fogState = new int[width*length]; fogHeight = new float[width * length]; for (int x = 0; x < width; x++) { for (int y = 0; y < length; y++) { RaycastHit hit; Physics.Raycast( new Vector3(x * disp + startPos.x, 1000, y * disp + startPos.z), Vector3.down, out hit, 10000, terrainLayer); fogHeight[x + y * width] = hit.point.y; } } var factions = GameManager.Instance.Factions.Length; _signalAgentsFactions = new SignalAgents[factions]; _hiddenAgentsFactions = new HiddenAgents[factions]; for (var factionIndex = 0; factionIndex < factions; factionIndex++) { _signalAgentsFactions[factionIndex] = new SignalAgents { FactionIndex = factionIndex }; _hiddenAgentsFactions[factionIndex] = new HiddenAgents { FactionIndex = factionIndex }; } }
// Bresenham's Line Algorithm at work for shadow casting private void Line( int x, int y, int x2, int y2, int radius, ref int[] fogVisionTemporary, ref Color32[] fogColorTemporary, Color32[] fogColor, float locY, float upwardSlopeHeight, float downwardSlopeHeight, int agentIndex, SignalAgents signalAgents) { int orPosX = x; int orPosY = y; int w = x2 - x; int h = y2 - y; int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; if (w < 0) { dx1 = -1; } else if (w > 0) { dx1 = 1; } if (h < 0) { dy1 = -1; } else if (h > 0) { dy1 = 1; } if (w < 0) { dx2 = -1; } else if (w > 0) { dx2 = 1; } int longest = Mathf.Abs(w); int shortest = Mathf.Abs(h); if (longest <= shortest) { longest = Mathf.Abs(h); shortest = Mathf.Abs(w); if (h < 0) { dy2 = -1; } else if (h > 0) { dy2 = 1; } dx2 = 0; } int numerator = longest >> 1; for (int i = 0; i <= longest; i++) { float dist = new Vector2(orPosX - x, orPosY - y).sqrMagnitude; if (x < width && x >= 0) { if (x + y * width > 0 && x + y * width < fogHeight.Length) { if (fogHeight[x + y * width] == -1) { MarkVisible( x, y, agentIndex, signalAgents, ref fogVisionTemporary, ref fogColorTemporary, fogColor); break; } if (dist >= radius * radius - 2) { break; } if (locY > fogHeight[x + y * width]) { if (locY - fogHeight[x + y * width] <= downwardSlopeHeight) { MarkVisible( x, y, agentIndex, signalAgents, ref fogVisionTemporary, ref fogColorTemporary, fogColor); } else { MarkVisible( x, y, agentIndex, signalAgents, ref fogVisionTemporary, ref fogColorTemporary, fogColor); break; } } else if (fogHeight[x + y * width] - locY <= upwardSlopeHeight) { MarkVisible( x, y, agentIndex, signalAgents, ref fogVisionTemporary, ref fogColorTemporary, fogColor); } else { MarkVisible( x, y, agentIndex, signalAgents, ref fogVisionTemporary, ref fogColorTemporary, fogColor); break; } } } numerator += shortest; if (numerator >= longest) { numerator -= longest; x += dx1; y += dy1; } else { x += dx2; y += dy2; } } }
/// <summary> /// Updates the hidden renderers based on their respective hideNextSetting. /// This triggers the visibility change events for signal agents. /// </summary> /// <param name="renderOnScreen"></param> /// <param name="fog"></param> /// <param name="signalAgents">Their LocationsSeenTemporary array will be used to check and trigger the /// visibility change event of the actor represented by the specific SignalAgent. This event will /// inform him of renderers that he sees. For the Attack Move purpose, this will be checked always.</param> public void SetRenderers(bool renderOnScreen, Fog fog, SignalAgents signalAgents) { for (int x = 0; x < hideAmount; x++) { var previousState = (VisionReceiver.VisionState)hideCurrentSetting[x]; var newState = (VisionReceiver.VisionState)hideNextSetting[x]; if (previousState != newState) { if (renderOnScreen) { hiddenRend[x].SetRenderer(newState); } hideCurrentSetting[x] = hideNextSetting[x]; } // Find all agents that saw the hidden agent or his change in state var signalIndexesSawHidden = new List <int>(); var location = fog.DetermineLocInteger(hiddenAgentT[x].position); if (signalAgents.LocationsSeenTemporary == null) { Log.w("Fog hidden agent cannot find locations of nearby signal agents"); return; } for (var signalIndex = 0; signalIndex < signalAgents.LocationsSeenTemporary.Length; signalIndex++) { try { var agentSeenPositions = signalAgents.LocationsSeenTemporary[signalIndex]; if (agentSeenPositions != null && agentSeenPositions.Contains(location)) { signalIndexesSawHidden.Add(signalIndex); } } catch (Exception e) { // This problem seems to be fixed as LocationsSeenTemporary[agentIndex] just wasn't initialized Log.w("LocationsSeenTemporary problem: " + e.Message); } } // Conversion to Lists of GameObjects and Actors var signalAgentsSawHidden = new List <GameObject>(); signalIndexesSawHidden.ForEach(signalIndex => { // For an unknown reason, sometimes the index would try to get accessed above the agent count if (signalIndex < signalAgents.agents.Count) { signalAgentsSawHidden.Add(signalAgents.agents[signalIndex]); } }); var agentActorsSawHidden = new List <Actor>(); signalAgentsSawHidden.ForEach(signalAgent => agentActorsSawHidden.Add( GameManager.Instance.ActorLookup[signalAgent])); // Notifies Players about the change if (!GameManager.Instance.ActorLookup.ContainsKey(hiddenAgent[x])) { // If the lookup fails, it is because the game is still initializing. Events arent required here continue; } var actor = GameManager.Instance.ActorLookup[hiddenAgent[x]]; var owner = GameManager.Instance.FindPlayerOfActor(actor); foreach (var enemyFactionIndex in owner.Faction.EnemyFactionIndexes()) { foreach (var player in GameManager.Instance.Players) { if (player.FactionIndex == enemyFactionIndex) { player.EnemyOnSight( hiddenAgent[x], actor, signalAgentsSawHidden, agentActorsSawHidden, previousState, newState); } } } } }