国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

這篇具有很好參考價(jià)值的文章主要介紹了DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


前言

DOTS是Unity在17年左右提出的一個(gè)概念,其核心是ECS。


提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、1. What is DOTS and why we use it?

全稱:(Multi-Thread)Data-Oriented-Tech-Stack
(多線程式)數(shù)據(jù)導(dǎo)向型技術(shù)堆棧

1.DOTS包含的主要元素(三件套)

  1. 實(shí)體組件系統(tǒng)(ECS) - 提供使用面向數(shù)據(jù)的方法進(jìn)行編碼的框架。在Unity中它通過(guò)Entities軟件包進(jìn)行分發(fā),您可以通過(guò)Package Manager來(lái)添加編輯器。
  2. C#作業(yè)系統(tǒng) (JobSystem)- 提供一種生成多線程代碼的簡(jiǎn)單方法。它通過(guò)Jobs軟件包進(jìn)行分發(fā)。
  3. Burst編譯器 - 可生成快速、優(yōu)化的本機(jī)代碼。它通過(guò)Burst軟件包進(jìn)行分發(fā),可通過(guò)Package Manager在編輯器中使用。
  4. 本機(jī)容器 - 屬于ECS數(shù)據(jù)結(jié)構(gòu),可提供對(duì)內(nèi)存的控制,值得注意的是Unity專門(mén)對(duì)內(nèi)存管理進(jìn)行了一部分優(yōu)化以降低MissCache。

2.Why we use it?

  1. 許多并行編程范式,尤其是SIMD(單指令多數(shù)據(jù))型范式,更傾向于使用SoA(結(jié)構(gòu)體數(shù)組)。在CUDA C編程中也普遍傾向于SoA,一維數(shù)據(jù)元素是為全局內(nèi)存的有效合并訪問(wèn)而預(yù)先準(zhǔn)備好的,而相同內(nèi)存操作引用的同字段元素在存儲(chǔ)時(shí)時(shí)彼此相鄰的,使用SoA能夠顯著減少M(fèi)issCache。
  2. 實(shí)體組件系統(tǒng)(ECS)提供了一種面向數(shù)據(jù)的編碼設(shè)計(jì)方法。利用面向數(shù)據(jù)的方法,可以對(duì)數(shù)據(jù)結(jié)構(gòu)加以組織,以免出現(xiàn)高速緩存未命中的情況,從而令隨后的數(shù)據(jù)訪問(wèn)更加高效、快捷。由于面向?qū)ο蟮脑O(shè)計(jì)并不專注于數(shù)據(jù)的組織,因此高速緩存未命中的情況很常見(jiàn),這樣就減慢了CPU訪問(wèn)數(shù)據(jù)的速度,因?yàn)樗仨氼l繁地返回訪問(wèn)主內(nèi)存中的數(shù)據(jù)。
  3. C#作業(yè)系統(tǒng)可以輕松地用C#編寫(xiě)快速、并行化的代碼,以充分利用當(dāng)今的多核處理器。
  4. Burst編譯器會(huì)生成高度優(yōu)化的代碼,而這些代碼可以利用您要編譯的平臺(tái)硬件。

Tips:

  1. jobsystem和ecs是兩個(gè)不同的東西,但是配合起來(lái)使用會(huì)有1+1>2的效果
  2. burst與ecs的高度適配也使得ecs運(yùn)行效率很高

3.Where we use it? (摘自Unity官方)

除非您在尋求短期或中期的性能改進(jìn),否則很難判定是否需要過(guò)渡到DOTS或何時(shí)過(guò)渡到DOTS。
DOTS幾乎可以為每個(gè)應(yīng)用程序帶來(lái)一定程度的性能改進(jìn)。這其中包括性能、電池使用壽命、迭代及項(xiàng)目可擴(kuò)展性。過(guò)渡到DOTS不會(huì)造成任何性能的下降,但評(píng)估過(guò)渡到DOTS所增加的費(fèi)用卻至關(guān)重要,尤其是對(duì)于那些僅帶來(lái)較小改進(jìn)的項(xiàng)目。
對(duì)于所有應(yīng)用程序而言,DOTS適合處理大量數(shù)據(jù),例如開(kāi)放式環(huán)境或使用大量相同材料的復(fù)雜結(jié)構(gòu)。通過(guò)在實(shí)例之間共享公共數(shù)據(jù)以減少內(nèi)存訪問(wèn),DOTS也同樣適用于重復(fù)的元素。
DOTS將來(lái)會(huì)幫助您開(kāi)發(fā)高質(zhì)量的內(nèi)容,而不使用DOTS的Unity卻很難做到,這一點(diǎn)務(wù)必要考慮清楚。例如,當(dāng)今的標(biāo)準(zhǔn)游戲和Unity項(xiàng)目已經(jīng)取代了過(guò)去的AAA游戲。放眼未來(lái),您需要采用DOTS來(lái)保持競(jìng)爭(zhēng)力。
針對(duì)不同的垂直行業(yè),DOTS可以適用于不同的解決方案:

