700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > unity Physics.Raycast 射线进入离开collider 开始结束碰撞检测功能的实现

unity Physics.Raycast 射线进入离开collider 开始结束碰撞检测功能的实现

时间:2023-06-28 12:10:47

相关推荐

unity Physics.Raycast 射线进入离开collider 开始结束碰撞检测功能的实现

问题与解决思路

问题

当使用unity的射线组件时,发现unity只提供了射线与物体碰撞的时的响应办法。这就尴尬了,因为我的需求是获取射线在某物体停留、或是射线离开某物体的信息。本以为被碰撞物体的collider会解决这个问题,结果发现虽然使用raycast需要物体必须有collider,但并不会触发collider相关的事件。没办法,只能自己解决了。

解决思路

解决思路其实很简单,编写一个脚本,定义射线与物体碰撞、停留、离开三个事件,通过不断更新射线的扫描目标信息并与上一帧已保存的信息进行对比,来推算行为并触发相应事件。

实现过程

1. 创建组件:在资源窗口中创建脚本,起名为mRayCasterInput,并填入下列代码

using System;using System.Collections;using UnityEngine;public class mRayCasterInput{// 定义三个事件,用来定义不同行为的不同相应public event Action<Collider> OnRayEnter;public event Action<Collider> OnRayStay;public event Action<Collider> OnRayExit;// 用来保存上一个射线扫到的物体Collider previousCollider;public void CastMouseRay(){// 从摄像机向鼠标位置发射一束射线,并返回相关信息Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;Physics.Raycast(ray, out hitInfo);// 处理返回的信息CollisionProcess(hitInfo.collider); }private void CollisionProcess(Collider current) {// 执行射线离开物体触发的事件// 如果在当前帧中,射线没有碰撞到任何物体,并且在记录中保存到碰撞体不为空,就触发该物体的结束射线碰撞事件if (current == null) {if (previousCollider != null) {OnRayExit?.Invoke(previousCollider);}}// 射线停留在某个物体时触发的事件// 如果当前射线碰撞的物体和上一个射线碰撞到物体相同,则触发射线停留事件else if (previousCollider == current) {OnRayStay?.Invoke(current);}// 射线更新事件// 如果当前射线和上一个射线碰撞的物体不是同一个,则上一个物体触发射线离开事件,当前物体触发射线碰撞事件else if (previousCollider != null) {OnRayEnter?.Invoke(current);OnRayExit?.Invoke(previousCollider);}// 如果之前帧中没有射线碰撞的物体,当前帧有射线碰撞到物体,则触发此事件。else {// no collider on last frameOnRayEnter?.Invoke(current);}// 将当前射线碰撞的物体保存为 上一个碰撞的物体previousCollider = current;}}

2. 在脚本中调用新组件

在脚本中到start()周期中 注册相关相应事件,在update() 周期中更新射线信息,即可正常运作了。

private void Update(){// 更新射线信息rayCasterinput.CastMouseRay();}private void Start() {// 处理射线与物体碰撞时触发的方法rayCasterinput.OnRayEnter += (Collider c)=>{Debug.Log("enter name:"+c.gameObject.name);};// 处理射线与已碰撞物体结束碰撞时触发的方法rayCasterinput.OnRayExit += (Collider c)=>{Debug.Log("exit name:"+c.gameObject.name);};}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。