Unity 制造moba英雄联盟战争迷雾2

news/2024/12/21 21:17:58/

文接上一篇

如何使用这些数据?

首先我们需要把这些生成的数据读取出来保存到一个int二维数组里
代码如下

    public Vector2 startPos;//地图开始点public Vector2 Scale;//地图大小public Texture2D renderTexture;//用来渲染的战争迷雾贴图private Texture2D orignTexture;//原始没迷雾贴图public Node[,] map;//地图可见度数组public int[,] Bytemap;//地图障碍物和可行走点地图void Init()//初始化因为是demo我没有独自去生成地图数据然后读取,所以开始游戏的时候再去生成地图数据{Bytemap = new int[(int)Scale.x, (int)Scale.y];//这个是地图数据scale的x和y是代表地图的长宽map =new Node[(int)Scale.x, (int)Scale.y];//node下面有介绍是用来记录点的可见度orignTexture = new Texture2D((int)Scale.x , (int)Scale.y );//这是初始的贴图renderTexture = new Texture2D((int)Scale.x, (int)Scale.y);//这是用来渲染的战争迷雾贴图int pre = 4;//因为地图精度是128*128的如果按照这个直接使用NavMesh.SamplePosition来生成数据会导致不精确所以我让它乘上4倍每4个里有3个以上是可行走的对应的点就是可行走的如果不到三个就是障碍物int y =(int) Scale.y * pre;int x = (int)Scale.x * pre;for (int i = 0; i < y; ++i)//遍历可行走网格点{for (int j = 0; j < x; ++j){bool flag = false;//是否可见NavMeshHit hit;//可行走网格的碰撞信息for (int k = -10; k < 10; ++k){//这个是y轴偏移,因为行走网格位置y轴上可能有不同,这样就可以正常获得当前点是不是可行走网格if (NavMesh.SamplePosition(new Vector3(startPos.x,0,startPos.y ) + new Vector3(j*( accuracy/ pre), k, i* (accuracy/ pre)), out hit, 0.5f, NavMesh.AllAreas)){//如果当前点有行走网格的让bytemap对应下标的值+30没有行走网格的下面就让他减40,因为大于0是可行走,小于0是不可以行走,所以一个点需要3个以上都是可行走的才算可以行走,我让它获取网格的数据是4个精细的点代表一个点flag = true;Bytemap[j/ pre, i/ pre] += 30;if (map[j / pre, i / pre] == null){//如果当前node数组是null就给他生成一个nodemap[j / pre, i / pre] = new Node(j / pre, i / pre);}if ( Bytemap[j/ pre, i/ pre]>0){orignTexture.SetPixel(j / pre, i / pre, Color.black);//如果可以行走设置原始地图贴图对应点是黑色}break;}}if (!flag)//如果不可以走就是让bytemap对应点的值-40{Bytemap[j / pre, i / pre] -= 40;if (map[j / pre, i / pre]==null){map[j / pre, i / pre] = new Node(j / pre, i / pre);map[j / pre, i / pre].intensity = 0;   //这个是当前点的能见度刚开始将它设置成0}if (Bytemap[j / pre, i / pre] <= 0){orignTexture.SetPixel(j / pre, i / pre, Color.red);//如果不可以行走设置原始地图贴图对应点是红色}}}}orignTexture.filterMode = FilterMode.Point;orignTexture.wrapMode = TextureWrapMode.Clamp;orignTexture.Apply();}

需要创建一个Node类这个类是当一个点可以见的时候给对应的intensity赋值,intensity越大就是这个点能见度越大,x y是代表的对应地图点下标

public class Node
{public  int x, y;private int width=1, height=1;public float intensity;public Node(int v1, int v2){this.x = v1;this.y = v2;}public Node(){}public int X{get { return x; }}public int Y{get { return y; }}public int Width { get { return width; } }public int  Height { get { return height; } }
}

