重庆工信部网站,绵阳公司网站建设,怎么给领导做网站分析,苏州现在可以正常进入吗文章目录 前言导入素材开始1. 设置瓦片间隙2. 放置全图瓦片3. 美化瓦片地图4. 添加树木障碍物5. 设定不同的排序图层6. 瓦片交互6. 瓦片交互优化6. 瓦片是否允许角色7. 添加角色8. 新增游戏管理脚本9. 角色移动范围逻辑10. 角色移动范围可视化11. 角色移动12. 重置瓦片颜色12. … 文章目录 前言导入素材开始1. 设置瓦片间隙2. 放置全图瓦片3. 美化瓦片地图4. 添加树木障碍物5. 设定不同的排序图层6. 瓦片交互6. 瓦片交互优化6. 瓦片是否允许角色7. 添加角色8. 新增游戏管理脚本9. 角色移动范围逻辑10. 角色移动范围可视化11. 角色移动12. 重置瓦片颜色12. 限制移动次数13. 最终效果 其他源码下载参考完结 前言
探索战争与策略的无穷魅力让我们一同踏入一个充满战旗的世界战旗游戏作为战棋类游戏的翘楚引领了一股独特的战斗风潮。你是否曾经想过如果能够自己设计并实现一个属于自己的战旗游戏该是何等的创造与乐趣
在本文中我们将使用Unity引擎探索如何快速构建一个简单而富有策略的战旗游戏Demo。通过本教程的指引你将学习如何使用Unity的强大功能和库创造出一个令人着迷的战旗世界。
在这个Demo中我们将以一个虚拟的大陆为背景玩家将担任敌对阵营的指挥官通过战略布局和英勇的决策争夺控制权。你可以选择完善这个demo如每个棋子具有独特的能力和特点如守护剑士的高生命值、魔法师的强大攻击力等通过购买、升级和精心安排棋子的位置引领你的队伍战胜对手达到最终的胜利目标
另外最近很火的自走棋也属于战旗游戏的一种。自走棋是战棋类游戏的变种它保留了战旗游戏的核心元素如策略布局和战斗对抗同时加入了自动化的棋子行动机制。
为了帮助你更好地理解我们特别准备了一些战旗游戏的精彩截图和GIF动画展示了战旗游戏的精彩瞬间。这些截图将带你亲身体验游戏的视觉效果和紧张的战斗氛围。 无论是战旗游戏爱好者还是对Unity开发感兴趣的朋友本教程都将为你揭开战旗游戏的奥秘帮助你构建一个引人入胜的战旗游戏Demo。
照例先来看看本文实现的最终效果以觉得你是否还要看下去
好了让我们开始我们的战旗之旅吧 源码放在文章底部了
导入素材 开始
1. 设置瓦片间隙
新建一个2d项目打开以后将所需要的【图片】拖入到项目中 我们首先将这张【Tile瓦片】拖入场景窗口中 由于这张图片的原始大小过大我们可以手动的去调整图片的大小 至于这个瓦片大小究竟要调整到什么样的程度我建议确保四周的相邻瓦片他们之间的 相对距离为【一个单位】就可以了并留一点点的间隙就好了 具体的原因会和之后的角色【移动范围】有关 为了达到这个效果我们要先去设置Snap Setting我们希望当我们按住【cmd/Ctrl】后拖拽物体能够移动【一个单位】长度 2021之前Snap Setting是在Edit栏最下面我在Unity2021菜单栏里找了半天没找到最后发现在Scene窗口里 按下【Cmd/CtrlD克隆】当前瓦片游戏对象 然后当我们要移动该对象时(首先)按住【cmd/ctrl】按钮 然后拖拽实现Snap Moving”即【一个单位】距离长度的移动 如果你觉得相邻的两个瓦片之间的间隙还是稍微有一点大的 我们还可以稍微放大一点这张图片的大小
2. 放置全图瓦片
设置瓦片为预制体如下图配置好全图的瓦片地图
3. 美化瓦片地图 现在我们的地图图片看上去还是有一点【枯燥】的我们希望每次运行游戏后地图上的【每一张瓦片】他都能够随机生成不一样的瓦片图片供我们欣赏 在Sprites文件夹中将Tilesi这张图片设置为多图模式以后 在精灵编辑器中进行【自动的裁切】 在Scripts文件夹中新建一个C#脚本Tile
public class Tile : MonoBehaviour
{private SpriteRenderer spriteRenderer;//瓦片[SerializeField] private Sprite[] sprites;//瓦片集private void Start(){spriteRenderer GetComponentSpriteRenderer();int randomNum Random.Range(0, sprites.Length);//随机获取0-9下标spriteRenderer.sprite sprites[randomNum];//赋值给瓦片}
}挂载脚本和对象运行游戏现在每次开始游戏我们都会随机生成不一样的地图了
4. 添加树木障碍物 我们现在希望在图片上添加更多的树木而有的树木他会作为实体有的会作为【障碍物】的形式 障碍物在之后的角色移动当中起到【阻止角色移动】到这个瓦片上的功能 我们新建三个空物体树木背景障碍物负责管理所有树木以及障碍物 将树木游戏对象作为它们的【父物体】来使用
我们先建立一些美观的树木 选择【多图模式】后进行裁剪
5. 设定不同的排序图层
由于之后还会创建人物我们希望所有【有关背景的图片】都会渲染在人物的后方 配置不同的排序层级 瓦片和树木排序图层我们都设置为background因为树木肯定显示在瓦片前面我们可以把图层排序设置为50放置不同的树木丰富一下场景如下
6. 瓦片交互 为了能够更好的交互我们希望当我们的鼠标【选择到】每一个瓦片时瓦片能给我们一定的反馈我们希望鼠标【进入瓦片】时瓦片能放大当我们【离开瓦片】时瓦片能回到原来的大小 我们可以使用Unity内置的【OnMouseEnter】和【OnMouseExit】方法来实现 大家只要记住一点实现这两个方法呢是有一个前提的那就是我们鼠标要检测的对象也就是这里的瓦片他必须添加【Collider2D】碰撞器组件
我们先给瓦片添加碰撞器记得应用全部预制体 完善Tile脚本代码
private void OnMouseEnter()
{transform.localScale Vector3.one * 0.05f;}private void OnMouseExit(){transform.localScale - Vector3.one * 0.05f;}效果
6. 瓦片交互优化 我们还可以去观察一个细节现在部分放大的瓦片时还是会被相邻的瓦片渲染在下方 为了能够保证当我们放大每一个瓦片时这个瓦片都可以渲染在【最上方】我们还可以调整它的渲染层顺序 瓦片位于Background层的0号位置顺序 而实体的树木呢顺序是50号 我们只需要去保证放大的瓦片顺序 在其他瓦片之上实体树木之下就可以了(即在0到50之间),我们这里设置为【25】
完善Tile脚本代码
private void OnMouseEnter()
{transform.localScale Vector3.one * 0.05f;spriteRenderer.sortingOrder 25;}private void OnMouseExit(){transform.localScale - Vector3.one * 0.05f;spriteRenderer.sortingOrder 0;}最终效果
6. 瓦片是否允许角色 我们就要开始最重要的第一步判断了这个瓦片是否允许角色去行走 如果这个瓦片上有【树木】,那我们的角色是不能够行走到这个瓦片上的 我们判断的依据是如果瓦片上存在【树木】或者【人】,那么这个瓦片【不允许】再站人玩家是不能够移动到这个瓦片上的 完善Tile脚本代码
public bool canWalk;//是否能走
public LayerMask obLayerMask;//检测层private void Start()
{CheckObstacle();
}private void CheckObstacle()
{//参数1圆形检测的中心点位置那也就是我们瓦片的中心点位置//参数2范围spriteRenderer.bounds.extents.x获取图片一半的长度//参数3检测层Collider2D collider Physics2D.OverlapCircle(transform.position, spriteRenderer.bounds.extents.x, obLayerMask);if (collider ! null)//检测不为空说明有障碍物在这个瓦片上呀canWalk false;elsecanWalk true;//这个瓦片我们的角色是可以行走的
}回到Unity当中新建一个Layer层命名为Obstacle全选中所有【实体树木】游戏对象设置为Obstacle层 回忆一下有关【Physics:2D.Raycast】或者【Physics:2D.OverlapCircle】的定义 他们的方法检测的都是添加了【Collider组件】的游戏对象
还有别忘记了要给每个树木加碰撞体
7. 添加角色
添加角色随便找个人物角色图片就可以了,也可以用我准备的 注意角色裁剪时记得把锚点设置在人物脚的位置这个很关键开始我就是没注意当设置人物位置时会发生偏移 直接拖拽锚点肯定是不精准每张图片不同位置锚点的偏差会使角色出现晃得的情况所以最好是手动修改锚点的位置我这里设置的是0.5x0.15
想默认把角色放在哪个瓦片上就设置角色xy坐标为对应即可切记不要拖拽不然xy坐标会不准确后面渲染行走路线会不准确 给角色添加对应动画和碰撞器记得修改排序图层为Forground
8. 新增游戏管理脚本 我们希望的是当鼠标点击角色时角色能够显示相应的可移动范围有障碍物则这个瓦片呢不可以移动 我们首先需要遍历所有的瓦片 然后去筛选出所有满足要求的瓦片 然后对这些瓦片呢进行高亮 然后就可以显示出我们角色可以移动的这些瓦片了 由于需要遍历所有的瓦片 之后呢我们也会去需要对所有的瓦片进行高亮和重置等操作 我们会反反复复的一遍一遍的去用到所有瓦片这一数组
我们新建一个C#脚本GameManager 来管理游戏中的一些核心的变量和一些常用的方法 tiles其实可以通过动态生成比较好这里为了方便我就直接使用拖拽了
设置为单例
public class GameManager : MonoBehaviour
{public static GameManager instance;public Tile[] tiles;//在这个游戏中所有的贴图public Unit selectedUnit;//被选中的角色private void Awake(){if(instance null){instance this;}else{if(instance ! this){Destroy(gameObject);}}DontDestroyOnLoad(gameObject);}
}新建一个C#脚本Unit将Unit脚本添加到角色游戏对象中 鼠标要点击的呢是Unit对象所以写在Unit脚本中
我们鼠标是点击我们的角色 当我们鼠标进入角色Collider范围 并且按下鼠标左键时则会调用这个方法(OnMouseDown】 所以方法内部呢 当我们点击这个角色后显示可移动的瓦片
声明一个整数类型int类型的变量moveRange 表示当前角色可移动的格子数 我们先设置为三 如果之后我们创建不同的角色 我们还可以去使用 【ScriptableObject】)或者【继承】 的方式来进行代码上的重构
我们还可以利用特性【Range】 将这个变量的可选择范围呢控制在1~7这几个整数当中 在【ShowWalkableTiles】)方法中 我们要获取角色周围以自身为中心的一个菱形 菱形的大小呢由角色的移动范围来决定 Unit代码
9. 角色移动范围逻辑 我们应该如何去获取角色移动可行走的瓦片呢 我们可以先做一个这样的判断
如果我们的角色移动范围等于1 那么我们角色可以行走范围呢应该是这个样子的 如果我们的角色移动范围等于2 那么我们可以行走的范围可以到达额外的这八个点 我们将所有可移动的瓦片位置坐标标示在了图片上 我们可以发现我们可达到的瓦片的位置坐标呢X和Y值相加会小于等于角色的移动范围 我们可以分别去通过角色与每个瓦片之间的x轴的距离 角色与每个瓦片之间Y轴的距离相加进行比较 如果X轴和Y轴的距离相加之后小于等于角色的移动范围 那么这些瓦片呢就是我们可以移动的范围了 其他的瓦片就是在我们角色移动范围之外的这些瓦片
10. 角色移动范围可视化
完善Unit代码
public class Unit : MonoBehaviour
{[SerializeField] [Range(1,7)]private int moveRange 3;private void OnMouseDown(){ShowWalkableTiles();}private void ShowWalkableTiles(){for (int i 0; i GameManager.instance.tiles.Length; i){float distX Mathf.Abs(transform.position.x - GameManager.instance.tiles[i].transform.position.x);float distY Mathf.Abs(transform.position.y - GameManager.instance.tiles[i].transform.position.y);if(distX distY moveRange){//Tile is Walkable or not (without obstacle)if (GameManager.instance.tiles[i].canWalk)GameManager.instance.tiles[i].HighlightTile();}}}Tile脚本定义可行走区域高亮显示方法
public void HighlightTile()
{if (canWalk){spriteRenderer.color highlightColor;}else{spriteRenderer.color Color.white;}}挂载脚本绑定参数 如果发现一切设置都没错但是点击没有效果也没有调用OnMouseDown方法可以将角色z轴适当调高防止遮挡 效果可以看到被障碍物树木占据的瓦片禁止行走是我们想要的效果
11. 角色移动 下一步就是我们要让我们的角色能够真正的移动到我们想要移动到的点 当我们选中角色后点击瓦片时角色才能移动 意思就是说我们移动的方法应该写在Tile瓦片脚本内部 我们可以在瓦片这个Tile脚本当中使用OnMouseDown方法来执行角色的移动 我们的角色会移动到我们点击的这个瓦片位置上 由于之后呢 我们可能会不止有一个角色 我们在GameManager脚本当中呢 声明一个Unit类型的变量selectedUnit 表示我们当前鼠标点击的这个角色
public Unit selectedUnit;//被选中的角色在Unit脚本中创建一个Move方法
由于角色的移动是需要一个【过程】的并且我们希望角色的移动是根据瓦片的路线来进行移动的而不是点对点的直接移动这里我们就需要去使用协程函数【协程函数】可以将一个函数分割成多个帧去执行按一定顺序去执行优先去进行【水平方向】的移动 [SerializeField] private float moveSpeed;//MARKER 这个方法会在【Tile脚本】中OnMouseDown函数中被【调用】
public void Move(Transform _trans)
{StartCoroutine(MoveCo(_trans));
}IEnumerator MoveCo(Transform _trans)
{//角色先水平方向移动while (transform.position.x ! _trans.position.x){transform.position Vector2.MoveTowards(transform.position, new Vector2(_trans.position.x, transform.position.y), moveSpeed * Time.deltaTime);yield return new WaitForSeconds(0);}//水平方向到达目的地X后再垂直方向移动while (transform.position.y ! _trans.position.y){transform.position Vector2.MoveTowards(transform.position, new Vector2(transform.position.x, _trans.position.y), moveSpeed * Time.deltaTime);yield return null;}
}12. 重置瓦片颜色 在角色完成移动后我们当然希望将我们一开始【高亮】的瓦片能够重置回原本的颜色来保证之后的所有操作 我们可以在Tile脚本中创建一个ResetTile方法 对【颜色属性】进行一次修改
public void ResetTile()
{spriteRenderer.color Color.white;
}在Unit脚本中创建一个ResetTiles方法 遍历所有瓦片将他们重置回原本的颜色
private void ResetTiles()
{for (int i 0; i GameManager.instance.tiles.Length; i){GameManager.instance.tiles[i].ResetTile();}
}在角色完成移动后再调用这个方法
IEnumerator MoveCo(Transform _trans)
{//。。。ResetTiles();
}在tile脚本中调用move方法
private void OnMouseDown()
{//Player Move to this TILE 当我们选择了角色点击这块瓦片那么角色就会移动到这个瓦片上if (GameManager.instance.selectedUnit ! null)GameManager.instance.selectedUnit.Move(this.transform);}最后别忘了一点我们还需要在这个角色的Unit脚本当中的OnMouseDown中指明 GameManager.instance.selectedUnit this;
private void OnMouseDown()
{GameManager.instance.selectedUnit this;//。。。
}效果 ps上图演示有个瓦片没有显示是因为我下面的障碍物树木碰撞体设置过大影响了上面的瓦片我自己调整了这里说明一下
12. 限制移动次数 最后还遗留了一个问题我们的角色可以进行无限次数的移动 在Tile引入canMove参数判断哪个瓦片人物是可移动的以此来限制角色的移动次数
public bool canMove;public void HighlightTile()
{if (canWalk){canMove true;spriteRenderer.color highlightColor;}else{spriteRenderer.color Color.white;}
}public void ResetTile()
{spriteRenderer.color Color.white;//重置所有的canMove为falsecanMove false;
}
private void OnMouseDown()
{//Player Move to this TILE 当我们选择了角色点击这块瓦片那么角色就会移动到这个瓦片上if (canMove GameManager.instance.selectedUnit ! null)GameManager.instance.selectedUnit.Move(this.transform);
}13. 最终效果 其他
其实后面还有很多开发的空间比如增加不同的角色、敌人完善角色移动和攻击动画等这里我就不在赘述了留给大家自由去扩展结束
源码下载
https://gitcode.net/unity1/battleflag
参考
【视频】https://www.bilibili.com/video/BV1vQ4y1M7gy/
完结
赠人玫瑰手有余香如果文章内容对你有所帮助请不要吝啬你的点赞评论和关注以便我第一时间收到反馈你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法也欢迎评论私信告诉我哦
好了我是向宇https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者出于兴趣爱好于是最近才开始自习unity。如果你遇到任何问题也欢迎你评论私信找我 虽然有些问题我可能也不一定会但是我会查阅各方资料争取给出最好的建议希望可以帮助更多想学编程的人共勉~