Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

这篇具有很好参考价值的文章主要介绍了Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今天想给大家分享的主题是如何实现RTS类型游戏中的游戏单位角色控制

本文中会介绍如何运用最新的ECS架构来实现游戏单位控制

效果演示

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

效果实现

选中多个游戏单位

public class UnitControlSystem : ComponentSystem 
{
		private float3 startPosition;
		protected override void OnUpdate() // OnUpdate与MonoBehaviour中的UPdate一样,游戏运行的每一帧都会执行OnUpdate
		{
				if(Input.GetMouseButtonDown(0)) // 鼠标左键按下时执行的内容
				{
						// Mouse Pressed
						StartPosition = UnilsClass.GetMouseWorldPosition(); // 记录鼠标按下的位置
				}
				if(Input.GetMouseButtonUP(0)) //鼠标左键弹起时执行的内容
				{
						// Mouse Released
						float3 endPosition = UnilsCalss.GetMouseWorldPosition(); // 记录鼠标弹起的位置
						
						float3 lowerLeftPosition = new float3(math.min(startPosition.x, endPosition.x),
								math.min(startPosition.y, endPosition.y),0); // 获取鼠标框选方框左下角的位置
						float3 upperRightPosition = new float3(math.max(startPosition.x, endPosition.x),
								math.max(startPosition.y, endPositon.y),0); // 获取鼠标框选方框右上角的位置
						
						Entities.ForEach((Entity entity, ref Translation translation) => {
								float3 entityPosition = translation.Value;
								if(entityPosition.x >= lowerLeftPosition.x &&
									 entityPosition.y >= lowerLeftPosition.y &&
									 entityPosition.x <= upperRightPosition.x &&
									 entityPosition.y <= upperRightPosition.y){
									 Debug.Log(entity);
								}
						}); // 遍历所有实体,判断它是否被框选选中
				}
		}
}
  • 上方代码实现的功能是获取被鼠标框选的游戏单位,如果需要源代码可以在文末添加爱丽丝老师的QQ或者微信号领取
  • 代码讲解
  • 获取鼠标框选方框的左下角和右上角
float3 lowerLeftPosition = new float3(math.min(startPosition.x, endPosition.x),
math.min(startPosition.y, endPosition.y),0); // 获取鼠标框选方框左下角的位置
float3 upperRightPosition = new float3(math.max(startPosition.x, endPosition.x),
math.max(startPosition.y, endPositon.y),0); // 获取鼠标框选方框右上角的位置
  • 鼠标在按下和弹起的过程中画出的方框一般存在两种情况
    • 鼠标的起始位置对应左下角,终止位置对应右上角
    • 鼠标按下时的起始位置是右上角,终止位置则是左下角
  • 在计算方框的起始位置为右上角,终止位置为左下角时不能直接用起始位置当方框的左下角,要把终止位置当做方框左下角的位置
  • 想要统一的获得左下角和右上角的位置需要写一些算法,如上方代码所示,这个算法很简单,就是比较起始位置和终止位置,取较小值作为左下角点,然后用两者的较大值作为右上角点
  • 查找被选中的游戏实体
Entities.ForEach((Entity entity, ref Translation translation) => {
								float3 entityPosition = translation.Value;
								if(entityPosition.x >= lowerLeftPosition.x &&
									 entityPosition.y >= lowerLeftPosition.y &&
									 entityPosition.x <= upperRightPosition.x &&
									 entityPosition.y <= upperRightPosition.y){
									 Debug.Log(entity);
								}
						});
  • ForEach方法的作用是遍历每一个游戏单位,后面的Lambda表达式的功能是判断游戏单位的位置坐标是否在鼠标框选范围内,并打印鼠标范围框选范围内的游戏单位

绘制选区

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 在场景中创建一个空节点,起名为SelectionArea(选择区域),再创建一个空子节点,取名为Sprite(精灵节点)
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制
  • 为精灵节点添加精灵渲染器,并选择一张绿色的图片(把白色图片设置成绿色也可以)
  • 这里需要注意一下这张图片的大小
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制
  • 我们为这张图片设置了0.5的偏移值,这是什么意思呢?

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 也就是说SelectionArea(选择区域)节点和Sprite(精灵)节点的位置关系变成了上图的样子,上图中红色坐标轴的原点就是SelectionArea(选择区域)节点的位置,蓝色坐标轴的原点则代表Sprite(精灵)节点的位置,这样偏移以后,将来拖拽、缩放选框时就会以红颜色的中心点为起点,会比较方便
  • 在代码中实现动态绘制选框