判断点是否可见的方法

    /// <summary>/// /// </summary>/// <param name="player">玩家的点</param>/// <param name="obstacle">障碍物的点</param>/// <param name="target">要判断是否可见的点</param>bool isVisable(Node player, Node obstacle, Node target){if (EyeManager.Instance.Bytemap[(int)target.x, (int)target.y] <= 0){//如果目标点也是障碍物就不可见return false;}if (distance(player,target)>radius){//如果目标点到玩家的距离大于视野范围的就不可见return false;}if (distance(player, target) <= distance(player, obstacle)){//因为我用向量判断所以导致有些点本来可以看见的但是向量也是在两个向量之间导致不可见所以判断障碍物到玩家的点距离是否小于障碍物到玩家的点return true;}if (player.Y == obstacle.Y && target.Y == obstacle.Y){//因为我用向量判断所以导致有些点本来可以看见的但是向量也是在两个向量之间导致不可见if (obstacle.x > player.x && obstacle.x < target.x){return false;}if (obstacle.x < player.x && obstacle.x > target.x){return false;}}if (obstacle.X==player.X&&target.X==obstacle.X){//因为我用向量判断所以导致有些点本来可以看见的但是向量也是在两个向量之间导致不可见if (obstacle.y > player.y && obstacle.y < target.y){return false;}if (obstacle.y < player.y && obstacle.y >target.y){return false;}}if (player.X == obstacle.X && target.X == obstacle.X){//因为我用向量判断所以导致有些点本来可以看见的但是向量也是在两个向量之间导致不可见if (distance(player, target) > distance(player, obstacle)){return false;}}//在下面我把目标点和障碍物位置分成四个象限然后每个象限用不同的计算方式来计算是否可见int dir = 0;//0障碍物在人右边,1在人左边dir = player.X > obstacle.X ? 1 : 0;double a = 0;bool isvisible = true;if (obstacle.Y > player.Y && dir == 0){//第一个象限double targety = target.Y + target.Height - player.Y;double targetx = target.X + target.Width - player.X;a = targety / targetx;double obstacley = obstacle.Y + obstacle.Height - player.Y;double obstaclex = obstacle.X + target.Width - player.X;if (((obstaclex * a <= obstacley) && (obstaclex * a >= (obstacley - obstacle.Height)))|| ((obstaclex - obstacle.Width) * a <=obstacley && (obstaclex - obstacle.Width) * a >= (obstacley - obstacle.Height))|| ((obstaclex * a >= obstacley && ((obstaclex - obstacle.Width) * a <= (obstacley - obstacle.Height))))){isvisible = false;}}else if (obstacle.Y > player.Y && dir == 1){//第二个象限double targety = target.Y + target.Height - player.Y;double targetx = target.X - player.X;a = targety / targetx;double obstacley = obstacle.Y + target.Height - player.Y;double obstaclex = obstacle.X - player.X;if (((obstaclex * a <= obstacley) && (obstaclex * a >= (obstacley - obstacle.Height)))|| ((obstaclex - obstacle.Width) * a <= obstacley && (obstaclex - obstacle.Width) * a >= (obstacley + obstacle.Height))|| (obstaclex * a >= obstacley && ((obstaclex + obstacle.Width) * a <= (obstacley - obstacle.Height)))){isvisible = false;}}else if (obstacle.Y <= player.Y && dir == 1){//第三个象限double targety = target.Y - player.Y;double targetx = target.X - player.X;a = targety / targetx;double obstacley = obstacle.Y - player.Y;double obstaclex = obstacle.X - player.X;if (((obstaclex * a >= obstacley) && (obstaclex * a <= (obstacley + obstacle.Height)))|| ((obstaclex + obstacle.Width) * a >= obstacley && (obstaclex + obstacle.Width) * a <= (obstacley + obstacle.Height))|| (obstaclex * a <= obstacley && (obstaclex + obstacle.Width) * a >= (obstacley + obstacle.Height))){isvisible = false;}}else if (obstacle.Y <= player.Y && dir == 0){//第四个象限double targety = target.Y - player.Y;double targetx = target.X + target.Width - player.X;a = targety / targetx;double obstacley = obstacle.Y - player.Y;double obstaclex = obstacle.X + obstacle.Width - player.X;if (((obstaclex * a >= obstacley) && (obstaclex * a <= (obstacley + obstacle.Height)))|| ((obstaclex - obstacle.Width) * a >= obstacley && (obstaclex - obstacle.Width) * a <= (obstacley + obstacle.Height))|| ((obstaclex * a <= obstacley && (obstaclex - obstacle.Width) * a >= (obstacley + obstacle.Height)))){isvisible = false;}}return isvisible;}

计算周围点可见度的详细方法

先获得要遍历的点

