Unity3d-解决游戏角色在固定路线地图中行进时遇到各种岔道口时如何自动转向

1》人(任何移动物体)平常行走的每个路点都有两个方向(即:人可以从两个方向到此路点),人通过此路点到下个路点时人的朝向不变,故看起来什么都不需要做,只需要朝前走;

当面对各种路口(类似'L'形状路口有4种,类似'T'形状路口4种,类似''形状路口1种)时需要将人转向:

思路1(交给人脚本来做)人判断是什么样的路口,通过自己的当前朝向再确定自己转向角度(有多个转向角度可以选择时需要选择其中一个)。特点:大量代码放到人这一个脚本。

思路2.(交给路口脚本做)人只需要一直朝前走,路过路口时将自身引用传给路口脚本的函数,路口脚本(每种路口一个脚本)根据自身是什么样的路口和人当前朝向将人的朝向改变;特点:人一个脚本,每种路口各一个脚本共9+1 = 10个脚本。

显然思路2比较好,原因:路口相对于其他普通的路点来说,不同的地方就是可以起到一个转向器的作用;

2》当路点为‘L’型拐角路口时,人到达此路口需要转向为向下一个路点行走做准备,通过此时人的朝向确定旋转的角度。经过此路点的人的朝向只可能有两种,而这两种朝向对应两个转向角度;

3》实现:工具:Unity

此处以'L'形状的路口点为例,'T‘形和'十'形路口介绍主要代码;//下面的代码修改角度可以走斜路

思路:人只要通过射线检测到自己前方有cube就向自己的前方走一步,到达路口时,由路口脚本使人转向

人用红色cube代替,普通路点为白色,‘L’形路口点为蓝色,人行走6步停止,行走前状态如图:

运行时注意设置人的朝向:(人朝向Rotation的y值分别为:下:180或-180 上:0或360 左:270或-90 右:90)

Inspector面板中Rotation的y值设为:180或-180 即朝向下


路过路口后如图:(红色Cube的已经转向,别被看到的箭头迷惑,咱这是Mac版的Unity)


人行走的主要代码:

Player.cs:

public void MoveTo()
	{
		m_stepNum--;                //对行走步数的控制
		if (m_stepNum < 0)
		{
			m_stepNum = 0;
			return;
		}

		RaycastHit hit;
		Physics.Raycast(m_transform.position, m_transform.forward, out hit, 1.2f);//射线检测
		TweenPosition twPos = TweenPosition.Begin(m_transform.gameObject, 0.1f, hit.transform.position);//此方法来自NGUI插件,功能是将m_transform.gameObject在0.1s时间内移动到位置hit.transform.position
		if (hit.transform.GetComponent<WayPointLeftDownCorner>() != null)//WayPointLeftDownCorner.cs是挂在‘L’形路口点上的脚本
		{
			WayPointLeftDownCorner.RotatePlayer(this);//将人本身作为参数,此类方法用来改变人的朝向
		}
		else if (hit.transform.GetComponent<WayPointT2Corner>() != null)//WayPointT2Corner.cs是挂在‘T’形路口点上的脚本
		{
			WayPointT2Corner.RotatePlayer(this);//将人本身作为参数,此类方法用来改变人的朝向
		}
		else if (hit.transform.GetComponent<WayPointCross>() != null)//WayPointCross.cs是挂在'十'形路口点上的脚本
		{
			WayPointCross.RotatePlayer(this);//将人本身作为参数,此类方法用来改变人的朝向
		}

		EventDelegate.Add(twPos.onFinished, MoveTo);//当人移动到下个路点完成后,调用MoveTo(即自身)
	}
WayPointLeftDownCorner.cs://挂在'L‘形路口点上的脚本,其他3种类似

public static void RotatePlayer(Player player)
	{
		if (player.transform.eulerAngles.y < 0)//人朝向下时,player.transform.eulerAngles.y的值180或-180;人朝向左时,值为-90或270
		{
			if (Mathf.Abs(-180 - player.transform.eulerAngles.y) < 0.5f)
			{
				player.transform.eulerAngles += new Vector3(0, -90, 0);
			}
			else if (Mathf.Abs(-90 - player.transform.eulerAngles.y) < 0.5f)
			{
				player.transform.eulerAngles += new Vector3(0, 90, 0);
			}
		}
		else//0~360
		{
			if (Mathf.Abs(180 - player.transform.eulerAngles.y) < 0.5f)
			{
				player.transform.eulerAngles += new Vector3(0, -90, 0);
			}
			else if (Mathf.Abs(270 - player.transform.eulerAngles.y) < 0.5f)
			{
				player.transform.eulerAngles += new Vector3(0, 90, 0);
			}

		}
	}