(1)對(duì)于AEC(工程建設(shè))應(yīng)用

  • DOTS適合處理大型數(shù)據(jù)集并確保內(nèi)容的可擴(kuò)展性。
  • DOTS非常適合進(jìn)行大型交互式地圖和具有大量模型和重復(fù)內(nèi)容(例如建筑物和道路)的環(huán)境設(shè)計(jì)。
  • DOTS適用于復(fù)雜的工程可視化,可大規(guī)模地模擬現(xiàn)實(shí)環(huán)境。例如,DOTS非常適合進(jìn)行粒度級(jí)工廠和基礎(chǔ)架構(gòu)設(shè)計(jì)。

(2) 對(duì)于汽車應(yīng)用

  • 自動(dòng)駕駛的仿真和可視化
  • DOTS非常適合進(jìn)行大型交通和行人模擬,這需要成千上萬(wàn)的志愿Agent以逼真的方式移動(dòng)和交互。

(3) 對(duì)于游戲獨(dú)立開(kāi)發(fā)者和自由職業(yè)者

  • DOTS可以幫助您減輕游戲中一些高成本操作的負(fù)擔(dān),并有助于提高性能,尤其是對(duì)于一些重復(fù)性進(jìn)程。
  • 許多輕量級(jí)游戲(例如用于移動(dòng)設(shè)備的游戲)并不能最大限度地提高硬件性能。即使有些游戲能夠做到這一點(diǎn),但這可能并不是它的主要關(guān)注點(diǎn)。不過(guò),隨著游戲的不斷發(fā)展和硬件需求的持續(xù)增加,明智的做法是為將來(lái)使用DOTS做好準(zhǔn)備。同樣,Project Tiny也提供了使用DOTS開(kāi)發(fā)較小應(yīng)用程序和游戲的解決方案。
  • 如果您沒(méi)有使用DOTS的迫切需求,那么最好先未雨綢繆,提高自己的DOTS技能,以便在DOTS成為Unity開(kāi)發(fā)的標(biāo)準(zhǔn)方法時(shí)能夠整裝待發(fā)。

(4)對(duì)于游戲工作室

  • 當(dāng)前格式的DOTS可以幫助您逐步達(dá)到Unity或其他方式所無(wú)法達(dá)到的規(guī)模和性能。具體而言,更長(zhǎng)的電池使用壽命、溫度控制以及DOTS所提供的代碼可重用性是其主要優(yōu)勢(shì)所在。這些方面的性能改進(jìn)還使您可以開(kāi)發(fā)更多的低端設(shè)備,尤其是在西方市場(chǎng)以外的地區(qū),這些設(shè)備會(huì)受到一定的硬件限制。
  • 通過(guò)讓研發(fā)團(tuán)隊(duì)以DOTS開(kāi)展工作,可以幫助您逐步了解所能采取的最佳方法,以及哪些最新的功能和領(lǐng)域最具性能優(yōu)勢(shì)和發(fā)展影響力。
  • DOTS并非要取代引擎團(tuán)隊(duì)的作用,而是讓工程師騰出更多精力在自己的專業(yè)領(lǐng)域(例如陰影或著色器)進(jìn)行創(chuàng)新。

4.DOTS的優(yōu)劣(機(jī)遇以及風(fēng)險(xiǎn))

在改善Unity項(xiàng)目的績(jī)效方面,DOTS有著巨大的潛力。 但是,在使用DOTS時(shí)需要做出一些考量,它們會(huì)影響到項(xiàng)目的時(shí)間表、預(yù)算和開(kāi)發(fā)團(tuán)隊(duì)。以下是一些需要與項(xiàng)目?jī)?yōu)先事項(xiàng)進(jìn)行比較和對(duì)比的事項(xiàng)。這些事項(xiàng)可以歸類為風(fēng)險(xiǎn)與機(jī)遇。

