Unity3d使用鼠标点击控制人物走动无效的问题

Unity3d使用鼠标点击控制人物走动无效的问题

最近在自学Unity3d,在学到使用鼠标点击控制人物走动时,按照API上面将代码写好,如下:

void Update () {

	//	_clickListener.Update();

		if (Input.GetMouseButtonUp (0)) {
  
			ClickOn(Input.mousePosition);
		}

	}

void ClickOn(Vector2 pos)
	{
		if (player == null)
			return;
		Ray ray = this.GetComponent<Camera>().ScreenPointToRay(pos);
		RaycastHit[] hits = Physics.RaycastAll(ray);

	
		foreach (RaycastHit hit in hits){
			BoxCollider bc = hit.collider as BoxCollider;
            Debug.Log("bc.name is " + bc.name);
            Debug.Log("bc.name is Contains floor  " + bc.name.Contains("floor"));
			if (bc != null && bc.name.Contains("floor") && player != null){
             
			player.GetComponent<Player>().WalkTo(hit.point);
				break;
			}
		}
	}

检查下,没什么错误,Unity3d,点击运行,满以为接下来可以美滋滋的用鼠标控制人物走动了,想想还有点小激动呢!结果点击鼠标,毫无响应!!!!

what fuck?

代码咋回事?写错了吗,于是又反复的检查了一下代码,确认是没问题的。代码既然是没问题,但是又没有达到相应的功能,到底怎么回事呢?

遇到这样的情况第一想到的是肯定是有哪段代码没有执行,从以上代码来看,只有3个地方涉及到了判断逻辑,分别是:if (Input.GetMouseButtonUp (0)) 和foreach (RaycastHit hit in hits) 以及 if (bc != null && bc.name.Contains(“floor”) && player != null)。

先说第一个if (Input.GetMouseButtonUp (0)) :
这是用来判断是否点击了鼠标左键的判断,如果鼠标左键被点击,那么Input.GetMouseButtonUp (0)返回的则是true;
在以上的代码上的对应地方加上打印,最终代码如下:

if (Input.GetMouseButtonUp (0)) {
            Debug.Log("the Mouse button has been press");
			ClickOn(Input.mousePosition);
		}

OK,运行,鼠标左键点击,发现Unity控制台打印为:
在这里插入图片描述
确实收到了鼠标的点击事件,那么确认第一个判断正确的可以pass掉,接下来看第二个逻辑foreach (RaycastHit hit in hits)
这句逻辑是用从射线碰撞点的数组中(具体可以百度)进行遍历的数组,在foreach (RaycastHit hit in hits) 里面加个打印,如下:

foreach (RaycastHit hit in hits){
            Debug.Log("hits has been in ");
			BoxCollider bc = hit.collider as BoxCollider;
          
            Debug.Log("bc.name is Contains floor  " + bc.name.Contains("floor"));
			if (bc != null && bc.name.Contains("floor") && player != null){
             
			player.GetComponent<Player>().WalkTo(hit.point);
				break;
			}
		}

运行,没有执行打印。所以说明foreach语句里面的循环没有被执行,所以说明hits的数组长度为0.
再看:

   Ray ray = this.GetComponent<Camera>().ScreenPointToRay(pos);
    		RaycastHit[] hits = Physics.RaycastAll(ray);

如果hits长度为0,则只能说明 Physics.RaycastAll(ray);拿到的数据为空。
为什么这句会拿到空,首先了解Physics.RaycastAll(ray)该方法return一个数组。ray代表射线,即拿到射线上的所有碰撞点,如果获取的数组为0.则毫无意义是因为没有碰撞器造成的。
搞明白这个问题后,继续回去检查GameObject的Component看有没有添加碰撞器。果然还没加,是这样的:

在这里插入图片描述
没有加就加一个,点击“Add Component” 加一个,如下图:

在这里插入图片描述
添加好之后,保存。继续运行,点击鼠标还是不动。。。。,几乎要放弃的,但是程序员有程序员的倔强。之前两个都解决了,所以再检查第三个 if (bc != null && bc.name.Contains(“floor”) && player != null),继续加Debug日志,发现bc.name.Contains(“floor”)这一句一直返回false,说明碰撞点的对象名字不包含"floor"。找到对应的gameObject,如下图:
在这里插入图片描述
默认的名字都不含有"floor",好吧 改名字呗!不用全部改,只用将地板的模型gameObject改成含有"floor"即可,比如我的,就只改了3个:
在这里插入图片描述
改完之后,运行,完美,可以走动了!
在这里插入图片描述

在这里插入图片描述
第一次写CSDN还不会传动态度,呵呵!
最后说一下,这些素材的都是从网上下载下来导入到工程里面的,里面很多默认的东西没有创建或改名,刚学习接触Unity3d,跟着教程视频,视频讲解老师略过了一些步骤后,就会发现自己没法实现视频上的效果,唉。。。没基础就是不行,好在有因为有其他编程语言的基础,有程序员的职业技能,哈哈,不错就是调试。emmm,仅以此文献给在编程领域摸滚打爬的程序员们,共勉!!!

猜你喜欢

转载自blog.csdn.net/qq_34888164/article/details/89213972