2019-04-11 16:29:30 qq_34888164 阅读数 127
  • 老孙的游戏课:第2篇 人机交互

    本课是“老孙游戏课”系列课程的第2篇,该课程重点介绍Unity中的人机交互功能,以游戏实例为背景,深入浅出地讲解键盘操作、鼠标操作、碰撞检测、血条制作等多个游戏中常用的交互变换功能。

    12 人正在学习 去看看 孙博文

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,仅以此文献给在编程领域摸滚打爬的程序员们,共勉!!!

2013-07-20 14:59:28 a2587539515 阅读数 3218
  • 老孙的游戏课:第2篇 人机交互

    本课是“老孙游戏课”系列课程的第2篇,该课程重点介绍Unity中的人机交互功能,以游戏实例为背景,深入浅出地讲解键盘操作、鼠标操作、碰撞检测、血条制作等多个游戏中常用的交互变换功能。

    12 人正在学习 去看看 孙博文

账号被盗,文章被修改,博主已将博文删除

2016-12-16 10:59:22 KathyKarol 阅读数 1835
  • 老孙的游戏课:第2篇 人机交互

    本课是“老孙游戏课”系列课程的第2篇,该课程重点介绍Unity中的人机交互功能,以游戏实例为背景,深入浅出地讲解键盘操作、鼠标操作、碰撞检测、血条制作等多个游戏中常用的交互变换功能。

    12 人正在学习 去看看 孙博文

 作为一个新人,我也来发表一篇文章,大早上的通过unity3d来给大家分享一下我自己做的小demo;


首先获取鼠标在屏幕上点击的那个点的坐标,在这里要用到input类中的MouseButtonDown()这个方法来获得鼠标的左键,右键已经滚轮的点击反应。

今天我们就用左键吧,在MouseButtonDown()这个方法里,使用参数0来表示按下左键,;使用MouseButtonUp(0)方法来表示释放左键,因为在屏幕

中是要拖动的,所以需要持续按下鼠标的函数GetMouseButton(0);这三个函数我们都放在Update里面执行;




在这里我们使用unity自带的画图类库来对鼠标点击并且拖动形成的范围进行画图,我们使用类GL中的一些方法,如PushMatrix()、LoadPixelMatrix(),以及开始画图的点和结束画图的点的函数,在这里就不一一介绍啦,待会直接上传代码就好了。


当鼠标点击拖动,形成的区域肯定是矩形,所以这边涉及上下左右边框的计算,我们使用一个材质来表示,


最后,当鼠标左键施放之后,所形成的区域就在屏幕中释放,我们使用GL中的PopMatrix()函数来表示结束;


下面是我这个demo的源代码,给大家分享一下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class GetRange : MonoBehaviour {


    private Vector2 mouseStartPos, mouseEndPos;
    private bool mBDrawMouseRect;


    public Material rectMat;//画线的材质


    void Start()
    {
        mBDrawMouseRect = false;
    }


    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        //按下鼠标左键  
        {
            Vector3 mousePosition = Input.mousePosition;
            mouseStartPos = new Vector2(mousePosition.x, mousePosition.y);
        }


        if (Input.GetMouseButton(0))
        //持续按下鼠标左键  
        {
            mBDrawMouseRect = true;
            Vector3 mousePosition = Input.mousePosition;
            mouseEndPos = new Vector2(mousePosition.x, mousePosition.y);
        }


        if (Input.GetMouseButtonUp(0))
        {
            mBDrawMouseRect = false;
        }
    }


    void OnGUI()
    {
        if (mBDrawMouseRect)
            Draw(mouseStartPos, mouseEndPos);
        GUILayout.Label("X:"+Input.mousePosition.x);
        GUILayout.Label("Y:" + Input.mousePosition.y);
    }


    //渲染2D框  
    void Draw(Vector2 start, Vector2 end)
    {
        rectMat.SetPass(0);
        


        GL.PushMatrix();//保存摄像机变换矩阵  


        Color clr = Color.green;
        clr.a = 0.1f;


        GL.LoadPixelMatrix();//设置用屏幕坐标绘图  
                             //透明框  
        GL.Begin(GL.QUADS);
        GL.Color(clr);
        GL.Vertex3(start.x, start.y, 0);
        GL.Vertex3(end.x, start.y, 0);
        GL.Vertex3(end.x, end.y, 0);
        GL.Vertex3(start.x, end.y, 0);
        GL.End();


        //线  
        //上  
        GL.Begin(GL.LINES);
        GL.Color(Color.green);
        GL.Vertex3(start.x, start.y, 0);
        GL.Vertex3(end.x, start.y, 0);
        GL.End();


        //下  
        GL.Begin(GL.LINES);
        GL.Color(Color.green);
        GL.Vertex3(start.x, end.y, 0);
        GL.Vertex3(end.x, end.y, 0);
        GL.End();


        //左  
        GL.Begin(GL.LINES);
        GL.Color(Color.green);
        GL.Vertex3(start.x, start.y, 0);
        GL.Vertex3(start.x, end.y, 0);
        GL.End();


        //右  
        GL.Begin(GL.LINES);
        GL.Color(Color.green);
        GL.Vertex3(end.x, start.y, 0);
        GL.Vertex3(end.x, end.y, 0);
        GL.End();


        GL.PopMatrix();//还原  
    }


}