機(jī)遇

  1. 改進(jìn)性能。默認(rèn)情況下,我們經(jīng)常使用“性能”一詞來(lái)描述DOTS。這是什么意思呢?借助面向數(shù)據(jù)的設(shè)計(jì)和多線程,DOTS可以顯著提升內(nèi)存、運(yùn)行時(shí)間和電池性能。隨著游戲中顯示的項(xiàng)目數(shù)量不斷增加,提高性能的潛力也隨之上升。相反,對(duì)于項(xiàng)目較少的游戲,您會(huì)發(fā)現(xiàn)游戲性能的改善程度卻不太明顯。
  2. 代碼控制。隨著項(xiàng)目規(guī)模的不斷增大,DOTS可以更好地控制代碼的復(fù)雜性。為DOTS編寫(xiě)的代碼通??梢愿玫胤蛛x關(guān)注點(diǎn)。因此,使用DOTS工作時(shí),代碼重構(gòu)、編寫(xiě)單元測(cè)試以及在開(kāi)發(fā)人員之間分配工作就變得更加容易。

風(fēng)險(xiǎn)

  1. 學(xué)習(xí)成本。如果您不熟悉DoD,那么面對(duì)DOTS時(shí)就會(huì)有一個(gè)學(xué)習(xí)曲線。盡管DoD在計(jì)算機(jī)科學(xué)領(lǐng)域有著良好的根基并已存在數(shù)年,而且DoD方法與OOP方法也有很大的不同,但DoD本質(zhì)上并不比OOP復(fù)雜。ECS是一種不同于當(dāng)前Unity MonoBehaviour方法的代碼體系架構(gòu),因此學(xué)習(xí)需要一定的時(shí)間。目前,我們認(rèn)為一名普通的Unity專業(yè)開(kāi)發(fā)人員平均需要1個(gè)月才能熟練使用DOTS。這一準(zhǔn)備時(shí)間可以被使用DOTS時(shí)的代碼質(zhì)量和性能改進(jìn)所抵消。當(dāng)然,具體要取決于項(xiàng)目。
  2. 有限支持。DOTS當(dāng)前僅與Unity中一組有限的功能兼容。 最終,DOTS將與Unity的所有功能完全兼容,但我們目前尚無(wú)實(shí)現(xiàn)完全兼容的時(shí)間表。不過(guò),DOTS允許在單個(gè)項(xiàng)目中同時(shí)使用游戲?qū)ο蠛虳OTS,因此您可以將DOTS用于最頻繁的處理任務(wù),而將非DOTS Unity用于其余任務(wù)。
  3. 過(guò)渡。如果之前的項(xiàng)目是基于Mono開(kāi)發(fā),那么跟ECS之間的轉(zhuǎn)換可能比較簡(jiǎn)單,使用Unity自帶的一些Hybrid工具就可以較為簡(jiǎn)單的做到,但是想要把ECS轉(zhuǎn)化為目前常用的Mono的話,我們認(rèn)為可以做到,但是十分困難,而且也不建議這么做(為什么要嘗試把高效率轉(zhuǎn)為低效率呢)。目前比較推薦的是HybridECS開(kāi)發(fā),ECS與Mono混合在一起,ECS再配合Jobsystem處理最需要多線程的那一部分。

隨著時(shí)間的推移,晶體管電路逐漸接近性能極限,在摩爾定律逐漸失效的今天,人們面臨的數(shù)據(jù)也呈幾何倍數(shù)暴增,我們有理由去發(fā)明并且學(xué)習(xí)使用一種效率更高,更能完全發(fā)揮硬件性能的軟件編程方式,目前看來(lái)也許ECS也許能做到。

二、DOTS-Man小游戲項(xiàng)目實(shí)戰(zhàn)

想要熟悉DOTS以及ECS框架,最好還是要上手做一個(gè)小項(xiàng)目,使用部分基礎(chǔ)組件,想要熟悉以及精通還需要大量的練習(xí)以及使用,開(kāi)發(fā)過(guò)程中要配合官方Entities文檔使用。
Entities最新版本0.17的官方說(shuō)明文檔

1.環(huán)境配置

  • 如果是Unity2020.X以下版本:
    1. windows -> package manager
    2. advanced -> show preview package
    3. install三件套 (Entities,Jobs,Burst)
    4. install其他組件(Hybrid Renderer,Mathematics)

DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

  • 如果是Unity2020.X及以上版本(推薦,作者使用2020.3.26f1c1):

    • 進(jìn)入package manager
    • 點(diǎn)擊 + 號(hào)點(diǎn)擊add package from gir url手動(dòng)添加三件套以及其他組件
      • com.unity.dots.editor
      • com.unity.physics
      • com.unity.entities
      • com.unity.rendering.hybrid

    DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

2.游戲設(shè)計(jì)

