日誌2019-09-11 11:30
Unity的 RTS戰爭迷霧 視野障礙作者:樂小呈
[SerializeField] float sightRange = 1; public float SightRange { get => sightRange; } [SerializeField] LayerMask blockLayer; //New [SerializeField] bool showDebug = false; //New |
[SerializeField] Vector3 mapScale; [SerializeField] Vector3 fogScale = Vector3.up; [SerializeField] SpriteRenderer fogSprite; List<SpriteRenderer> mapFogs = new List<SpriteRenderer>(); //改名 [SerializeField] List<Sight> allSights = new List<Sight>(); //改名 |
void UpdateFogs() { ResetFogs(); foreach (var sight in allSights) { List<SpriteRenderer> fogInSight = mapFogs.FindAll (n => Vector3.Distance(n.transform.position, sight.transform.position) < sight.SightRange); List<SpriteRenderer> sightBlock = sight.SightBlock(fogInSight); //找出視線範圍中受到阻擋的部分 List<SpriteRenderer> sights = fogInSight.Except(sightBlock).ToList(); //找出視線範圍中不受阻擋的部分 FogLight(fogInSight, sights); //更改霧塊狀態 } } |
public List<SpriteRenderer> SightBlock(List<SpriteRenderer> fogs) { bool blockCheck = Physics2D.OverlapCircle(transform.position, sightRange, blockLayer); //判斷視野範圍中有沒有[障礙物],用blockLayer來分辨 if (!blockCheck) { return new List<SpriteRenderer>() ; } //如果視野中沒有任何[障礙物],回傳空 List List<SpriteRenderer> blockSight = new List<SpriteRenderer>(); foreach (var fogSprite in fogs) { //檢查視線中每一個霧塊 Vector3 dirction = transform.position - fogSprite.transform.position ; //計算霧塊對於自己的方向,Raycast需要用到 float distance = Vector3.Distance(transform.position, fogSprite.transform.position); //計算目標霧塊與自身的距離,Raycast需要用到 bool isBlocking = Physics2D.Raycast(fogSprite.transform.position, dirction, distance, blockLayer); //發射一條射線,檢查霧塊和自己之間有沒有受到[障礙物]阻擋 if (!isBlocking) { continue; } //判斷有沒有受到[障礙物]阻擋 if (showDebug) { Debug.DrawRay(fogSprite.transform.position, dirction, Color.red); //Debug用的,顯示判斷的線 } blockSight.Add(fogSprite); //把受到阻擋的霧塊加入List } return blockSight; //回傳所有受到阻擋的霧塊 } |
void FogLight(List<SpriteRenderer> lightFogs, List<SpriteRenderer> sights) { foreach (var lightFog in lightFogs) //把視野範圍中的霧塊設置不透明 { Color fogColor = lightFog.color; fogColor.a = 0.5f; lightFog.color = fogColor; } foreach (var sight in sights) //把視線中的霧塊隱藏 { sight.gameObject.SetActive(false); } } |