Day 18 | FPS灭火AR游戏开发Part3 - 火焰生成

昨天的文章中已介绍火焰粒子的制作,那麽今天的文章将会说明如何在AR世界中产生火焰!

火焰产生器

在场景中,创建一个Empty GameObject,添加新的火焰产生器script,宣告物件变数,放入上一篇文章制作的火焰Prefab。

public Gameobject FlamePrefab;    

游戏机制为计时到固定时间後,产生火焰,在限时内灭火一定数量即可通关。主要的框架如下:

void Update()
{
    if(产生 == true){
    
         Fire();//产生火焰function;

    }else{
 
        nextFireTime();计时下一次产生火焰funtion;

    }
}

因为产生器的机制与计时有关,所以放在Update()函式当中。

火焰产生器计时,时间一到就升火 nextFireTime()

在产生器的class当中宣告计时变数。

privae float generateTime = 0f;    

在计时的函式nextFireTime()中,如果计时超过了2.5秒,就呼叫产生函式Fire(),产生一朱火焰;如果还没到产生时间,就让generateTime持续增加Time.deltaTime,继续计时。

nextFireTime()
{
    if(generateTime>2.5f)
    {
    
        Fire();  //产生火焰
    
    }else{
        
        generateTime += Time.deltaTime;
    
    }
}

随机地点生成

在Fire()函式当中,产生火焰之前要先随机选择要产生的点:

  • 宣告int变数,储存使用Random.Range函式生成的数值
  • 宣告Vector2变数,用来储存之後要产生的Position
  • 利用switch选择Position
  • 使用ViewportToScreenPoint
    • Viewport:相对於相机是标准化的。相机的左下角是 (0,0);右上角是 (1,1); z 位置以相机的世界单位为单位。
    • ScreenPoint:以像素为单位定义。屏幕左下角是(0,0);右上角是(pixelWidth , pixelHeight)。z 位置以相机的世界单位为单位。
  • 生成的火焰希望分别是三个位置,固定的y值。
int Randomnum;
Vector2 screenPosition;

Randomnum = Random.Range(0, 3);
switch (Ramdonnum)
{
    case 0:
    screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.25f, 0.4f));
        break;
    case 1:
    screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.5f, 0.4f));
        break;
    case 2:
    screenPosition = Camera.main.ViewportToScreenPoint(new Vector2(0.75f, 0.4f));
        break;
                }

射线、平面管理器

  • 在ARSessionOrigin中挂上AR PlaneManager及AR RaycaseManager两个元件
  • 将AR Default Plane制成Prefab,放入AR PlaneManager的Plane Prefab中(不喜欢预设的Plane可以针对Mesh的部分做更改)

射线、平面碰撞

在产生器的class当中宣告ARRaycastManager,在Unity将ARSessionOrigin放入。

public ARRaycastManager raycastManager;
  • 宣告撞击List,储存射线撞击物体的讯息。
  • 使用Raycast,从萤幕座标的一个点向可追踪类型投射光线。
  • 如果有撞击发生,取得撞击的第一个位置作为产生火焰的位置。
List<ARRaycastHit> hits = new List<ARRaycastHit>();
raycastManager.Raycast(screenPosition, hits, UnityEngine.XR.ARSubsystems.TrackableType.Planes);
if (hits.Count > 0)
{
    GameObject.Instantiate(FlamePrefab, hits[0].pose.position, hits[0].pose.rotation);
}

今天的文章利用 Raycasy Hit搭配Plane侦测,顺利的让火焰在AR世界中产生了,下一篇就会撰写灭火的部分,那就明天见~


<<:  【Day 17】Django model

>>:  Day17-Vue Router与前端路由管理

Day 15 - UML x Interface — Notifier

UML Notifier 的 UML 主要是根据 Ant Design 的设计画出来的,而在 Ma...

Day20 - 在 XState 与 Side Effect 互动吧~ action API

1. Action 与 Side Effect 昨天,我们确认了状态能被储存起来,然而我们这个开门,...

[DAY 19]Gan

前言 在这个 GAN 到爆炸的年代,你能想到的东西我都可以拿出一个有 GAN 的 Paper 出来X...

Windows event 59 sidebyside invalid

工作上遇到了些问题纪录一下 因作业关系,修改了服务中的设定档 服务启动发生错误: 错误14001 使...

Day 23:最小生成树(MST)

贪婪演算法可以解决的一个问题就是找到一张图中的最小生成树(minimum spanning tree...