我們準(zhǔn)備做一個(gè)類似Pac-Man的小游戲,主要熟悉Physics包以及Entities的基本使用,所以不會(huì)開(kāi)發(fā)怪物AI之類的,因?yàn)槭褂肈OTS開(kāi)發(fā)所以就叫DOTS-MAN好了。

需求分析

主要功能有:玩家移動(dòng),鏡頭跟隨,分?jǐn)?shù)顯示,因?yàn)槿绻肊CS來(lái)修改UGUI的TEXT可能比較麻煩,這里選擇使用HybridECS開(kāi)發(fā),使用MonoBehaviours開(kāi)發(fā)一些基礎(chǔ)功能比如鏡頭跟隨以及物體生產(chǎn)之類。

3.正式開(kāi)發(fā)

一些自帶腳本

在開(kāi)發(fā)過(guò)程中,因?yàn)槭占镆约巴婕疫€有地形之類的都要有碰撞,但是ECS無(wú)法使用object上面的collider之類的組件,所以就要用Entities包自帶的一些腳本。

記得在掛Entities腳本之前刪掉不用的Object腳本,避免混淆以及無(wú)意義的空間占用

把Object轉(zhuǎn)化成Entity的腳本:
DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)
一般配合一起使用的腳本就是PhysicsShape和PhysicsBody,一個(gè)控制物理碰撞的類型,一個(gè)控制entity的物理性質(zhì)(例如重力之類的),各個(gè)屬性的作用都有明確說(shuō)明:

DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

添加physicsbody之后碰到List越界報(bào)錯(cuò)問(wèn)題解決方案:
go into YOURPROJECTLibrary/PackageCache/
copy com.unity.collections@0.15.0-preview.21 into YOURPROJECT/Packages/
open com.unity.collections@0.15.0-preview.21\Unity.Collections\NativeList.cs
change line 599 from Allocator.None to Allocator.Invalid

Component

組件只有三個(gè),兩個(gè)存儲(chǔ)分別存儲(chǔ)移動(dòng)和旋轉(zhuǎn)的速度,一個(gè)負(fù)責(zé)標(biāo)記收集物(所以里面沒(méi)有數(shù)據(jù))
要記得把Serializable屬性改為GenerateAuthoringComponent,這樣把component掛上object之后就會(huì)把他變成entity。
創(chuàng)建component和system都可以直接使用右鍵 -> create -> ECS進(jìn)行快速選擇自帶模板
DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

using Unity.Entities;

[GenerateAuthoringComponent]
public struct MoveComponent : IComponentData
{
    public float moveSpeed;
}
using Unity.Entities;

[GenerateAuthoringComponent]
public struct RotationComponent : IComponentData
{
    public float rotateSpeed; 
}

Component配置:
玩家:
DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)
墻體和收集物:

要注意在腳本中配置Collision Filter相關(guān)以及Collision Response相關(guān),即某個(gè)entity屬于哪個(gè)標(biāo)簽,他能與其他哪些標(biāo)簽的entity發(fā)生碰撞

DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)
搭建一個(gè)使用場(chǎng)景(renderer相關(guān)的根據(jù)自己喜好來(lái)整):

因?yàn)閙ono和ECS是相互穿插的,所以如果mono中有需要的system可以直接先去看看system的代碼,配合官方文檔理解為何這么做,這樣才能把整個(gè)流程梳理清楚(至少我學(xué)習(xí)的時(shí)候是這樣的)

Mono Behaviour

這里需要一個(gè)全局的mono behaviour來(lái)控制游戲,例如entity與object的連接,這里我們換一種方式,把之前的玩家小球弄成prefab,然后在這個(gè)全局mono控制玩家的生成,起名就叫做GameManager吧(具體說(shuō)明看注釋):

  1. GameManager:
using System.Collections;
using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine.UI;
using Unity.Transforms;

public class GameManager : MonoBehaviour
{
    public static GameManager instance;

    public bool insaneMode;

    //在實(shí)體object世界中的prefab
    public GameObject ballPrefab;
    public GameObject cubePrefab;
    public Text scoreText;

    public int maxScore;
    public int cubesPerFrame;
    public float cubeSpeed = 3f;

    private int curScore;
    private Entity ballEntityPrefab;
    private Entity cubeEntityPrefab;
    private EntityManager entityManager;
    private BlobAssetStore blobAssetStore;

    //private bool insaneMode;

