unity3d入门教程五

unity3d入门教程五

13鼠标事件处理

需要好好学习,不然一些有趣的操作就无法实现了

鼠标跟随

飞机飞行的方向会根据鼠标进行移动,鼠标移到哪,飞机就朝哪飞

在B站没有发布此相关视频,需要去网盘中寻找

在 Update() 里,可以探测鼠标事件

复制代码
if(Input.GetMouseButtonDown(0))
{  
  Debug.Log("鼠标按下" + Input.mousePosition);      
}
其中,0代表左键,1为右键,2为中键 (滚轮) 
           Input.mousePosition 代表此时鼠标的位置 ( 屏幕坐标 )


注意区分事件和状态是不同的,如鼠标按下不同,BUTTONDOWN事件只触发一次,只打印一次,而BUTTN状态是一直被触发,显示是否一直按着的状态的。

区分:

复制代码
Input.GetMouseButtonDown(0)  检查鼠标按下事件
Input.GetMouseButtonUp(0)      检查鼠标抬起事件
Input.GetMouseButton(0)           检查鼠标状态 ( 是否是按下状态 )

其中,Input.GetMouseButtonDown(0) 事件不会重复触发

验证:保持鼠标一直按下,观察打印输出。。


鼠标的位置 Input.mousePosition

屏幕坐标  世界坐标

示例:

复制代码
 Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 Debug.Log("世界坐标: " + pos);
 pos.z = 0;    // 把Z坐标置0,放到2D平面上来

13.2鼠标跟随

飞机自动调整前进的方向,使其自动朝着鼠标所在的方向进行追随

当鼠标按下时,可以控制飞机转向,而鼠标抬起就不控制了

后期还是有很多优化的,你可以让它有渐变的效果,让一开始转头的时候不至于太过于突兀

所有代码如下

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class gensui : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {

        // 检查 '当前鼠标左键是否按下' ,此为状态检查
        if (Input.GetMouseButton(0))
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来

            // 控制机头的指向
            SetDirection(pos);
        }

        float step = 1.2f * Time.deltaTime;
        transform.Translate(0, step, 0, Space.Self);
    }

    void SetDirection(Vector3 targetPos)
    {
        Vector3 face = transform.up; // 头部指向
        Vector3 direction = targetPos - transform.position;

        // 参考第11,12章
        float angle = Vector3.SignedAngle(face, direction, Vector3.forward);
        transform.Rotate(0, 0, angle);
    }
}

13.3鼠标拖拽(选中对象,拖动对象)

运行后通过鼠标可以拖拽物体

第一层优化代码如下:

此处效果是,不点击飞机,在平面任意位置点击,飞机会直接出现在鼠标的位置,按住移动鼠标,飞机也会跟着移动

有问题,没有按住飞机,它跳过来了

复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Reporting;
using UnityEngine;
using UnityEngine.UIElements;

public class MyJet : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {

        // 检查 '当前鼠标左键是否按下' ,此为状态检查
        if ( Input.GetMouseButton(0) )
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来


            transform.position = pos;

        }

    } 

}

第二层优化

对上方是否选中飞机进行判断,判断按下鼠标的坐标与飞机中心坐标的距离,处于范围内则是选中飞机了,鼠标只要抬起选中状态就为false

效果:虽然只有在点击飞机的时候才会选中移动,但是当点击与飞机中心有一定距离时会跳一下,飞机中心会瞬移到鼠标所在位置。

我们应该记住鼠标位置,进行相对一定,鼠标移动的距离其再一定这一定距离

复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Reporting;
using UnityEngine;
using UnityEngine.UIElements;

public class MyJet : MonoBehaviour
{
    private bool drag = false;//此为选中状态,处于选中择为TRUE,否则false
 
    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        if ( Input.GetMouseButtonDown(0) )
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来

            float distance = (pos - transform.position).magnitude;
            if(distance < 1.5f)
            {
                drag = true;
                
            }
        }

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


        // 检查 '当前鼠标左键是否按下' ,此为状态检查
        if ( drag )
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来


            transform.position = pos;

        }

    }

}

第三层优化

进行更精细的操作,记录鼠标的位置,根据鼠标的相对位移进行计算

飞机的位置,鼠标移动的相对位置,飞机之前的位置加上鼠标相对位置得到飞机移动位置,并且再次更新飞机上次位置。

此时的效果,点击飞机时就不会突然跳动一下了

代码如下:

复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Build.Reporting;
using UnityEngine;
using UnityEngine.UIElements;

public class MyJet : MonoBehaviour
{
    private bool drag = false;
    private Vector3 lastMousePos;

    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        if ( Input.GetMouseButtonDown(0) )
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来

