使用射线检测完成光束照耀激活功用——2024TapTap聚光灯GameJam(一)
运用射线检测完结光束照耀激活功用——2024TapTap聚光灯GameJam
记载日期 2024-11-05 记载时刻 13:35 项目完结 2024-10-28 历经时长 21 天
简介
项目主题:Light
项目名称:《OneLastLight》(2D渠道跳动解密)
我的责任:gamepaly程序,担任完结游戏玩法功用
简述:
策划的规划为人物操控灯火,灯火照耀到渠道,能够使渠道闪现实体,玩家能够凭借渠道解密。
灯火能够被不是渠道的实体阻挠,并且灯火不能被渠道阻挠,能够穿透渠道。
人物有两种形状的灯火,光圈会以玩家为中心构成圆形照亮区域,光束会从玩家开端射出一个扇形区域跟从鼠标勘探。
光束有红、蓝、白三种色彩,光圈有红、蓝两种色彩。白色能够使一切渠道闪现实体,红、蓝光只能令相反色彩的渠道闪现实体,能够使相同色彩的渠道躲藏。
这儿记载我完结这个玩法所运用的解决办法。
正文
设想
选用射线检测办法,从人物的方位开端,每次让射线移动一个视点,设置视点约束,使射线检测构成扇形区域,而光圈形式只要将视点约束改为360度
一般的 Physics2D.Raycast只能检测射线碰到的第一个实体,不行穿透,所以这次挑选Physics2D.RaycastAll办法,此办法能够回来一个射线上的一切实体从近到远的数组.(Physics2D-RaycastAll - Unity 脚本 API
完结
-
创立人物Player,创立两个空物体LightBeam、LightCircle作为Player的子物体
-
新建两个脚本:LightBeamController、LightCircleController,别离挂载在:LightBeam、和LightCircle上,脚本内容为设想中RayCastAll办法的完结运用,先获取射线上的一切物体,然后遍历,调用物体上脚本中的激活代码
LightBeamController(LightCircleControl类似):
//此办法用于完结光线激活渠道、阻挠、穿透
void DrawFieldOfView(){
// 核算最左侧方向的向量
// -transform.up看情况设置,最好与LightBeam的旋转共同
Vector3 forward_down = Quaternion.Euler(0, 0, -(viewAngle / 2f)) * -transform.up * viewRadius;
//在约束视点内创立viewAngleStep条射线,每条射线偏移必定的视点
for (int i = 0; i <= viewAngleStep; i++){
Vector3 v = Quaternion.Euler(0, 0, (viewAngle / viewAngleStep) * i + 180f) * forward_down; // 依据当时视点核算方向向量
Vector3 pos = transform.position + v; // 核算射线结尾
// 在Scene中制造线条(仅在Scene中可见,便利检查)
Debug.DrawLine(transform.position, pos, Color.red);
// 设置射线检测射线
Ray2D ray = new Ray2D(transform.position, v);
//射线检测
RaycastHit2D[] hits =
Physics2D.RaycastAll(ray.origin, v, viewRadius, LayerMask.GetMask("Trigger")); //这儿设置只检测Trigger层级
//遍历检测到的物体
for (int j = 0; j < hits.Length; j++){
RaycastHit2D hitInfo = hits[j];
if (hitInfo.collider != null){
if (hitInfo.collider.CompareTag("BluePlatform") || hitInfo.collider.CompareTag("RedPlatform")){
//检测到为BluePlatform或许RedPlatform履行渠道上的闪现操作
}
}
}
}
}
}
- 射线穿透做完了,现在射线能够穿透一切的物体,为其增加阻挠功用,十分简略。已知Physice2D.RayCastAll办法是将射线磕碰到的一切物体按从近到远的顺序排列在数组中。那么在遍历时遇到不是激活渠道的物体直接跳出此次遍历即可,即在判别渠道的条件句后加上break即可
if (hitInfo.collider.CompareTag("BluePlatform") || hitInfo.collider.CompareTag("RedPlatform")){
//检测到为BluePlatform或许RedPlatform履行渠道上的闪现操作
}
else break;
}
- 制造渠道,创立一个空物体叫platform,创立一个矩形叫Entity,给它们挂载磕碰体,将platform的磕碰体设置为trigger,layer层级设置为Trigger(我设置的射线只能检测Trigger层的物体),tag设置为BluePlatform或RedPlatform,最终将Entity作为platform的子物体
- 创立脚本PlatformController,在脚本中增加BoxAppear()和BoxDisappear()办法,用来操控实体的激活和失活
public void BoxDisappear()
{
_entity.SetActive(false);
}
public void BoxAppear()
{
_entity.SetActive(true);
timer=0;//将计时器置为0
}
- 在update中增加计时器,在灯火照耀时不断将计时器置为0,灯火不照耀时计时器开端累计时刻,抵达必定时长后将渠道实体主动失活。
private void Update()
{
timer += Time.deltaTime;
if (timer > canSeeTime)
{
BoxDisappear();
}
- 最终在LightBeamController和LightCircleController中参加灯火色彩判别
if (hitInfo.collider.CompareTag("BluePlatform")||
hitInfo.collider.CompareTag("RedPlatform")){
switch (_colorID){
case 0:
if (hitInfo.collider.CompareTag("BluePlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxAppear();
if (hitInfo.collider.CompareTag("RedPlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxDisAppear();
break;
case 1:
if (hitInfo.collider.CompareTag("BluePlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxDisAppear();
if (hitInfo.collider.CompareTag("RedPlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxAppear();
break;
case 2:
if (hitInfo.collider.CompareTag("BluePlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxAppear();
if (hitInfo.collider.CompareTag("RedPlatform"))
hitInfo.collider.gameObject.GetComponent<PlatFormController>().BoxAppear();
break;
}
}
else break;
}
将射线检测的办法放在UpDate中调用,完结!
其它
光束与光圈形式的切换只需启用对应目标。
光束跟从鼠标,只需要令游戏目标LightBeam跟从鼠标旋转即可。
项目全体视频演示
项目代码GitHub链接(因为项目后边要合作Shader完结视觉效果,源码可能与上文略有不同)