    private void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(gameObject);
            return;
        }

        instance = this;

        //初始化EntityManager
        entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
        blobAssetStore = new BlobAssetStore();

        //從object世界獲得setting
        //即inspector中可以獲取的prefab
        GameObjectConversionSettings settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, blobAssetStore);

        //通過(guò)GameObjectConversionUtility的ConvertGameObjectHierarchy來(lái)把object變成entity
        //參數(shù)(GameObject root, World dstEntityWorld)
        ballEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(ballPrefab, settings);
        cubeEntityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(cubePrefab, settings);

    }

    private void OnDestroy()
    {
        //重置BlobAssetStore中的blobasset緩存,釋放清空blobAssetStore
        blobAssetStore.Dispose();
    }

    private void Start()
    {
        curScore = 0;

        insaneMode = false;

        //顯示分?jǐn)?shù),這個(gè)函數(shù)在每一幀都會(huì)調(diào)用
        DisplayScore();
        //創(chuàng)建初始球球
        SpawnBall();
    }

    private void Update()
    {
        //如果符合條件就開(kāi)啟insanemode瘋狂造方塊,這里改成手動(dòng)開(kāi)啟
        //if (!insaneMode && curScore >= maxScore)
        if (insaneMode)
        {
            //開(kāi)啟協(xié)程造方塊
            //insaneMode = true;
            StartCoroutine(SpawnLotsOfCubes());
        }
    }

    //回調(diào),造方塊
    IEnumerator SpawnLotsOfCubes()
    {
        while (insaneMode)
        {
            //每一幀造cubesPerFrame量的方塊
            for (int i = 0; i < cubesPerFrame; i++)
            {
                SpawnNewCube();
            }
            yield return null;
        }
    }


    void SpawnNewCube()
    {
        //使用entityManager造方塊并且給予屬性

        Entity newCubeEntity = entityManager.Instantiate(cubeEntityPrefab);

        Vector3 direction = Vector3.up;
        Vector3 speed = direction * cubeSpeed;

        PhysicsVelocity velocity = new PhysicsVelocity()
        {
            Linear = speed,
            Angular = float3.zero
        };

        //最后記得往entity添加component數(shù)據(jù)
        entityManager.AddComponentData(newCubeEntity, velocity);
    }

    public void IncreaseScore()
    {
        curScore++;
        DisplayScore();
    }

    private void DisplayScore()
    {
        scoreText.text = "Score: " + curScore;
    }

    //造第一個(gè)球
    void SpawnBall()
    {
        Entity newBallEntity = entityManager.Instantiate(ballEntityPrefab);

        Translation ballTrans = new Translation
        {
            //初始位置
            Value = new float3(0f, 0.5f, 0f)
        };

        //還是要記得添加component
        entityManager.AddComponentData(newBallEntity, ballTrans);
        //設(shè)置鏡頭跟隨的對(duì)象
        CameraFollow.instance.ballEntity = newBallEntity;
    }
}
  1. CameraFollow:
    相機(jī)跟隨的mono腳本:
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{
    public static CameraFollow instance;

    public Entity ballEntity;
    //設(shè)置一個(gè)偏移量用來(lái)調(diào)整相機(jī)位置
    public float3 offset;

    private EntityManager manager;

    private void Awake()
    {
        if (instance != null && instance != this)
        {
            Destroy(gameObject);
            return;
        }

        instance = this;
        manager = World.DefaultGameObjectInjectionWorld.EntityManager;
    }

    private void LateUpdate()
    {
        if (ballEntity == null) { return; }

        Translation ballPos = manager.GetComponentData<Translation>(ballEntity);
        transform.position = ballPos.Value + offset;
    }
}

記得把相機(jī)腳本掛到main camera上!

System

  1. MoveSystem:
    控制玩家移動(dòng),獲取玩家輸入放入一個(gè)float2中,具體的Mathematics相關(guān)class可以看官方文檔,這是一個(gè)用起來(lái)比vector要快的東西(因?yàn)镋CS是數(shù)據(jù)驅(qū)動(dòng),不用特別關(guān)注object):
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine;

public class MoveSystem : SystemBase
{
    protected override void OnUpdate()
    {
        float deltaTime = Time.DeltaTime;

        float2 curInput = new float2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

        Entities.ForEach((ref PhysicsVelocity vel, ref MoveComponent speedData) =>
        {
            float2 newVel = vel.Linear.xz;

            newVel += curInput * speedData.moveSpeed * deltaTime;

            vel.Linear.xz = newVel;
        }).Run();
    }
}

相關(guān)要點(diǎn):
ForEach就是對(duì)包含參數(shù)相關(guān)Component的entity在每一幀都進(jìn)行一定的操作,其中ref關(guān)鍵字表示對(duì)數(shù)據(jù)進(jìn)行讀取也可以修改,而in關(guān)鍵字表示對(duì)數(shù)據(jù)只讀,而且in一定要全部放在ref后面。
后面的的.Run()表示在主線程中運(yùn)行,如果要在子線程可以使用Schedule。

  1. RotateSystem:
    控制收集物旋轉(zhuǎn)的system,具體的quaternion用法可以參考官方文檔:
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