public struct UnitSelected : IComponentDate {
}

public class UnitControlSystem : ComponentSystem 
{
		private float3 startPosition;
		protected override void OnUpdate() // OnUpdate与MonoBehaviour中的UPdate一样,游戏运行的每一帧都会执行OnUpdate
		{
				if(Input.GetMouseButtonDown(0)) // 鼠标左键按下时执行的内容
				{
						// Mouse Pressed
						ECS_RTSControls.instance.selectionAreaTransform.gameObject.SetActive(true); // 鼠标按下时激活选区
						startPosition = UnilsClass.GetMouseWorldPosition(); // 记录鼠标按下的位置
						ECS_RTSControls.instance.selectionAreaTransform.position = startPosition; // 设置选取的位置为鼠标按下的位置
				}
				
				if(Input.GetMouseButton(0)) // 鼠标左键按下后,拖拽鼠标时要执行的内容
				{
						// Mouse Held Down
						float3 selectionAreaSize = (float3)UtilsClass.GetMouseWorldPosition() - startPositon; // 获取鼠标绘制出的选区大小
						ECS_RTSControls.instance.selectionAreaTransform.localScale = selectionAreaSize; // 设置选区大小
				}
				
				if(Input.GetMouseButtonUP(0)) //鼠标左键弹起时执行的内容
				{
						// Mouse Released
						ECS_RTSControls.instance.selectionAreaTransform.gameObject.SetActive(false); // 在鼠标抬起时隐藏选区
						float3 endPosition = UnilsCalss.GetMouseWorldPosition(); // 记录鼠标弹起的位置
						
						float3 lowerLeftPosition = new float3(math.min(startPosition.x, endPosition.x),
								math.min(startPosition.y, endPosition.y),0); // 获取鼠标框选方框左下角的位置
						float3 upperRightPosition = new float3(math.max(startPosition.x, endPosition.x),
								math.max(startPosition.y, endPositon.y),0); // 获取鼠标框选方框右上角的位置
						
						Entities.ForEach((Entity entity, ref Translation translation) => {
								float3 entityPosition = translation.Value;
								if(entityPosition.x >= lowerLeftPosition.x &&
									 entityPosition.y >= lowerLeftPosition.y &&
									 entityPosition.x <= upperRightPosition.x &&
									 entityPosition.y <= upperRightPosition.y){
									 PostUpdateCommands.AddComponent(entity, new UnitSelected()); // PostUpdateCommands.AddComponent是ECS里的API,
																																								// 它在这里的功能是为被选中的游戏对象添加UnitSelected组件
							  }
						}); // 遍历所有实体,判断它是否被框选选中
				}
		}
}
  • 注意
    • SelectionArea节点被添加到总控脚本ECS_RTSControls里了,所以在上方代码中是通过访问总控脚本的单例来获取SelectionArea节点
  • 此脚本是在之前的UnitControlSystem脚本上增加了一个类和一些代码
    • 这些代码会在鼠标按下时激活SelectionArea节点,并将SelectionArea节点的位置设置为鼠标按下的位置
    • 在鼠标拖拽过程中会不断获取鼠标当前位置,并用鼠标当前为减去鼠标初始位置,以得到当前鼠标框选的选区大小,然后赋值给selectionArea的localScale,这样就实现了selectionArea选区随着鼠标拖拽自动改变大小的效果
    • 最后在鼠标抬起时会将selectionArea的SetActive设置为false,隐藏鼠标选区,并为被选中的游戏对象添加UnitSelected结构体
  • 效果演示
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

绘制角色脚下的圆圈

public class UnitSelectedRenderer : ComponentSysten
{
		protected override void OnUpdate()
		{
				Entities.WithAll<UnitSelected>().ForEach((ref Translation translation) => { // 通过for循环找到所有带有UnitSelected标记的游戏对象
						float3 position = translation.Value + new float3(0, -3f , +1); // 调低圆圈高度,使它出现在游戏对象脚下
						Graphics.DrawMesh(    
								ECS_RTSControls.instance.unitSelectedCircleMesh, // 通过ECS_RTSControls单例获取圆圈的网格模型
								translation.Value, // 指定圆圈位置为士兵所在的位置
								Quaternion.identity, // 指定旋转为不进行旋转
								ECS_RTSControls.instance.unitSelectedCircleMaterial, // 通过ECS_RTSControls的单例获取圆圈的材质
								0 // 指定要绘制的层
						); // Graphics.DrawMesh是Unity的底层接口,在这里用来绘制游戏角色脚底的圆圈
				});
		}
}
  • 注意
    • 用于绘制角色脚下圆圈的材质添加到了总控脚本ECS_RTSControls里,所以在上方代码中是通过访问总控脚本的单例来获取圆圈的材质的
    • 圆圈的网格模型则是在ECS_RTSControls调用Unity动画的创建网格方法动态创建的,所以也通过ECS_RTSControls的单例获取
  • unitSelectedCircleMaterial(角色选中材质)

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

