unity如何实现战争迷雾?思路一
2021-02-01 19:14
标签:组成 span src lse 创建 世界 raw canvas cube unity如何实现战争迷雾?思路一 断更很久了,刚好今天放假,写一个unity下实现战争迷雾的思路. 效果如下: 思路如下: 建一个plane作为地面,用UI中的rawimage放在最上层作为迷雾显示,用cube作为主角移动.cube每次移动,将它的坐标转化为rawimage上相对位置的点,然后用texture2d的setpixel方法逐像素清除出一个区域出来. 左下角rawimage显示小地图,有单独一个camera专门将迷雾绘制到小地图中. 具体实现: 1.新建plane,cube,分别作为地面和主角,并把场景中的Main Camera作为cube的子物体.如下设置. 在project窗口创建一个material并赋给cube方便改颜色. 2.新建一个canvas和一个rawimage,并按如下设置. 3.新建一个gameobject,在它的下面,新建一个camera,新建一个canvas并在它的下面新建image,rawimage.设置如下. 在project窗口创建一个rendertexture并赋给camera和rawimage. image用于小地图的背景框,也可忽略. 3.新建一个gameobject,并加上脚本. 4.首先,先将迷雾初始化出来.打开编辑FogOfWar脚本.定义fogRawImage,是worldcanvas下的rawimage.定义fogDensity ,迷雾的像素密度,由多少个点组成.定义fogTexture,赋给fogRawImage后,后续的像素颜色更改,只需对fogTexture进行.InitializeTheFog方法将迷雾初始化为黑色. 5.接着,设置要消除的形状的坐标数组.定义beEliminatedShapeSize ,要消除的形状的长和宽.定义shapeLocalPosition,这个形状的点分布数组,假设中心为(0,0),后续只需要将要消除的点的坐标跟这个数组所有值相加,即可得到该点出现的形状的所有坐标.InitializeTheShape方法是初始化视野的形状,此处是矩形,如果想将视野做成椭圆形,三角形,六角形,修改InitializeTheShape中的写法然后赋给shapeLocalPosition. 6.接着是在texture中消除出一个形状来.这里需要注意的是,cube是在世界坐标中,通过消除rawimage中的像素透明度来实现获得视野,所以需要将cube的坐标转换为rawimage上(texture2d上)相对应的点.因为texture是左下角为原点,向右为正x,向上为正y,如下图. 所以,一种思路就是将cube的世界最左下的一点作为它的原点,然后根据cube的位置和这个原点的位置偏移量,换算成texture中相对应的点,也就是plane的左下角的坐标.下图,是从上往下看的视角. 定义cubeTransform,cube的transform.定义planeMeshCollider,用于获取plane的尺寸.定义planeOriginPoint,储存世界坐标中cube的假定原点.定义worldSize,地面的尺寸,也就是plane的尺寸.EliminateFog方法,获得当前cube位置的视野. 7.设置cube的移动控制,并在每次移动消除迷雾.这里简单写一个. 8.完成后的场景结构和FogOfQar脚本设置如下. 9.完整代码如下: 欢迎交流. 转载注明出处. unity如何实现战争迷雾?思路一 标签:组成 span src lse 创建 世界 raw canvas cube 原文地址:https://www.cnblogs.com/JinT-Hwang/p/12813028.html 1 public RawImage fogRawImage;
2
3 public Vector2Int fogDensity = new Vector2Int(100, 100);
4
5 private Texture2D fogTexture;
6
7 void Start()
8 {
9 fogTexture = new Texture2D(fogDensity.x, fogDensity.y);
10
11 fogRawImage.texture = fogTexture;
12
13 InitializeTheFog();
14 }
15
16 void InitializeTheFog()
17 {
18 int pixelCount = fogDensity.x * fogDensity.y;
19 //将迷雾的默认颜色设置为黑色
20 Color[] blackColors = new Color[pixelCount];
21 for (int i = 0; i )
22 {
23 blackColors[i] = Color.black;
24 }
25 fogTexture.SetPixels(blackColors);
26
27 fogTexture.Apply();
28 }
1 public Vector2Int beEliminatedShapeSize = new Vector2Int(8, 6);
2 private Vector2Int[] shapeLocalPosition;
3 void Start()
4 {
5 //...
6
7 InitializeTheShape();
8 }
9
10 void InitializeTheShape()
11 {
12 int pixelCount = beEliminatedShapeSize.x * beEliminatedShapeSize.y;
13 shapeLocalPosition = new Vector2Int[pixelCount];
14
15 int halfX = Mathf.FloorToInt(beEliminatedShapeSize.x * 0.5f);
16 int remainingX = beEliminatedShapeSize.x - halfX;
17 int halfY = Mathf.FloorToInt(beEliminatedShapeSize.y * 0.5f);
18 int remainingY = beEliminatedShapeSize.y - halfY;
19
20 int index = 0;
21 for (int y = -halfY; y )
22 {
23 for (int x = -halfX; x )
24 {
25 shapeLocalPosition[index] = new Vector2Int(x, y);
26 index++;
27 }
28 }
29 }
1 public Transform cubeTransform;
2 public MeshCollider planeMeshCollider;
3
4 private Vector2 planeOriginPoint;
5 private Vector2 worldSize;
6
7 void Start()
8 {
9 //...
10
11 worldSize = new Vector2(planeMeshCollider.bounds.size.x, planeMeshCollider.bounds.size.z);
12 //将plane的坐标减去它尺寸的一半,即可得到它的左下角的坐标
13 planeOriginPoint = new Vector2(planeMeshCollider.transform.position.x - worldSize.x * 0.5f, planeMeshCollider.transform.position.z - worldSize.y * 0.5f);
14
15 InitializeTheShape();
16 InitializeTheFog();
17
18 EliminateFog();
19 }
20
21 void EliminateFog()
22 {
23 Vector2 cubePos = new Vector2(cubeTransform.position.x, cubeTransform.position.z);
24 //相对假定原点的距离比例,因为是世界坐标,两个点相减有可能是负数,texture中不存在负数的坐标,所以转化为正数.
25 Vector2 originDistanceRatio = (cubePos - planeOriginPoint) / worldSize;
26 originDistanceRatio.Set(Mathf.Abs(originDistanceRatio.x), Mathf.Abs(originDistanceRatio.y));
27 //距离比例乘以密度,即可知道cube相当在texture中的点即可计算出来
28 Vector2Int fogCenter = new Vector2Int(Mathf.RoundToInt(originDistanceRatio.x * fogDensity.x), Mathf.RoundToInt(originDistanceRatio.y * fogDensity.y));
29 for (int i = 0; i )
30 {
31 int x = shapeLocalPosition[i].x + fogCenter.x;
32 int y = shapeLocalPosition[i].y + fogCenter.y;
33 //因为消除迷雾的形状是比cube的位置还要大的,在最边缘的时候,消除的像素点的坐标会超出texture范围,所以超出部分忽略.
34 if (x 0 || x >= fogDensity.x || y 0 || y >= fogDensity.y)
35 continue;
36
37 fogTexture.SetPixel(x, y, Color.clear);
38 }
39
40 fogTexture.Apply();
41 }
1 public float cubeMoveSpeed = 0.1f;
2 private void Update()
3 {
4 if (Input.anyKey)
5 {
6 if (Input.GetKey(KeyCode.W))
7 {
8 cubeTransform.position += Vector3.forward * cubeMoveSpeed;
9 }
10 else if (Input.GetKey(KeyCode.S))
11 {
12 cubeTransform.position += Vector3.back * cubeMoveSpeed;
13 }
14 else if (Input.GetKey(KeyCode.A))
15 {
16 cubeTransform.position += Vector3.left * cubeMoveSpeed;
17 }
18 else if (Input.GetKey(KeyCode.D))
19 {
20 cubeTransform.position += Vector3.right * cubeMoveSpeed;
21 }
22
23 EliminateFog();
24 }
25 }
1 using UnityEngine;
2 using UnityEngine.UI;
3
4 public class FogOfWar : MonoBehaviour
5 {
6 public RawImage fogRawImage;
7 public MeshCollider planeMeshCollider;
8 public Transform cubeTransform;
9
10 public float cubeMoveSpeed = 0.1f;
11
12 public Vector2Int fogDensity = new Vector2Int(100, 100);
13 public Vector2Int beEliminatedShapeSize = new Vector2Int(8, 6);
14
15 private Texture2D fogTexture;
16
17 private Vector2Int[] shapeLocalPosition;
18
19 private Vector2 planeOriginPoint;
20 private Vector2 worldSize;
21
22 // Start is called before the first frame update
23 void Start()
24 {
25 fogTexture = new Texture2D(fogDensity.x, fogDensity.y);
26 fogRawImage.texture = fogTexture;
27
28 worldSize = new Vector2(planeMeshCollider.bounds.size.x, planeMeshCollider.bounds.size.z);
29 //将plane的坐标减去它尺寸的一半,即可得到它的左下角的坐标
30 planeOriginPoint = new Vector2(planeMeshCollider.transform.position.x - worldSize.x * 0.5f, planeMeshCollider.transform.position.z - worldSize.y * 0.5f);
31
32 InitializeTheShape();
33 InitializeTheFog();
34
35 EliminateFog();
36 }
37
38 private void Update()
39 {
40 if (Input.anyKey)
41 {
42 if (Input.GetKey(KeyCode.W))
43 {
44 cubeTransform.position += Vector3.forward * cubeMoveSpeed;
45 }
46 else if (Input.GetKey(KeyCode.S))
47 {
48 cubeTransform.position += Vector3.back * cubeMoveSpeed;
49 }
50 else if (Input.GetKey(KeyCode.A))
51 {
52 cubeTransform.position += Vector3.left * cubeMoveSpeed;
53 }
54 else if (Input.GetKey(KeyCode.D))
55 {
56 cubeTransform.position += Vector3.right * cubeMoveSpeed;
57 }
58
59 EliminateFog();
60 }
61 }
62
63 void InitializeTheShape()
64 {
65 int pixelCount = beEliminatedShapeSize.x * beEliminatedShapeSize.y;
66 shapeLocalPosition = new Vector2Int[pixelCount];
67
68 int halfX = Mathf.FloorToInt(beEliminatedShapeSize.x * 0.5f);
69 int remainingX = beEliminatedShapeSize.x - halfX;
70 int halfY = Mathf.FloorToInt(beEliminatedShapeSize.y * 0.5f);
71 int remainingY = beEliminatedShapeSize.y - halfY;
72
73 int index = 0;
74 for (int y = -halfY; y )
75 {
76 for (int x = -halfX; x )
77 {
78 shapeLocalPosition[index] = new Vector2Int(x, y);
79 index++;
80 }
81 }
82 }
83
84 void InitializeTheFog()
85 {
86 int pixelCount = fogDensity.x * fogDensity.y;
87 //将迷雾的默认颜色设置为黑色
88 Color[] blackColors = new Color[pixelCount];
89 for (int i = 0; i )
90 {
91 blackColors[i] = Color.black;
92 }
93 fogTexture.SetPixels(blackColors);
94
95 fogTexture.Apply();
96 }
97
98 void EliminateFog()
99 {
100 Vector2 cubePos = new Vector2(cubeTransform.position.x, cubeTransform.position.z);
101 //相对假定原点的距离比例,因为是世界坐标,两个点相减有可能是负数,texture中不存在负数的坐标,所以转化为正数.
102 Vector2 originDistanceRatio = (cubePos - planeOriginPoint) / worldSize;
103 originDistanceRatio.Set(Mathf.Abs(originDistanceRatio.x), Mathf.Abs(originDistanceRatio.y));
104 //距离比例乘以密度,即可知道cube相当在texture中的点即可计算出来
105 Vector2Int fogCenter = new Vector2Int(Mathf.RoundToInt(originDistanceRatio.x * fogDensity.x), Mathf.RoundToInt(originDistanceRatio.y * fogDensity.y));
106 for (int i = 0; i )
107 {
108 int x = shapeLocalPosition[i].x + fogCenter.x;
109 int y = shapeLocalPosition[i].y + fogCenter.y;
110 //因为消除迷雾的形状是比cube的位置还要大的,在最边缘的时候,消除的像素点的坐标会超出texture范围,所以超出部分忽略.
111 if (x 0 || x >= fogDensity.x || y 0 || y >= fogDensity.y)
112 continue;
113
114 fogTexture.SetPixel(x, y, Color.clear);
115 }
116
117 fogTexture.Apply();
118 }
119 }
上一篇:java实现发送短信
下一篇:归并排序(非递归实现)