public class RotateSystem : SystemBase
{
    protected override void OnUpdate()
    {

        float deltaTime = Time.DeltaTime;

        Entities.ForEach((ref Rotation rotation, in RotationComponent rotationSpeed) =>
        {
            rotation.Value = math.mul(rotation.Value, quaternion.RotateX(math.radians(rotationSpeed.rotateSpeed * deltaTime)));
            rotation.Value = math.mul(rotation.Value, quaternion.RotateY(math.radians(rotationSpeed.rotateSpeed * deltaTime)));
            rotation.Value = math.mul(rotation.Value, quaternion.RotateZ(math.radians(rotationSpeed.rotateSpeed * deltaTime)));
        }).Run();
    }
}

記得這時(shí)候往你的object上面掛component!如果想讓玩家移動(dòng)就掛movecomponent,讓收集物旋轉(zhuǎn)就掛上rotationcomponent??梢韵胍幌?,如果你往收集物上掛了movecomponent會(huì)發(fā)生什么?為什么會(huì)這樣?

這時(shí)候你的收集物應(yīng)該是旋轉(zhuǎn)的,玩家小球可以通過(guò)wasd或者方向鍵控制移動(dòng):
DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)
3. CollectSystem:
然后就是最難的碰撞收集系統(tǒng)了!本來(lái)在mono中兩三行就可以解決的問(wèn)題,現(xiàn)在要寫(xiě)幾十行才能解決!但是對(duì)于后期優(yōu)化以及性能上的提升,這些困難都不算什么!
相關(guān)的解釋說(shuō)明都在注釋中了:

using Unity.Entities;
using Unity.Collections;
using Unity.Physics;
using Unity.Physics.Systems;

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
public class CollectSystem : SystemBase
{   
    //用bufferSystem來(lái)處理這些碰撞事件
    private EndFixedStepSimulationEntityCommandBufferSystem bufferSystem;
    //初始化entity的物理世界
    private BuildPhysicsWorld buildPhysicsWorld;
    private StepPhysicsWorld stepPhysicsWorld;

    protected override void OnCreate()
    {
        bufferSystem = World.GetOrCreateSystem<EndFixedStepSimulationEntityCommandBufferSystem>();
        buildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
        stepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
    }

    protected override void OnUpdate()
    {
        //每一幀都添加一個(gè)triggerjob來(lái)進(jìn)行碰撞判斷,因?yàn)樾枰袛嗟氖怯蠱oveComponent的玩家
        //以及有DeleteTag的收集物,所以就要在job中進(jìn)行選擇
        Dependency = new TriggerJob
        {
            speedEntities = GetComponentDataFromEntity<MoveComponent>(),
            entitiesToDelete = GetComponentDataFromEntity<DeleteTag>(),
            commandBuffer = bufferSystem.CreateCommandBuffer(),
        }.Schedule(stepPhysicsWorld.Simulation, ref buildPhysicsWorld.PhysicsWorld, Dependency);

        //把job傳遞到buffer中
        bufferSystem.AddJobHandleForProducer(Dependency);

    }


    //創(chuàng)建一個(gè)triggerjob來(lái)進(jìn)行碰撞處理
    private struct TriggerJob : ITriggerEventsJob
    {   
        //初始化處理的entity
        public ComponentDataFromEntity<MoveComponent> speedEntities;
        [ReadOnly] public ComponentDataFromEntity<DeleteTag> entitiesToDelete;
        public EntityCommandBuffer commandBuffer;

        public void Execute(TriggerEvent triggerEvent)
        {
            TestEntityTrigger(triggerEvent.EntityA, triggerEvent.EntityB);
            TestEntityTrigger(triggerEvent.EntityB, triggerEvent.EntityA);
        }

        //處理碰撞,如果被碰撞的物品沒(méi)有DeleteTag,就把DeleteTag掛上去,移除它的物理組件
        private void TestEntityTrigger(Entity entity1, Entity entity2)
        {
            if (speedEntities.HasComponent(entity1))
            {
                if (entitiesToDelete.HasComponent(entity2)) { return; }
                commandBuffer.AddComponent<DeleteTag>(entity2);
                commandBuffer.RemoveComponent<PhysicsCollider>(entity2);
            }
        }
    }
}
  1. DeleteSystem:
    控制刪除有deletetag的entity的system:
