(102)A* Pathfinding Project Pro(Aron Granberg):控制物体移动时,角色行走在不可行走区域的bug

  1. 如图,通过OnPathDelegate回调获得Path,然后在 update 里面,通过调用 SeekFunc,角色行走在不可行走区域(绿色区域),直接穿过去了,没有沿可行走路径移动:
    在这里插入图片描述

  2. 问题代码:

    public void SeekFunc()
    {	
    	if (path==null)
    	{
    		stateMachine.SwitchState((int)PlayerStateEnum.Idle);
    		Debug.Log($"path=========null, state={stateMachine.PlayerController.PlayerStateEnum}", stateMachine.PlayerController.gameObject);
    		return;
    	}
    
    	try
    	{
    		...		
    		Vector3 currentPos = stateMachine.PlayerController.transform.position;
    		Vector3 targetWaypoint = path.vectorPath[currentPoint];
    
    		// 计算剩余路径距离
    		float remainingDistance = 0;
    		for (int i = currentPoint; i < path.vectorPath.Count - 1; i++)
    		{
    			remainingDistance += Vector3.Distance(path.vectorPath[i], path.vectorPath[i + 1]);
    		}
    		remainingDistance += Vector3.Distance(currentPos, targetWaypoint);
    
    		// 计算移动方向和距离
    		Vector3 moveDir = (targetWaypoint - currentPos).normalized;
    		float playerSpeed = stateMachine.PlayerController.MoveSpeed;
    		Vector3 rvoTarget = currentPos + moveDir * remainingDistance;
    		
    		// for (int i = currentPoint; i < path.vectorPath.Count - 2; i++)
    		// {
    		//     Debug.DrawLine(path.vectorPath[i], path.vectorPath[i + 1],Color.red);
    		// }
    		
    		// 设置RVO目标
    		rvoController.SetTarget(rvoTarget, playerSpeed, playerSpeed);
    
    		// 应用RVO计算的移动
    		Vector3 movementDelta = rvoController.CalculateMovementDelta(Time.deltaTime);
    		stateMachine.PlayerController.transform.position += movementDelta;
    
    		// 更新朝向
    		if (movementDelta.magnitude > 0.01f)
    		{
    			var scale = stateMachine.PlayerController.Root.localScale;
    			
    			// 计算当前移动方向在等轴视角下的"水平"分量
    			float adjustedX = movementDelta.x - movementDelta.z;
    			
    			// 保存当前朝向状态(1为右,-1为左)
    			int currentDirection = scale.x > 0 ? 1 : -1;
    			
    			// 只有当变化足够明显时才改变方向
    			float threshold = 0.03f; // 调整阈值大小控制朝向切换灵敏度
    			
    			// 若当前方向与移动方向不一致,且差异显著,才切换方向
    			if ((currentDirection > 0 && adjustedX < -threshold) || 
    				(currentDirection < 0 && adjustedX > threshold))
    			{
    				// 方向明显不同,切换朝向
    				scale.x = Mathf.Abs(scale.x) * (adjustedX > 0 ? 1 : -1);
    				stateMachine.PlayerController.Root.localScale = scale;
    			}
    		}
    
    		// 检查是否到达当前路径点
    		float moveNextDist = 1f;
    		if (Vector3.Distance(currentPos, targetWaypoint) < moveNextDist)
    		{
    			currentPoint++;
    		}
    	}
    	catch (Exception e)
    	{
    		// Debug.LogError(e);
    		stateMachine.SwitchState((int)PlayerStateEnum.Idle);
    	}
    }
    
  3. 解决,将 moveNextDist 改小为 0.1。

float moveNextDist = 0.1f;
if (Vector3.Distance(currentPos, targetWaypoint) < moveNextDist)
{
currentPoint++;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值