您现在的位置是:首页 >其他 >【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】网站首页其他

【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】

布鲁布鲁吐泡泡 2023-05-20 16:00:02
简介【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】

参考:极客学院unity3d教程

输入

inputManager

在这里插入图片描述

Horizontal虚拟轴的各个属性含义(摘选自ChatGpt,部分回答不准确)

  • Name:虚拟轴的名称,用于在代码中访问该虚拟轴。这个名称应该是唯一的,用于区分其他虚拟轴。
  • Descriptive Name:描述虚拟轴的名称,用于在Inspector中显示。这个名称通常是用户友好的,例如"水平轴"、"左右方向"等。
  • Negative Button:定义一个负向按钮,按下这个按钮将使轴值变为负数。这个按钮可以是Unity中默认定义的按键(例如左箭头键、A键等),也可以是用户自定义的按键。如果不需要负向按钮,可以将其留空。
  • Positive Button:定义一个正向按钮,按下这个按钮将使轴值变为正数。同样,这个按钮可以是默认定义的按键或者自定义的按键。如果不需要正向按钮,可以将其留空。
  • Alt Negative Button:定义一个替代的负向按钮。如果定义了这个按钮,当Negative Button按钮没有被按下时,按下这个替代按钮也可以使轴值变为负数。如果不需要替代按钮,可以将其留空。
  • Alt Positive Button:定义一个替代的正向按钮。同样,当Positive Button按钮没有被按下时,按下这个替代按钮也可以使轴值变为正数。如果不需要替代按钮,可以将其留空。
  • Gravity:轴值的“重力”,表示轴值在没有按下按钮时逐渐趋向于0的速度。例如,如果Gravity属性设置为1,则当没有按下任何控制键时,轴值每秒钟会减少1。这可以使物体在没有输入时自然地停下来。如果Gravity属性设置为0,则轴值将永远不会自动返回0。

在这里插入图片描述

  • Dead:死区,当轴值的绝对值小于这个值时,轴值将被认为是0。死区通常用于解决输入设备的精度问题,可以消除轻微的移动或震动对轴值的影响。
  • Sensitivity:轴值的灵敏度,用于控制轴值的变化速度。例如,如果Sensitivity属性设置为2,则每按下一次控制键,轴值将增加2,而不是1。这可以使物体的移动更快或更缓慢。

在这里插入图片描述

  • Snap:如果勾选,存在一个反方向的输入,则会跳到中点并再沿这个反方向移动;如果不勾选,则不存在一个跳变(snap)的过程。例如人物移动,可以勾选,但赛车类游戏则可以不勾选。
    float axisX;

    // Update is called once per frame
    void Update()
    {
        axisX = Input.GetAxis("Horizontal");
        this.transform.position = new Vector3(axisX*2,1,0);
    }

在这里插入图片描述

键值的含义

用的chatgpt回答的…
在这里插入图片描述
md google is dead
在这里插入图片描述

键名称命名约定:

键系列命名约定
字母键a, b, c…
数字键1, 2, 3…
箭头键up, down, left, right
小键盘按键[1], [2], [3], [+], [equals]…
修饰键right shift, left shift, right ctrl, left ctrl, right alt, left alt, right cmd, left cmd
特殊键backspace, tab, return, escape, space, delete, enter, insert, home, end, page up, page down
功能键f1, f2, f3…

我这里插一句,这里可以让chatgpt把表格内容生成markdown形式,但由于浏览器会直接渲染成表格,无法复制源文本,可以让它用代码格式展示答案:
在这里插入图片描述

键盘输入

官网API

静态函数

GetKey

public static bool GetKey (string name); 在用户按下 name 标识的键时返回 true。

Input.GetKey("up")
GetButton

public static bool GetButton (string buttonName); bool 当按下并且未释放轴时,返回 true。(需要输入管理器进行控制)

Input.GetButton("Fire1")
KeyCode

KeyCode其中列出了所有的按键、鼠标和游戏杆选项 (属于Enum)
包含内容参考官方 API

    bool key;

    // Update is called once per frame
    void Update()
    {
        // key = Input.GetKey(KeyCode.Space);
        // key = Input.GetKey("space");
        key = Input.GetButton("Jump");
        if(key)
        transform.localScale = new Vector3(2,2,2);
        else
        transform.localScale = new Vector3(1,1,1);
    }

在这里插入图片描述

GetButton/Down/up

GetButton 当按住 buttonName 标识的虚拟按钮时,返回 true。
GetButtonDown 在用户按下由 buttonName 标识的虚拟按钮的帧期间返回 true。
GetButtonUp 在用户释放由 buttonName 标识的虚拟按钮的第一帧返回 true。
在这里插入图片描述

GetAxis

返回由 axisName 标识的虚拟轴的值。

对于键盘和游戏杆输入设备,该值将处于 -1…1 的范围内。

该值的含义取决于输入控制的类型,例如,对于游戏杆的水平轴,值为 1 表示游戏杆向右推到底,值为 -1 表示游戏杆向左推到底;值为 0 表示游戏杆处于中性位置。

如果将轴映射到鼠标,该值会有所不同,并且不会在 -1…1 的范围内。此时,该值为当前鼠标增量乘以轴灵敏度。通常,正值表示鼠标向右/向下移动,负值表示鼠标向左/向上移动。

该值与帧率无关;使用该值时,您无需担心帧率变化问题。

    float axisX;
    float axisY;

    // Update is called once per frame
    void Update()
    {
        axisX = Input.GetAxis("Horizontal");
        axisY = Input.GetAxis("Vertical");
        this.transform.position = new Vector3(axisX*2,axisY*2,0);
    }

在这里插入图片描述