2014-10-23 11:02:54 Tonny_007 阅读数 5794
  • 老孙的游戏课:第2篇 人机交互

    本课是“老孙游戏课”系列课程的第2篇,该课程重点介绍Unity中的人机交互功能,以游戏实例为背景,深入浅出地讲解键盘操作、鼠标操作、碰撞检测、血条制作等多个游戏中常用的交互变换功能。

    12 人正在学习 去看看 孙博文

Unity3d本身并不能设置鼠标的位置,需要依赖系统库,最近在做MAC平台的开发,MAC下得方法还没找到,但是在windows下得方法如下:

//引用系统库

    [DllImport("User32")]
    private static extern bool SetCursorPos(int xint y);
    [DllImport("User32")]

    private static extern bool GetCursorPos(out POINT pt);


        if (Input.GetMouseButton(1)/* && !Input.GetMouseButton(0)*/)
        {

            if (Input.GetMouseButtonDown(1))
            {
                POINT pt;

                GetCursorPos(out pt);

                lastMouseX = pt.X;
                lastMouseY = pt.Y;

                Input.mousePosition{ }
            }

            //Screen.lockCursor = true;
            Screen.showCursor = false;
            SetCursorPos(lastMouseXlastMouseY);
         

//改变视角
            x += Input.GetAxis("Mouse X") * speed.x * 0.02f;
            y -= Input.GetAxis("Mouse Y") * speed.y * 0.02f;
            y = ClampAngle(yyMinLimityMaxLimit);
        }


2019-05-15 16:13:10 q764424567 阅读数 2285
  • 老孙的游戏课:第2篇 人机交互

    本课是“老孙游戏课”系列课程的第2篇,该课程重点介绍Unity中的人机交互功能,以游戏实例为背景,深入浅出地讲解键盘操作、鼠标操作、碰撞检测、血条制作等多个游戏中常用的交互变换功能。

    12 人正在学习 去看看 孙博文

一、前言

以前转载了一篇关于在Unity3d中鼠标控制物体的旋转、移动、缩放的代码
然后发现错误比较多,就重新写了一个代码,自我感觉简单实用。。。特意分享出来供大家参考
原文章也贴出来吧
【Unity3d 鼠标滚动拉近模型、鼠标右键旋转模型、鼠标中键拖拽模型】
https://blog.csdn.net/q764424567/article/details/78630649

效果图:
在这里插入图片描述

二、知识点

  • Input.GetMouseButton(0)
    获取鼠标输入,参数为一个int值
    为0的时候获取的是左键

  • Input.GetMouseButton(1)
    为1的时候获取的是右键

  • Input.GetMouseButton(2)
    为2的时候获取的是中键(就是那个滑轮)

  • Input.GetMouseButton
    鼠标按压

  • Input.GetMouseButtonUp
    鼠标点击

  • Input.GetMouseButtonDown
    鼠标松开

  • Camera.main.ScreenToWorldPoint
    屏幕坐标转化为世界坐标

  • Quaternion rotation = Quaternion.Euler(0, 0, 0);
    欧拉角转化为四元数

三、代码分享

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseControlModel : MonoBehaviour
{
    //旋转最大角度
    public int yMinLimit = -20;
    public int yMaxLimit = 80;
    //旋转速度
    public float xSpeed = 250.0f;
    public float ySpeed = 120.0f;
    //旋转角度
    private float x = 0.0f;
    private float y = 0.0f;

    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            //将屏幕坐标转化为世界坐标  ScreenToWorldPoint函数的z轴不能为0,不然返回摄像机的位置,而Input.mousePosition的z轴为0
            //z轴设成10的原因是摄像机坐标是(0,0,-10),而物体的坐标是(0,0,0),所以加上10,正好是转化后物体跟摄像机的距离
            Vector3 temp = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10));
            transform.position = temp;
        }
        else if (Input.GetMouseButton(1))
        {
            //Input.GetAxis("MouseX")获取鼠标移动的X轴的距离
            x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
            y = ClampAngle(y, yMinLimit, yMaxLimit);
            //欧拉角转化为四元数
            Quaternion rotation = Quaternion.Euler(y, x, 0);
            transform.rotation = rotation;
        }
        else if (Input.GetAxis("Mouse ScrollWheel") != 0)
        {
            //鼠标滚动滑轮 值就会变化
            if (Input.GetAxis("Mouse ScrollWheel") < 0)
            {
                //范围值限定
                if (Camera.main.fieldOfView <= 100)
                    Camera.main.fieldOfView += 2;
                if (Camera.main.orthographicSize <= 20)
                    Camera.main.orthographicSize += 0.5F;
            }
            //Zoom in  
            if (Input.GetAxis("Mouse ScrollWheel") > 0)
            {
                //范围值限定
                if (Camera.main.fieldOfView > 2)
                    Camera.main.fieldOfView -= 2;
                if (Camera.main.orthographicSize >= 1)
                    Camera.main.orthographicSize -= 0.5F;
            }
        }
    }

    //角度范围值限定
    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }
}

谢谢大家!

Unity获取系统鼠标

阅读数 428

unity获取系统鼠标

博文 来自: qq_34678199
没有更多推荐了,返回首页