using Unity.Entities;

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
//這里添加一個(gè)屬性,就是在collectionsystem發(fā)生之后再更新,因?yàn)橐扰鲎仓笤龠M(jìn)行處理
[UpdateAfter(typeof(CollectSystem))]
public class DeleteSystem : SystemBase
{
    private EndFixedStepSimulationEntityCommandBufferSystem _endSimulationECBSystem;

    protected override void OnStartRunning()
    {
        _endSimulationECBSystem = World.GetOrCreateSystem<EndFixedStepSimulationEntityCommandBufferSystem>();
    }

    protected override void OnUpdate()
    {
        var ecb = _endSimulationECBSystem.CreateCommandBuffer();

        Entities
            .WithAll<DeleteTag>()
            .WithoutBurst()
            .ForEach((Entity entity) =>
            {    
                //修改分?jǐn)?shù)
                GameManager.instance.IncreaseScore();
                ecb.DestroyEntity(entity);
            }).Run();
        _endSimulationECBSystem.AddJobHandleForProducer(Dependency);
    }
}

這里ForEach之前有一系列限定條件,比如.WithAll()的意思就是對(duì)帶有deletetag的entity執(zhí)行下面的操作,這樣能更加方便的進(jìn)行處理,所以大部分情況下entity都會(huì)被打一個(gè)標(biāo)簽來(lái)區(qū)別其他entity

最后需要進(jìn)行的一些操作

  • 創(chuàng)建一個(gè)空物體放入GameManager,并且進(jìn)行相關(guān)配置(可以在play模式下打開(kāi)insaneMode看看ECS的強(qiáng)大性能提升):
    DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)
  • 在play模式下調(diào)整Camera中的相機(jī)跟隨參數(shù),讓鏡頭舒服:

DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)

太棒啦!

太棒啦!你成功的使用了目前領(lǐng)先的開(kāi)發(fā)模式開(kāi)發(fā)了一個(gè)小游戲,雖然這個(gè)小游戲的功能在mono中實(shí)現(xiàn)的話可以很簡(jiǎn)單的實(shí)現(xiàn),但是隨著工程規(guī)模的擴(kuò)大以及性能需求的提高,ECS只會(huì)愈發(fā)強(qiáng)大!因?yàn)槟壳癉OTS相關(guān)教程不完善,所以如果在上述開(kāi)發(fā)中碰到問(wèn)題主要需要參考官方文檔以及一些論壇大牛的解答,想要更深入的理解還需要更多項(xiàng)目的磨練。

3. 參考文檔

Entities最新版本0.17的官方說(shuō)明文檔:
https://docs.unity3d.com/Packages/com.unity.entities@0.17/api/Unity.Entities.html
油管ECS大神Turbo的說(shuō)明文檔:
https://www.tmg.dev/tuts/roll-a-ball-entities-0-17/文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-412450.html