//因为一个英雄只关心自己周围的点是否可见所以我们先获得玩家的点和周围要遍历的点int posx = (int)((pos.x - EyeManager.Instance.startPos.x)/ EyeManager.Instance.accuracy);//玩家的x下标
int    posy = (int)((pos.y - EyeManager.Instance.startPos.y) / EyeManager.Instance.accuracy);//玩家的y下标int   xStart = (int)(posx - radius < 0 ? 0 : posx - radius);//x轴开始遍历的下标
int   yStart = (int)(posy - radius < 0 ? 0 : posy - radius);//y轴开始遍历的下标
int   xEnd = (int)(posx + radius >= EyeManager.Instance.Scale.x  ? EyeManager.Instance.Scale.x  - 1 : posx + radius);//x轴结束遍历的下标
int   yEnd = (int)(posy + radius >= EyeManager.Instance.Scale.y  ? EyeManager.Instance.Scale.y  - 1 : posy + radius);//y轴结束遍历的下标
  public Node[] CalcVisibleNodes(int[,] map)//传入地图障碍物数据来计算
{List<Node> obstacles= new List<Node>();//周围障碍物for (int i = xStart; i <= xEnd; i++)//先遍历周围障碍物{for (int j = yStart; j <= yEnd; j++){if ((map[i, j] <= 0)//因为小于零所以是障碍物{Node node = EyeManager.Instance.map[i, j];//获得相应的点obstacles.Add(node);//添加到障碍物列表}}}
 for (int i = xStart; i <= xEnd; i++){for (int j = yStart; j <= yEnd; j++){bool isVisible = true;//当前点是否可见Node target =EyeManager.Instance.map[i, j];float dis = distance(player, target);//目标点和玩家的距离for (int n = 0; n < obstacles.Count; n++)//遍历障碍物{if (!isVisable(player,obstacles1[n],target)){//当前点有被周围一个障碍物遮挡就不可见isVisible = false;//设置标识不可见break;}			         }  if(isVisible ){float intensity = Mathf.Clamp((float)((radius - dis) / (radius - (innerradius * radius))),0, 1);//按照目标点到玩家距离来设置可见度target.intensity += intensity;visibles.Add(target); //添加到可见列表 }          }}return visibles;}

如何生成战争迷雾

由以上方法我们可以获得玩家周围的可见点和可见度

for (int i = 0; i < nodes.Count; i++)//循环遍历获得的可见点这些点是多线程计算获得的详细方法下一篇再说{float intensity= Mathf.Clamp((float)nodes[i].intensity, 0, 1.0f);Color color2 = Color.Lerp(renderTexture.GetPixel(nodes[i].x, nodes[i].y), Color.white * intensity, 0.8f);//进行一个插值计算这样变化就不会很生硬renderTexture.SetPixel(nodes[i].x, nodes[i].y, color2);//然后设置相应点的颜色nodes[i].intensity =0;}nodes.Clear();renderTexture.Apply();//这就是我们要的战争迷雾贴图

如何使用战争迷雾贴图

下一篇再讲


http://www.ppmy.cn/news/686527.html

相关文章

【英雄联盟】关于我是如何打上超凡大师的,ADC键位设置

玩ADC如何上大师&#xff1f;作为曾在全国高校solo赛拿德莱文进过八强的选手&#xff0c;分享一点自己的游戏经验。 修改基本设置这东西真的非常非常重要&#xff0c;用默认的设置上限就是青铜&#xff0c;所以基本上老玩家都有一套自己喜欢的键位。 分享一套自己用的&#…

用英雄联盟的方式讲解JavaScript设计模式

关注 前端瓶子君&#xff0c;回复“交流” 加入我们一起学习&#xff0c;天天进步 构造函数模式 简介 在JavaScript里&#xff0c;构造函数通常是认为用来实现实例的特殊的构造函数。通过new关键字来调用定义的构造函数&#xff0c;你可以告诉JavaScript你要创建一个新对象并且…

使用Unity和A*插件实现LoL英雄联盟中的移动方式

LoL中的移动方式是怎么样的呢&#xff1f;我分析一下应该是这样的&#xff1a; 右键单击选择目标点&#xff0c;角色会向着目标点走去&#xff0c;而去目标点的路上如果点击了其它目标点就更新目标点&#xff0c;如果中间有障碍会自动选择最近的路径&#xff0c;如果目标点不可…

使用这个算法我可以实现英雄联盟里英雄的走位|Java 开发实战

A算法&#xff0c;A&#xff08;A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法&#xff0c;也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近&#xff0c;最终搜索速度越快。 基本概念 首先在大学我们遇到最多的算法Dijkstra、Floyd、广度…

用英雄联盟的方式讲解JavaScript设计模式!

简介 在JavaScript里&#xff0c;构造函数通常是认为用来实现实例的特殊的构造函数。通过new关键字来调用定义的构造函数&#xff0c;你可以告诉JavaScript你要创建一个新对象并且新对象的成员声明都是构造函数里定义的。在构造函数内部&#xff0c;this关键字引用的是新创建的…

从认识英雄联盟到放弃英雄联盟

从认识英雄联盟到放弃英雄联盟 从大学毕业后工作这2&#xff0c;3年内&#xff0c;可以说自己很少玩网络游戏&#xff1b;像dota、 魔兽、 英雄联盟这类即时对战游戏&#xff0c;就根本没有接触过。 最近合租室友一直在玩这款游戏&#xff0c;而我却还在一旁看一边嘲笑他 ‘这来…

用英雄联盟的方式讲解 JavaScript 设计模式

点击下方“逆锋起笔”&#xff0c;公众号回复 编程资源 领取大佬们推荐的学习资料作者&#xff1a;黄梵高 原文&#xff1a;https://juejin.cn/post/6844904165982879758 构造函数模式 简介 在JavaScript里&#xff0c;构造函数通常是认为用来实现实例的特殊的构造函数。通过n…

JavaGui实现英雄联盟换肤展示效果

小组项目 功能模块&#xff1a; 登录功能 注册功能 管理员增删改查 前端展示功能 1.登录功能 public class DengLu extends JFrame implements MouseListener{int i 1;JButton denglu new JButton();JButton zhuce new JButton();JButton guanli new JButton();JTextField…