            float distance = (pos - transform.position).magnitude;
            if(distance < 1.5f)
            {
                drag = true;
                lastMousePos = pos;
            }
        }

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


        // 检查 '当前鼠标左键是否按下' ,此为状态检查
        if ( drag )
        {
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            pos.z = 0;    // 把Z坐标置0,放到2D平面上来

            Vector3 delta = pos - lastMousePos;
            transform.position += delta;

            lastMousePos = pos;
        }

    }

    

}

13.4几个问题

飞机处理了点击事件,那小球还有没有机会处理这个点击事件哪

在飞机和小球下各挂载一个脚本,第一个脚本和第二个脚本都接收鼠标点击事件,看输出结果如何

发现都触发了

鼠标点击事件所有的对象都会发送


内部执行即所有脚本会按照自定义的顺序进行执行

14.1事件函数

先执行awake后执行start,都只执行一次,可以初始化放在其中

Awake是实例化,即在对象下有脚本组件,但脚本组件的对勾没打,在运行游戏时,此脚本的awake会被执行,但其他的如start是不被执行的

创建C#文件时,自动创建两个函数start(),update()

14.2脚本的执行顺序


一般用不到执行顺序设置

可能设置为全局脚本,让其在最先执行设为负值,默认脚本执行的都是0,或者最后执行设为正值,其他脚本,没有特别要求的不要进行设计

14.3脚本的参数




复制代码
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fly : MonoBehaviour
{
    // 飞行速度
    public Vector3 speed ;

    // Start is called before the first frame update
    void Start()
    {
        Application.targetFrameRate = 60;
    }

    // Update is called once per frame
    void Update()
    {
        Vector3 step = speed * Time.deltaTime; // 标量乘法

        transform.Translate(step, Space.Self);
    }
}

14.4引用类型的参数(进行图片更换,人物换装)

在游戏中看到的游戏对象,资源,游戏组件都可以在脚本中直接使用

实现换装功能,准备两种图片

当鼠标点击时,图片换成另外一张图片

如何实现:

将script render组件取出,修改其sprite属性即可,此属性就是其显示的哪张图片

演示:点击人物,实现换装功能。。

复制代码
SpriteRenderer renderer = GetComponent<SpriteRenderer>();//取出组件
renderer.sprite = ...  

显然,在脚本中需要指定2张图片,以便动态的切换

步骤:

1 在脚本中添加资源的引用

复制代码
 public Sprite sprite0;

2 在Inspector中指定参数

把图片Sprite资源拖到 Inspector相应参数位置

3 在代码中切换图片显示

复制代码
 renderer.sprite = this.sprite1;





注意在VS附加到unity之后,虽然在断点处停下来了,还要在unity点击游戏运行

如上图,此时的sprite0和1就有值了

复制代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class changeFace : MonoBehaviour
{
    //获取两张图片从资源中,使用引用
    //资源图片由Sprite类型表示
    public Sprite sprite0;  //资源图片0,默认为空,并未指定

    public Sprite sprite1;//资源图片1

    private int index = 0;//定义显示的图片序列

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("start......");
    }

    // Update is called once per frame
    void Update()
    {
        //如果鼠标点击了
        if (Input.GetMouseButtonDown(0))
        {
            DoChange();
        }
    }

    //定义一个方法用于换图
    void DoChange()
    {
        //先拿到当前对象的渲染器
        SpriteRenderer renderer = GetComponent<SpriteRenderer>();
        if(index == 0)
        {
            index = 1;
            renderer.sprite = this.sprite1;//当前渲染为1
        }
        else
        {
            index = 0;
            renderer.sprite = this.sprite0;//当前渲染为0
        }
    }
}

当我们还要操作另一个对象人的时候,

如下

相关推荐
一只一只17 分钟前
Unity之Invoke
unity·游戏引擎·invoke
SmalBox1 小时前
【节点】[NormalStrength节点]原理解析与实际应用
unity3d·游戏开发·图形学
技术小甜甜2 小时前
【Godot】【入门】信号系统从 0 到 1(UI/玩法彻底解耦的通用写法)
ui·游戏引擎·godot
技术小甜甜3 小时前
【Godot】【入门】节点生命周期怎么用(避免帧循环乱写导致卡顿的范式)
游戏引擎·godot
tealcwu3 小时前
【Unity踩坑】Simulate Touch Input From Mouse or Pen 导致检测不到鼠标点击和滚轮
unity·计算机外设·游戏引擎
ThreePointsHeat3 小时前
Unity WebGL打包后启动方法,部署本地服务器
unity·游戏引擎·webgl
erxij4 小时前
【游戏引擎之路】《古今东西4》正式立项——新的一年,开始长征
游戏引擎
迪普阳光开朗很健康4 小时前
UnityScrcpy 可以让你在unity面板里玩手机的插件
unity·游戏引擎
陈言必行1 天前
Unity 之 设备性能分级与游戏画质设置与设备自动适配指南
游戏·unity·游戏引擎
CreasyChan1 天前
Unity DOTS技术栈详解
unity·c#·游戏引擎