到了這里,關(guān)于DOTS介紹+Unity DOTS-MAN小游戲項(xiàng)目實(shí)戰(zhàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Unity小游戲】游戲開(kāi)發(fā)案例-Unity打造暢玩無(wú)阻的小游戲(上)

    【Unity小游戲】游戲開(kāi)發(fā)案例-Unity打造暢玩無(wú)阻的小游戲(上)

    乒乓克隆 使用立方體建造競(jìng)技場(chǎng)、球拍和球。 移動(dòng)球和球拍。 擊球并得分。 讓相機(jī)感受到?jīng)_擊力。 給游戲一個(gè)抽象的霓虹燈外觀。 這是有關(guān)基礎(chǔ)游戲的系列教程中的第一個(gè)教程。在其中,我們將創(chuàng)建一個(gè)簡(jiǎn)單的 Pong 克隆。 本教程是使用 Unity 2021.3.16f1 制作的。 本系列將涵

    2024年02月13日
    瀏覽(27)
  • 【Unity小游戲】《捕魚(yú)達(dá)人》小游戲來(lái)啦~ 有源碼下載【文末送書(shū)】

    ??博客主頁(yè):https://blog.csdn.net/zhangay1998 ??歡迎點(diǎn)贊 ?? 收藏 ?留言 ?? 如有錯(cuò)誤敬請(qǐng)指正! ??本文由 呆呆敲代碼的小Y 原創(chuàng),首發(fā)于 CSDN ?? ??未來(lái)很長(zhǎng),值得我們?nèi)Ρ几案篮玫纳?

    2023年04月08日
    瀏覽(58)
  • Unity小游戲——迷你拼圖

    拼圖演示 資源:? 鏈接:https://pan.baidu.com/s/1BGeSmRCO_WZRUyl3MxefGw? 提取碼:0n4a 排列拼圖碎片,拼出最后的圖案??梢渣c(diǎn)住碎片的任意位置拖動(dòng);點(diǎn)擊\\\"重來(lái)\\\"按鈕,可以回到最初狀態(tài)重新開(kāi)始。 有很多電腦游戲的原型來(lái)自于現(xiàn)實(shí)世界中的玩具,拼圖游戲就是其中的一個(gè)代表。 本

    2024年02月14日
    瀏覽(22)
  • Unity - 微信小游戲

    Unity - 微信小游戲

    總參考:Unity WebGL 微信小游戲適配方案(公測(cè)) ? 下載?Unity插件,并導(dǎo)入至游戲項(xiàng)目中,版本更新請(qǐng)查看更新日志 請(qǐng)查閱推薦引擎版本,安裝時(shí)選擇 WebGL 組件 最終選擇 Unity2021.2.5f1c1 InstantGame 前往Node官網(wǎng)安裝長(zhǎng)期穩(wěn)定版 之前已安裝 v16.17.0 前往微信開(kāi)發(fā)者工具下載安裝 Stable

    2024年02月06日
    瀏覽(55)
  • Unity 開(kāi)發(fā)微信小游戲

    Unity 開(kāi)發(fā)微信小游戲

    今天給大家分享一下我近期用Unity開(kāi)發(fā)微信小游戲的經(jīng)過(guò)和踩坑; 微信小游戲就是微信小程序,小游戲是小程序的一個(gè)子集,小游戲是一種特殊的小程序;這篇文章建議大家收藏,干貨滿滿 Unity開(kāi)發(fā)微信小程序 Unity 3D下載官網(wǎng) Unity轉(zhuǎn)化小程序的Package包下載地址 微信開(kāi)發(fā)者工

    2024年02月09日
    瀏覽(26)
  • unity小球吃金幣小游戲

    unity小球吃金幣小游戲

    鏈接放在這里 unity小球吃金幣小游戲-Unity3D文檔類資源-CSDN下載 這是我在學(xué)完虛擬現(xiàn)實(shí)技術(shù)這門(mén)課程后利用unity所做的小球吃金幣小游戲,里面有源碼和作品源文件,用u更多下載資源、學(xué)習(xí)資料請(qǐng)?jiān)L問(wèn)CSDN下載頻道. https://download.csdn.net/download/m0_57324918/85604051 1創(chuàng)建Roll A Ball小球吃

    2023年04月08日
    瀏覽(23)
  • Unity——2D小游戲筆記整理

    Unity——2D小游戲筆記整理

    【每日一句:清晨和夜晚都請(qǐng)用盡全力去生活】 目錄 一、環(huán)境搭建 二、人物 三、相機(jī)跟隨人物移動(dòng) 四、平鋪精靈 五、血條跟隨敵人行走 六、腳本邏輯 【玩家行走方法】 【玩家跳躍方法】 【改變玩家血量值方法】 【創(chuàng)建玩家子彈方法】 【主角血量,改變血條遮罩】 【敵

    2024年02月09日
    瀏覽(28)
  • 【Unity】小球吃方磚小游戲

    【Unity】小球吃方磚小游戲

    目錄 游戲背景 游戲開(kāi)發(fā) ????????2.1場(chǎng)景布置 ????????2.2小球運(yùn)動(dòng) ????????2.3鏡頭跟蹤 ????????2.4吃掉方磚 ? ? ? ? 2.5結(jié)束提示 游戲錄制 ? ? ? ? ? 用wasd(↑←↓→)操控小球進(jìn)行平面滑動(dòng),小球觸碰會(huì)原地打轉(zhuǎn)的立方體后立方體會(huì)消失,消除5個(gè)小球后提示

    2024年02月09日
    瀏覽(18)
  • 【抖音小游戲】 Unity制作抖音小游戲方案 最新完整詳細(xì)教程來(lái)襲【持續(xù)更新】
  • unity轉(zhuǎn)抖音小游戲筆記

    unity轉(zhuǎn)抖音小游戲筆記

    一.unity版本選擇2019.4.8f1 二.需從BGDT內(nèi)安裝以下插件 StarkMini for Unity?:基礎(chǔ)小包改造 sdk,提供游戲改造小包的框架 Stark Asset Analyser?:基于 starkmini 的自動(dòng)化小包工具 ? ? https://microapp.bytedance.com/docs/zh-CN/mini-game/rd-to-SCgame/minify/overall 三.打開(kāi)資源配置編輯器 ByteGame-StarkMini-Open

    2023年04月08日
    瀏覽(50)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包