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与前端路由管理

Python argparse 套件入门使用

test.py import argparse parser = argparse.Argument...

Day 24非同步程序设计

前言 非同步程序设计基本上就是没有等待或非阻塞程序的设计模型,在Flutter中,非同步是用Futu...

17. PHPer x Code Quality Tool

老板说程序码写得好就不会有 bug,你 bug 太多要扣你绩效。 为什麽前辈写的就没有 bug?我...

镜面效果

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

excel 内有病毒

想请问一下,公司用了本人一个 excel 档案已经几年了,一般也是自动化处理公司内部一些文件或报告类...