当前位置: 首页 >  在线学习 >  Unity3D学习记录04——利用射线实现角色类似LOL的移动

Unity3D学习记录04——利用射线实现角色类似LOL的移动

导读:首先新建一个空白的GameObject,挂在一个MouseManager的脚本.实现思路:.通过获取鼠标点击的位置,获得该位置的信息,然后使角色移动到该位置.MouseManager脚本的代码如下:.1 using System;.2 using System.Collectio

首先新建一个空白的GameObject,挂在一个MouseManager的脚本

实现思路:

通过获取鼠标点击的位置,获得该位置的信息,然后使角色移动到该位置

MouseManager脚本的代码如下:

 1 using System;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using UnityEngine;
 5 using UnityEngine.Events;
 6 
 7 public class MouseManager : MonoBehaviour
 8 {
 9     public event Action<Vector3> OnMouseClicked;//声明一个Action<Vector3>类型的事件
10     public RaycastHit hitInfo;//RaycastHit类型的变量,可以返回射线碰撞的的信息
11     public static MouseManager Instance;
12     public Texture2D attack, b, c, d, target;
13 
14     void Awake()
15     {
16         if (Instance != null)
17         {
18             Destroy(gameObject);
19         }
20         Instance = this;
21     }
22     void Update()
23     {
24         SetCursorTexture();
25         MouseControl();
26     }
27     void SetCursorTexture()
28     {
29         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
30         if (Physics.Raycast(ray, out hitInfo))
31         {
32             //切换鼠标贴图
33             switch (hitInfo.collider.gameObject.tag)
34             {
35                 case "Ground":
36                     Cursor.SetCursor(target, new Vector2(16, 16), CursorMode.Auto);
37                     break;
38                 case "Enemy":
39                     Cursor.SetCursor(attack, new Vector2(16, 16), CursorMode.Auto);
40                     break;
41             }
42         }
43     }
44     void MouseControl()
45     {
46         if (Input.GetMouseButtonDown(0) && hitInfo.collider != null)
47         {
48             if (hitInfo.collider.CompareTag("Ground"))
49                 OnMouseClicked?.Invoke(hitInfo.point);
50         }
51     }
52 }

代码解释:

先创建了一个Action类型的事件OnMouseClicked

这个是C#中事件的内容,我们可以在满足条件的时候自动触发这个OnMouseClicked的事件

接着我们声明两个函数,一个是SetCursorTexture,一个是MouseControl

第一个函数中,我们声明一个射线的对象ray,并且用Camera.Main.ScreenPointToRay()获取从摄像机通过屏幕点的光线

ScreenPointToRay()的参数为鼠标点击的位置,这样我们的对象ray就获得了我们鼠标点击的位置信息

Raycast回返回一个bool值,我这边用了两个参数,一个是我们的射线ray,一个是out的hitInfo,也就是返回的信息

那么当我们返回值为true的时候,我们会有一个切换鼠标贴图的效果

其中SetCursor中有个参数是偏移量,也就是上述代码中的new Vector2,因为鼠标指针判定是在左上角的,调节适当的偏移量,可以使你变换后的指针可以使其作用点在中心

(PS:我声明的几个Texture2D中,有几个没有意义的字母,是留着备用的,目前还没想到哪些功能需要使用)

第二个函数MouseControl的第一个if中,

我们如果鼠标按下了左键(函数的参数0即为鼠标左键,1为鼠标右键)并且我们射线碰撞不为空,

那么我们执行第二个if,第二个if表示 我们射线碰撞到的物体tag为Ground,那么我们执行OnMouseClicked函数

?.Invoke表示如果这个函数不为空,那么我们执行这个函数,和!=null是一个意思,这个写法较为便捷

Invoke中我们需要传入一个Vector3的参数,即为碰撞的Point

最后我们需要在Unity中设置一下我们Ground的Tag

至于鼠标切换贴图,需要在Unity里面进行操作:

先选中自己需要作为鼠标贴图的图片,打开Inspector窗口,设置为Cursor

下方的Max Size可以调整鼠标贴图的大小

关于射线的Unity 官方的API手册如下:

翻译

搜索

复制

内容
  • 一文揭秘DDD到底解决了什么问题
    一文揭秘DDD到底解决了什么问题
    2023-12-01
    DDD作为架构设计思想帮助微服务控制规模复杂度,那它是怎么做到的呢?.一、架构设计是为了解决系统复杂度.谈到架构,相信每
  • Unity实现3D物体遮挡血条
    Unity实现3D物体遮挡血条
    2023-12-08
    Unity 实现3D物体遮挡血条.######.前言:在游戏开发中,我们经常会遇到UI和3D物体的层级遮挡问题,最常见的
  • 一个公式让你35岁以后能越过越好!大神修炼心法
    一个公式让你35岁以后能越过越好
    2023-12-08
    前言.Cocos 的老铁,如果你这几天没有被麒麟子给卷到?那说明你还没有真正进入 Cocos 圈子里来。为什么这么说呢?
  • C++学习-static
    C++学习-static
    2023-12-02
    全局变量使用:.作用是限定全局变量的作用范围,只能在当前文件使用,类似给它加了个private属性。.其他文件即使使用e
  • 【Oculus Interaction SDK】(五)设置不同的抓握手势
    【Oculus Interact
    2023-12-10
    前言.前段时间 Oculus 的 SDK.频繁更新,很多已有的教程都不再适用于现在的版本了。本系列文章的主要目的是记录现
  • 吃透单调栈(2)——解两道Hard题:接雨水、柱状图中最大的矩形问题
    吃透单调栈(2)——解两道Har
    2023-12-04
    怎么想到要用单调栈的?.这类题目的数据通常是一维数组,要寻找任一个元素的右边或者左边第一个 比自己大 或者小 的元素的位