如果需要项目源码或资源可以在文末通过添加爱丽丝老师的QQ获取

  • 效果演示

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 问题

    • 问题1:无法取消选中
      • 上面的代码在选中了左边的角色后,点击空处或再次选中其他角色时并不会取消之前被选中角色的选中状态,为了要解决这个问题我们添加了几行代码,让UnitControlSystem脚本在鼠标弹起时遍历所有游戏对象,删除它们身上的UnitSelected组件
     if(Input.GetMouseButtonUP(0)) //鼠标左键弹起时执行的内容
     {
          	// Mouse Released
          	ECS_RTSControls.instance.selectionAreaTransform.gameObject.SetActive(false); // 在鼠标抬起时隐藏选区
          	float3 endPosition = UnilsCalss.GetMouseWorldPosition(); // 记录鼠标弹起的位置
          						
          	float3 lowerLeftPosition = new float3(math.min(startPosition.x, endPosition.x),
          			math.min(startPosition.y, endPosition.y),0); // 获取鼠标框选方框左下角的位置
          	float3 upperRightPosition = new float3(math.max(startPosition.x, endPosition.x),
          			math.max(startPosition.y, endPositon.y),0); // 获取鼠标框选方框右上角的位置
          						
          	Entities.WithAll<UnitSelected>().ForEach((Entity entity) => {
          			PostUpdateCommands.RemoveComponent<UnitSelected>(entity);
          	}); // 在鼠标弹起时遍历所有游戏对象,删除它们身上的UnitSelected组件
          						
          	Entities.ForEach((Entity entity, ref Translation translation) => {
          			float3 entityPosition = translation.Value;
          			if(entityPosition.x >= lowerLeftPosition.x &&
          				entityPosition.y >= lowerLeftPosition.y &&
          				entityPosition.x <= upperRightPosition.x &&
          				entityPosition.y <= upperRightPosition.y){
          				PostUpdateCommands.AddComponent(entity, new UnitSelected()); // PostUpdateCommands.AddComponent是ECS里的API,它在这里的功能是为被选中的游戏对象添加UnitSelected组件
          			}
          	}); // 遍历所有实体,判断它是否被框选选中
     }
          ```
          
    
  • 问题2:无法通过点击选中游戏对象

    • 上面代码实现的选中效果必须要把游戏对象整体框入才能选中,但在RTS游戏里,游戏玩家对于单个游戏对象是可以通过点击选中的,而且框选也很麻烦,那怎样才能让它可以点中选中一个对象呢?方法很简单
    • 就是扩大最小选区,选择区域在点击时自动扩大一圈,这样就能确保点击选中单个角色
         float selectionAreaMinSize = 10f; // 鼠标选区最小值
         float selectionAreaSize = math.distance(lowerLeftPosition, upperRightPosition); // 获取当前鼠标选区大小
         if(selectonAreaSize < selectionAreaMainSize) // 检测当前鼠标选区大小是否小于鼠标选区最小值
         {
         		lowerLeftPosition += new float(-1, -1, 0) * (selectionAreaMinSize - selectionAreaSize) * .5f; // 将鼠标选区左下角向下拉伸
         		upperRightPosition += new float(+1, +1, 0) * (selectionAreaMinSize - selectionAreaSize) * .5f; // 将鼠标选区右上角向上拉伸
         }
    
  • 注意:

    • 这些代码会在鼠标抬起时执行,它会检测当前鼠标选区大小是否小于鼠标选区最小值,如果小于则会根据鼠标选区最小值减去当前鼠标选区大小的值放大鼠标选区
  • 这样就保证了最小区域是足够大的,可以通过点击选中游戏单位

让游戏对象向指定的方向移动

if(Input.GetMouseButtonDown(1)) // 在鼠标右键按下时执行的内容
{
		Entities.WithAll<UnitSelected>().ForEach((Entity entity, ref MoveTo moveTo) =>{ 
				moveTo.position = UtilsClass.GetMouseWorldPosition(); // 设置移动目标点
				moveTo.move = true;	// 开始移动
		}); // 查找所有被选中的游戏对象,设置它们的移动目标点并开始移动
}
  • 注意:
    • 这段代码会在鼠标右键抬起时执行,它会为所有被选中的游戏对象设置移动目标点,并使游戏对象向目标点移动
    • MoveTo是一个移动脚本,MoveTo的position代表游戏角色移动的目标点,move代表是否开始移动,如果需要完整的ECS源码资源,可以在添加爱丽丝老师领取
  • 效果演示
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

实现游戏单位按阵列移动

  • 上面实现的效果还有一个问题存在

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 可以看到上面的两个角色变成一个了,因为如果他们的移动目标点是相同的,那么这两个角色在移动时就会重叠起来
if(Input.GetMouseButtonDown(1)) // 在鼠标右键按下时执行的内容
{
		float targetPosition = UtilsClass.GetMouseWorldPosition(); // 获取鼠标点击位置
		List<float3> movePositionList = new List<floa3>
		{
				targetPosition,
				tragetPosition + new float3(10,0,0),
				tragetPosition + new float3(20,0,0),
				tragetPosition + new float3(30,0,0),
		}; // 游戏单位的移动位置列表
		int positionIndex = 0;  // 移动位置列表的位置索引值
		Entities.WithAll<UnitSelected>().ForEach((Entity entity, ref MoveTo moveTo) =>{ 
				moveTo.position = movePositionList[positionIndex]; // 设置移动目标点
				positionIndex = (positionIndex + 1) % movePositionList.Count;
				moveTo.move = true;	// 开始移动
		}); // 查找所有被选中的游戏对象,设置它们的移动目标点并开始移动
}
  • 上面代码中的movePositionList是游戏单位的移动位置列表,当鼠标右键按下设置目标点时,这段代码会遍历所有被选中的游戏单位,并使用positionIndex(位置索引)取出移动位置列表里计算好的移动位置,让这些游戏单位的移动位置都不一样

  • 效果演示
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 可以看到被选中的游戏单位朝着同一个目标点移动,并且位置都各不相同,这是因为目标点在movePositionList经过处理后,产生四个位置不同的坐标点,这样赋值给游戏单位的就是位置不同的坐标点了

  • 这段代码的问题也很明显:当玩家选中四个以上的游戏单位进行移动时,仍然会产生重叠现象

    • 这是因为movePositionList里的元素只有四个,当这段代码遍历完所有元素时,就会从movePositionList的起始位置重新遍历,所以多出来的游戏单位位置会与其他游戏单位重叠
  • 解决这个问题最简单的方法就是增加movePositionList里的元素个数,让元素个数始终大于游戏单位个数,这个问题自然迎刃而解

  • 不过在一些游戏单位数量动辄就是几十、几百上下的RTS游戏中,这种方法就不够看了,需要用另一种方法

private List<float3> GetPositionListAround(float3 position, float distance, int positionCount)
{
		List<float3> positionList = new List<float3>(); // 创建一个float3列表
		for (int i = 0; i < positionCount; i++)
		{
				int angle = i * (360 / positionCount); // 用位置数量除以360以获得第i个位置在圆环上的角度
				float3 dir = ApplyRotationToVector(new float3(0,1,0), angle); 
				float3 position = startPosition + dir * distance; // 通过dir*distance获取长度为distance的向量,然后加上中心位置以得到向量的实际位置
				positionList.Add(position);
		}
		return positionList;
}

private float3 ApplyRotationToVector(float3 vec, float angle)
{
		return Quaternion.Euler(0,0,angle) * vec;
}
  • 上面的GetPositionListAround会返回一个位置列表,位置列表里的所有元素都会以该方法的position参数为圆心,distance为半径呈圆形排列(如下图),这些元素的数量就是positionCount

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • ApplyRotationToVector的作用则是通过传入的角度(angle)来构造旋转值,并使用这个旋转值旋转向量(vec),旋转到了angle所代表的角度,这个方法背后的数学原理,本文就不去细讲了,因为内容很多,如果想要学习这方面的知识,可以在文末添加爱丽丝老师了解
  • 对之前的代码进行修改,使用GetPositionListAround生产位置列表
if(Input.GetMouseButtonDown(1)) // 在鼠标右键按下时执行的内容
{
		float targetPosition = UtilsClass.GetMouseWorldPosition(); // 获取鼠标点击位置

		List<float3> movePositionList = GetPositionListAround(targetPosition, 10, 5); // 游戏单位的移动位置列表

		int positionIndex = 0;  // 移动位置列表的位置索引值
		Entities.WithAll<UnitSelected>().ForEach((Entity entity, ref MoveTo moveTo) =>{ 
				moveTo.position = movePositionList[positionIndex]; // 设置移动目标点
				positionIndex = (positionIndex + 1) % movePositionList.Count;
				moveTo.move = true;	// 开始移动
		}); // 查找所有被选中的游戏对象,设置它们的移动目标点并开始移动
}
  • 效果演示
    Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 由于在上面的代码中GetPositionListAround只指定了5个元素数量,所以重叠的现象依然存在,代码还需要继续改进

private List<float3> GetPositionListAround(float3 startPosition, float[] ringDistance, int[] ringPositionCount)
{
		List<float3> positionList = new List<float3>();
		positionList.Add(startPosition); 
		for (int ring = 0; ring < ringPositionCount.Length; ring++) // 使用for循环根据ringPositionCount元素个数生成圆环
		{
				List<float3> ringPositionList = GetPositionListAround(startPosition, ringDistance[ring], ringPositionCount[ring]); // 使用GetPositionListAround方法生成圆环和圆环上的位置点
				positionList.AddRange(ringPositionList);  // 将已经生成好的圆环放入positionList
		}
		return positionList;
}

private List<float3> GetPositionListAround(float3 position, float distance, int positionCount)
{
		List<float3> positionList = new List<float3>(); // 创建一个float3列表
		for (int i = 0; i < positionCount; i++)
		{
				int angle = i * (360 / positionCount); // 用位置数量除以360以获得第i个位置在圆环上的角度
				float3 dir = ApplyRotationToVector(new float3(0,1,0), angle); 
				float3 position = startPosition + dir * distance; // 通过dir*distance获取长度为distance的向量,然后加上中心位置以得到向量的实际位置
				positionList.Add(position);
		}
		return positionList;
}

private float3 ApplyRotationToVector(float3 vec, float angle)
{
		return Quaternion.Euler(0,0,angle) * vec;
}
  • 最上方的GetPositionListAround是之前写的GetPositionListAround的改进,可以让小兵的位置分布成几个圆环(如下图所示)

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制

  • 新的GetPositionListAround方法的第一个参数startPosition仍然代表圆环中心点的位置,第二个参数ringDistance是半径数组,用于存放所有圆环的半径,第三个参数ringPositionCount代表每一个圆环上的位置点数量
if(Input.GetMouseButtonDown(1)) // 在鼠标右键按下时执行的内容
{
		float targetPosition = UtilsClass.GetMouseWorldPosition(); // 获取鼠标点击位置

		List<float3> movePositionList = GetPositionListAround(targetPosition, new float[] {10f, 20f, 30f}, new int[] {5, 10, 20}); // 游戏单位的移动位置列表

		int positionIndex = 0;  // 移动位置列表的位置索引值
		Entities.WithAll<UnitSelected>().ForEach((Entity entity, ref MoveTo moveTo) =>{ 
				moveTo.position = movePositionList[positionIndex]; // 设置移动目标点
				positionIndex = (positionIndex + 1) % movePositionList.Count;
				moveTo.move = true;	// 开始移动
		}); // 查找所有被选中的游戏对象,设置它们的移动目标点并开始移动
}
  • 效果演示

Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制文章来源地址https://www.toymoban.com/news/detail-410952.html

思考练习

  1. 实现不受位置点数量限制,为每一个游戏单位生成不与其他单位重叠的位置点(因为只要小兵数量超过上面代码中设置的位置点总数,还是会有游戏单位重叠现象)
  2. 兵种遇到障碍能否实现游戏单位躲避障碍行走到目标点(A*,ECS实现)

写在最后

  • 更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
  • 点赞、关注、分享可免费获得配套学习资源
  • 点击观看完整视频

到了这里,关于Unity ECS实现RTS游戏中的游戏单位框选、集结和移动控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用Unity3D制作FPS游戏的学习笔记————人物移动、利用鼠标实现视角转动和人物跳跃(含人物悬空不掉落修复)

    前言: 这是我第一次发布文章,此文章仅供参考,我也是刚学习接触untiy,在制作项目的过程中将有用的写下来记一记,以便自己之后能回头看看,各位大佬轻点喷,若有错误请麻烦积极提谢谢各位。该文章参考自B站UP主蔡先森_rm-rf发布的 【第一人称射击游戏教程2.0【已完结

    2024年04月27日
    浏览(63)
  • 计算机毕设分享 在iOS上使用OpenCV实现图片中的文字框选

    在iOS上使用OpenCV实现图片中的文字框选 提示:适合用于课程设计或毕业设计,工作量达标,源码开放 首先,需要去OpenCV官网下载iOS的framework,下载好后拖入新建的工程中即可,由于OpenCV库是使用C++编写,所以swift无法直接使用,需要使用OC做桥接,需要使用swift的同学可以看

    2024年02月21日
    浏览(50)
  • Unity上接入手柄,手柄控制游戏物体移动

    1、unity软件上安装system input 组件。菜单栏【window】-【Packag Manager】打开如下界面,查找Input System,并且安装。 2、安装成功后插入手柄到windows上,打开菜单栏上【window】--【Analysis】--【Input Debuger】 进入Input Debug界面,可以看到手柄设备能被Unity识别。 3、双击【XinputControllerW

    2024年04月15日
    浏览(48)
  • 最新开源方案!Cocos Creator 写一个ECS框架+行为树,实现格斗游戏 AI

    引言: 实现游戏 AI 的方式有很多,目前最为常用的主要有有限状态机和行为树。和有限状态机相比,行为树有更好的可扩展性和灵活性,能实现更复杂的 AI 需求。开发者  honmono 在 Cocos Creator 中用一个  ECS + BehaviorTree 框架 实现了一个格斗 AI Demo,一起来看看他的方案。 De

    2024年02月12日
    浏览(48)
  • 【UE4 RTS游戏】03-摄像机运动_旋转视角

    可以通过WASD控制“CameraPawn”的移动;通过鼠标中键旋转视角;通过alt+鼠标中键将视角回归默认值;通过shift加速移动。 打开“CameraPawnController”,给如下节点添加注释,命名为“MovementX” 接下来开始开始编辑“MovementY”相关的逻辑 首先从“MovementX”中复制一些节点 新建一

    2024年02月15日
    浏览(32)
  • 【算法】游戏中的学习,使用c#面向对象特性控制游戏角色移动

    最近,小悦的生活像是一首繁忙的交响曲,每天忙得团团转,虽然她的日程安排得满满当当,但她并未感到充实。相反,她很少有时间陪伴家人,这让她感到有些遗憾。在周五的午后,小悦的哥哥突然打来电话,他的声音里充满了焦虑。 “小悦,我有个事情想拜托你。”哥哥

    2024年02月08日
    浏览(53)
  • 顶级工程师教你移动端游戏性能优化!Unity官方教程!

    ** 本期将给大家介绍如何提高资源、项目配置和图形的性能。所有教程均来自Unity官方,感兴趣的朋友可以去Unity官网查看完整教学内容。 降低或禁用 Accelerometer Frequency(加速度计频率) Unity每秒钟是会以一定次数统计移动设备的加速度计状态的。如果我们的程序不会用到加

    2024年02月20日
    浏览(49)
  • 微信小游戏开发之unity-精灵的创建动画和操作移动

    我们的目标是通过unity开发微信小游戏! 这是第一篇正式实战开发文章,将会很详细介绍每一个步骤和代码。 废话不多说直接操作! 由于目标开发游戏是2D小游戏,我们选择2D核心模板. 我们的目标是开发微信小游戏所以我们需要修改setting,选择运行平台选择转换 WebGL ,刚开

    2024年01月16日
    浏览(66)
  • 【unity与android的交互】移动游戏发布更安心!Unity安卓平台打包相关的常见参数全详解

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 首先需要切换到安卓平台 step1 :打包前的基础参数的设置 step2:包名的设置需要勾选,必须要去设置的内容 打包后进行测

    2024年04月17日
    浏览(72)
  • Unity中的物体移动

    局部坐标系(Transform.localPosition)是指当前物体相对于父物体的位置,会受到父物体的影响。 世界坐标系(Transform.Position)是指当前物体在世界空间坐标系中的位置,不受父物体影响。 若该物体有父类,则二者的关系为:该物体的世界坐标=该物体父类的世界坐标+该物体的局

    2024年02月03日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包