WayPointT2Corner.cs// 挂在'T‘形路口点上的脚本,其他3种类似

public static void RotatePlayer(Player player)
	{
		if (((player.transform.eulerAngles.y >= 0) && (Mathf.Abs(0 - player.transform.eulerAngles.y) < 0.5f))
		    || ((player.transform.eulerAngles.y < 0) && (Mathf.Abs(0 - player.transform.eulerAngles.y) < 0.5f))
		    || ((player.transform.eulerAngles.y > 0) && (Mathf.Abs(360 - player.transform.eulerAngles.y) < 0.5f)))//人朝向上
		{
			switch (Random.Range(0,2))
			{
			case 0:
				WayPointLeftUpCorner.RotatePlayer(player);//右转
				break;
			case 1:
				WayPointRightUpCorner.RotatePlayer(player);//左转
				break;
			default:
				break;
			}
		}
		else
		{
			if (player.transform.eulerAngles.y < 0 && Mathf.Abs(-90 - player.transform.eulerAngles.y) < 0.5f)//人朝向左
			{
				if (Random.Range(0,2) == 0)
				{
					WayPointLeftUpCorner.RotatePlayer(player);
				}
			}
			else if (player.transform.eulerAngles.y > 0 && Mathf.Abs(270 - player.transform.eulerAngles.y) < 0.5f)//人朝向左
			{
				if (Random.Range(0,2) == 0)
				{
					WayPointLeftUpCorner.RotatePlayer(player);
				}
			}
			else if (player.transform.eulerAngles.y > 0 && Mathf.Abs(90 - player.transform.eulerAngles.y) < 0.5f)//人朝向右
			{
				if (Random.Range(0,2) == 0)
				{
					WayPointRightUpCorner.RotatePlayer(player);
				}
			}
		}
	}
WayPointCross.cs// 挂在'十‘形路口点上的脚本

public static void RotatePlayer(Player player)
	{
		if ((((player.transform.eulerAngles.y >= 0) && (Mathf.Abs(180 - player.transform.eulerAngles.y) < 0.5f))
		    || ((player.transform.eulerAngles.y < 0) && (Mathf.Abs(-180 - player.transform.eulerAngles.y) < 0.5f))))//人朝向下
		{
			switch (Random.Range(0,3))
			{
			case 0:
				WayPointRightDownCorner.RotatePlayer(player);//右转
				break;
			case 1:
				WayPointLeftDownCorner.RotatePlayer(player);//左转
				break;
			case 2:
				break;//直行
			default:
				break;
			}
		}
		else if (((player.transform.eulerAngles.y >= 0) && (Mathf.Abs(270 - player.transform.eulerAngles.y) < 0.5f))
		        || ((player.transform.eulerAngles.y < 0) && (Mathf.Abs(-90 - player.transform.eulerAngles.y) < 0.5f)))//人朝向左
		{
			switch (Random.Range(0,3))
			{
			case 0:
				WayPointLeftUpCorner.RotatePlayer(player);
				break;
			case 1:
				WayPointLeftDownCorner.RotatePlayer(player);
				break;
			case 2:
				break;
			default:
				break;
			}
		}
		else if (((player.transform.eulerAngles.y >= 0) && (Mathf.Abs(0 - player.transform.eulerAngles.y) < 0.5f))
		         || ((player.transform.eulerAngles.y < 0) && (Mathf.Abs(0 - player.transform.eulerAngles.y) < 0.5f))
		         || ((player.transform.eulerAngles.y > 0) && (Mathf.Abs(360 - player.transform.eulerAngles.y) < 0.5f)))//人朝向上
		{
			switch (Random.Range(0,3))
			{
			case 0:
				WayPointLeftUpCorner.RotatePlayer(player);
				break;
			case 1:
				WayPointRightUpCorner.RotatePlayer(player);
				break;
			case 2:
				break;
			default:
				break;
			}
		}
		else if ((player.transform.eulerAngles.y >= 0) && (Mathf.Abs(90 - player.transform.eulerAngles.y) < 0.5f))//人朝向右
		{
			switch (Random.Range(0,3))
			{
			case 0:
				WayPointRightUpCorner.RotatePlayer(player);
				break;
			case 1:
				WayPointRightDownCorner.RotatePlayer(player);
				break;
			case 2:
				break;
			default:
				break;
			}
		}
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值