GetAxisRaw 返回由 axisName 标识的虚拟轴的值(未应用平滑过滤)。

对于键盘和游戏杆输入,该值将处于 -1…1 的范围内。 由于未对输入进行平滑处理,键盘输入将始终为 -1、0 或 1。 如果您想自己完成键盘输入的所有平滑处理,这非常有用。

鼠标输入与控制

OnMouseDown (继承自MonoBehavior)

在这里插入图片描述

        Rigidbody rigidbody;
    private void OnMouseDown() {
        rigidbody =  this.GetComponent<Rigidbody>();
        rigidbody.useGravity = true;
        rigidbody.isKinematic = false;
        rigidbody.AddForce(-Vector3.forward*10f,ForceMode.Impulse);
        Debug.Log("OnMouseDown");
    }

在这里插入图片描述

Physics.Raycast

public static bool Raycast (Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask, QueryTriggerInteraction queryTriggerInteraction);
返回 bool 当光线与任何碰撞体相交时,返回 true,否则返回 false。

也可以输入一个Ray类 Ray myRay = new Ray(vector3 origin,Vector3 direction);
Physics.Raycast(myRay,RaycastHit hitInfo,float distance,int LayerMask);

参数
  • origin 射线在世界坐标系中的起点。
  • direction 射线的方向。
  • hitInfo 如果返回 true,则 hitInfo 将包含有关最近的碰撞体的命中位置的更多信息。(另请参阅:RaycastHit)。
  • maxDistance 射线应检查碰撞的最大距离。
  • layerMask 层遮罩,用于在投射射线时有选择地忽略碰撞体。
  • queryTriggerInteraction 指定该查询是否应该命中触发器。
描述

向场景中的所有碰撞体投射一条射线,该射线起点为 origin,朝向 direction,长度为 maxDistance

您可以选择提供一个 LayerMask,以过滤掉不想生成与其碰撞的碰撞体。

您可以通过指定 queryTriggerInteraction 来控制是让触发碰撞体生成命中效果,还是使用全局 Physics.queriesHitTriggers 设置。
在这里插入图片描述

实例1 ray检测实现坠落开伞

目标:物体自由降落,当距离地面一定距离时,打开降落伞(没学动画,用active代替),并减速,到达地面收起降落伞。

   public GameObject parachute;//降落伞
    bool deployed =false;//默认降落伞折叠
    public float rayDistance = 4;//射线检测距离
    public float dragValue = 6f;//降落伞阻力
    void Awake()
    {
        parachute.SetActive(false);
    }
    void Update()
    {
        Ray testRay = new Ray(transform.position,Vector3.down);
        RaycastHit hitInfomation;
        if(!deployed){
            if(Physics.Raycast(testRay,out hitInfomation,rayDistance)){
                Deploy();
            }
        }
    }
    void Deploy(){
        deployed = true;
        GetComponent<Rigidbody>().drag = dragValue;
        parachute.SetActive(true);
    }
    void OnCollisionEnter(Collision other) {
        parachute.SetActive(false);
    }

在这里插入图片描述
最终效果
注意事项:

  • rigidBody已过时,用GetComponent< Rigidbody>()代替
  • child绑定到cube
实例2 利用ray实现鼠标点击检测
public Camera mCamera;

    // Update is called once per frame
    void Update()
    {
        // 检测鼠标按下,0左键,1右键,2中键
        if(!Input.GetMouseButtonDown(0)){
            return;
        }
        // Input.mousePosition鼠标的位置信息,左下角(0,0,0)
        // Space空间类型:world space、screen space、viewport space
        // 将screen坐标转换成世界坐标的射线
        Ray r = mCamera.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if(Physics.Raycast(r,out hit,1000f))
        {
            if(hit.collider.tag == "c1"){
               Debug.Log("点击上喽") ;
            }
        }
    }

效果跟之前OnMouseDown差不多

实例3 鼠标拖动场景物体
public Camera mCamera;
    private void OnMouseEnter() {
        transform.localScale = new Vector3(
            transform.localScale.x*1.5f,
            transform.localScale.y*1.5f,
            transform.localScale.z*1.5f
            );
    }
    private void OnMouseExit() {
        transform.localScale = new Vector3(
            transform.localScale.x/1.5f,
            transform.localScale.y/1.5f,
            transform.localScale.z/1.5f
            );
    }
    private void OnMouseOver() {
        transform.Rotate(Vector3.up,45*Time.deltaTime,Space.Self);
    }
    private void OnMouseDrag() {
        moveObject();
    }
    void moveObject(){
        Ray r = mCamera.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if(Physics.Raycast(r,out hit,1000f)){
            this.transform.position = new Vector3(
                hit.point.x,
                hit.point.y,
                hit.point.z
                );
        }
        Debug.DrawLine(r.origin,hit.point);
    }

如下图所示,能实现鼠标enter变大 离开变小 over旋转,但并没有想要drag效果,因为Raycast也会见到到cube本身,所以可以添加mask,排除cube
在这里插入图片描述

// 改用包含mask的Raycast方法
if(Physics.Raycast(r,out hit,1000f,1)){
            this.transform.position = new Vector3(
                hit.point.x,
                hit.point.y+0.5f,
                hit.point.z
                );
        }

在这里插入图片描述
还可以固定cube景深

void moveObjectFixDepth(){
        Vector3 mouseScreen = Input.mousePosition;
        mouseScreen.z = depth;
        Vector3 mouseWorld = mCamera.ScreenToWorldPoint(mouseScreen);
        this.transform.position = mouseWorld;
    }

其他输入

如遥感、触屏省略
还有input system package好像,以后遇到再补充吧

小结

耗时两天,中间两天没学习,忙着玩青藤,心有些浮躁,自我批评下。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。