【不用找素材】ECS 游戏Demo制作教程(3) 1.17

这篇具有很好参考价值的文章主要介绍了【不用找素材】ECS 游戏Demo制作教程(3) 1.17。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、生成墓碑

新建脚本如下:

using Unity.Entities;
using Unity.Mathematics;

namespace ECSdemo
{
    public struct GraveyardRandom : IComponentData
    {
        public Random Value;
    }

}

扩充GraveyardMono如下:

using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using Random = Unity.Mathematics.Random;

namespace ECSdemo
{
    public class GraveyardMono : MonoBehaviour
    {
        public float2 FieldDimensions;
        //float2 结构体表示一个包含两个 float 字段的结构体,记得引用命名空间
        public int NumberTombstonesToSpawn;
        //想要跟踪的数量
        public GameObject TombstonePrefab;
        //墓碑预制件

        public uint RandomSeed;
    }

    public class GraveyardBaker : Baker<GraveyardMono>
    {
        public override void Bake(GraveyardMono authoring)
        {
            AddComponent(new GraveyardProperties
            {
                FieldDimensions = authoring.FieldDimensions,
                NumberTombstonesToSpawn = authoring.NumberTombstonesToSpawn,
                TombstonePrefab = GetEntity(authoring.TombstonePrefab)
                //GetEntity:把GameObject变成Entity
            });

            AddComponent(new GraveyardRandom
            {
                Value = Random.CreateFromIndex(authoring.RandomSeed)
            }) ;
        }
    }

}

赋个值

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

这边也能看到了

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

再写个新脚本

using Unity.Entities;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;
    }
}

添加新脚本

using Unity.Burst;
using Unity.Entities;

namespace ECSdemo
{
    [BurstCompile]
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    public partial struct SpawnTombstoneSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            
        }
        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
            
        }
        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.Enabled = false;
        }
    }
}

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

点击运行就能看到啦

继续更新如下脚本:

using Unity.Entities;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;

        public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
        public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;
    
    }
}
using ECSdemo;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

namespace ECSdemo
{
    [BurstCompile]
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    public partial struct SpawnTombstoneSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<GraveyardProperties>();
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.Enabled = false;
            var graveyardEntity = SystemAPI.GetSingletonEntity<GraveyardProperties>();
            var graveyard = SystemAPI.GetAspectRW<GraveyardAspect>(graveyardEntity);

            var ecb = new EntityCommandBuffer(Allocator.Temp);
            
            for (var i = 0; i < graveyard.NumberTombstonesToSpawn; i++)
            {
                ecb.Instantiate(graveyard.TombstonePrefab);               
            }
            ecb.Playback(state.EntityManager);
        }
    }
}

点击运行,能看见有了很多墓碑,应该有250个

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

继续更新代码,给墓碑随机位置

using ECSdemo;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

namespace ECSdemo
{
    [BurstCompile]
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    public partial struct SpawnTombstoneSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<GraveyardProperties>();
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.Enabled = false;
            var graveyardEntity = SystemAPI.GetSingletonEntity<GraveyardProperties>();
            var graveyard = SystemAPI.GetAspectRW<GraveyardAspect>(graveyardEntity);

            var ecb = new EntityCommandBuffer(Allocator.Temp);
            
            for (var i = 0; i < graveyard.NumberTombstonesToSpawn; i++)
            {
                var newTombstone = ecb.Instantiate(graveyard.TombstonePrefab);        
                var newTombstoneTransform=graveyard.GetRandomTombstoneTransform();
                ecb.SetComponent(newTombstone,new LocalToWorldTransform { Value = newTombstoneTransform });

            }
            ecb.Playback(state.EntityManager);
        }
    }
}
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect _transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;

        public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
        public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;

        public UniformScaleTransform GetRandomTombstoneTransform()
        {
            return new UniformScaleTransform
            {
                Position = GetRandomPosition(),
                Rotation = quaternion.identity,
                Scale =1f
            };
        }

        private float3 GetRandomPosition()
        {
            float3 randomPosition;
            
            randomPosition = _graveyardRandom.ValueRW.Value.NextFloat3(MinCorner, MaxCorner);
            
            return randomPosition;
        }

        private float3 MinCorner => _transformAspect.Position - HalfDimensions;
        private float3 MaxCorner => _transformAspect.Position + HalfDimensions;
        private float3 HalfDimensions => new()
        {
            x = _graveyardProperties.ValueRO.FieldDimensions.x * 0.5f,
            y = 0f,
            z = _graveyardProperties.ValueRO.FieldDimensions.y * 0.5f
        };



    }
}

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

随机位置墓碑出来了!(调整了下大脑和地板的大小)

using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect _transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;

        public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
        public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;

        public UniformScaleTransform GetRandomTombstoneTransform()
        {
            return new UniformScaleTransform
            {
                Position = GetRandomPosition(),
                Rotation = GetRandomRotation(),
                Scale = GetRandomScale(0.5f)
            };
        }

        private float3 GetRandomPosition()
        {
            float3 randomPosition;
            do
            {
                randomPosition = _graveyardRandom.ValueRW.Value.NextFloat3(MinCorner, MaxCorner);
            } while (math.distancesq(_transformAspect.Position, randomPosition)<=BRAIN_SAFETY_RADIUS_SQ);
            
            
            return randomPosition;
        }

        private float3 MinCorner => _transformAspect.Position - HalfDimensions;
        private float3 MaxCorner => _transformAspect.Position + HalfDimensions;
        private float3 HalfDimensions => new()
        {
            x = _graveyardProperties.ValueRO.FieldDimensions.x * 0.5f,
            y = 0f,
            z = _graveyardProperties.ValueRO.FieldDimensions.y * 0.5f
        };
        private const float BRAIN_SAFETY_RADIUS_SQ = 100;

        private quaternion GetRandomRotation() => quaternion.RotateY(_graveyardRandom.ValueRW.Value.NextFloat(-0.25f, 0.25f));
        private float GetRandomScale(float min) => _graveyardRandom.ValueRW.Value.NextFloat(min, 1f);

    }
}

继续更新代码,产生随机大小

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

二、生成僵尸

添加新脚本

using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;

namespace TMG.Zombies
{
    public struct ZombieSpawnPoints : IComponentData
    {
        public NativeArray<float3> Value;
    }
}

更新脚本

using TMG.Zombies;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using Random = Unity.Mathematics.Random;

namespace ECSdemo
{
    public class GraveyardMono : MonoBehaviour
    {
        public float2 FieldDimensions;
        //float2 结构体表示一个包含两个 float 字段的结构体,记得引用命名空间
        public int NumberTombstonesToSpawn;
        //想要跟踪的数量
        public GameObject TombstonePrefab;
        //墓碑预制件

        public uint RandomSeed;
    }

    public class GraveyardBaker : Baker<GraveyardMono>
    {
        public override void Bake(GraveyardMono authoring)
        {
            AddComponent(new GraveyardProperties
            {
                FieldDimensions = authoring.FieldDimensions,
                NumberTombstonesToSpawn = authoring.NumberTombstonesToSpawn,
                TombstonePrefab = GetEntity(authoring.TombstonePrefab)
                //GetEntity:把GameObject变成Entity
            });

            AddComponent(new GraveyardRandom
            {
                Value = Random.CreateFromIndex(authoring.RandomSeed)
            }) ;
            AddComponent<ZombieSpawnPoints>();
        }
    }

}

using TMG.Zombies;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect _transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;
        private readonly RefRW<ZombieSpawnPoints> _zombieSpawnPoints;

        public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
        public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;

        public NativeArray<float3> ZombieSpawnPoints
        {
            get => _zombieSpawnPoints.ValueRO.Value;
            set => _zombieSpawnPoints.ValueRW.Value=value;
        }

        public UniformScaleTransform GetRandomTombstoneTransform()
        {
            return new UniformScaleTransform
            {
                Position = GetRandomPosition(),
                Rotation = GetRandomRotation(),
                Scale = GetRandomScale(0.5f)
            };
        }

        private float3 GetRandomPosition()
        {
            float3 randomPosition;
            do
            {
                randomPosition = _graveyardRandom.ValueRW.Value.NextFloat3(MinCorner, MaxCorner);
            } while (math.distancesq(_transformAspect.Position, randomPosition)<=BRAIN_SAFETY_RADIUS_SQ);
            
            
            return randomPosition;
        }

        private float3 MinCorner => _transformAspect.Position - HalfDimensions;
        private float3 MaxCorner => _transformAspect.Position + HalfDimensions;
        private float3 HalfDimensions => new()
        {
            x = _graveyardProperties.ValueRO.FieldDimensions.x * 0.5f,
            y = 0f,
            z = _graveyardProperties.ValueRO.FieldDimensions.y * 0.5f
        };
        private const float BRAIN_SAFETY_RADIUS_SQ = 100;

        private quaternion GetRandomRotation() => quaternion.RotateY(_graveyardRandom.ValueRW.Value.NextFloat(-0.25f, 0.25f));
        private float GetRandomScale(float min) => _graveyardRandom.ValueRW.Value.NextFloat(min, 1f);

    }
}
using ECSdemo;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

namespace ECSdemo
{
    [BurstCompile]
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    public partial struct SpawnTombstoneSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<GraveyardProperties>();
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.Enabled = false;
            var graveyardEntity = SystemAPI.GetSingletonEntity<GraveyardProperties>();
            var graveyard = SystemAPI.GetAspectRW<GraveyardAspect>(graveyardEntity);

            var ecb = new EntityCommandBuffer(Allocator.Temp);
            var spawnPionts = new NativeList<float3>(Allocator.Temp);
            var tombstoneOffset = new float3(0f, -2f, 1f);

            for (var i = 0; i < graveyard.NumberTombstonesToSpawn; i++)
            {
                var newTombstone = ecb.Instantiate(graveyard.TombstonePrefab);        
                var newTombstoneTransform=graveyard.GetRandomTombstoneTransform();
                ecb.SetComponent(newTombstone,new LocalToWorldTransform { Value = newTombstoneTransform });
                var newZombieSpawnPoint = newTombstoneTransform.Position + tombstoneOffset;
                spawnPionts.Add(newZombieSpawnPoint);
            }
            graveyard.ZombieSpawnPoints = spawnPionts.ToArray(Allocator.Persistent);

            ecb.Playback(state.EntityManager);
        }
    }
}

做一个僵尸预制体,要确保父物体y轴为0,也就是脚踩地面上

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏

更新脚本

using Unity.Entities;
using Unity.Mathematics;

namespace ECSdemo
{
    public struct GraveyardProperties : IComponentData
        //继承这个接口,让这个结构体变成组件,记得引用命名空间
    {
        public float2 FieldDimensions;
        //float2 结构体表示一个包含两个 float 字段的结构体,记得引用命名空间
        public int NumberTombstonesToSpawn;
        //想要跟踪的数量
        public Entity TombstonePrefab;
        //墓碑预制件
        public Entity ZombiePrefab;
        public float ZombieSpawnRate;

    }


    public struct ZombieSpawnTimer:IComponentData
    {
        public float Value;
    }

}


using TMG.Zombies;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using Random = Unity.Mathematics.Random;

namespace ECSdemo
{
    public class GraveyardMono : MonoBehaviour
    {
        public float2 FieldDimensions;
        //float2 结构体表示一个包含两个 float 字段的结构体,记得引用命名空间
        public int NumberTombstonesToSpawn;
        //想要跟踪的数量
        public GameObject TombstonePrefab;
        //墓碑预制件

        public uint RandomSeed;
        public GameObject Zombieprefab;
        public float ZombieSpawnRate;
    }

    public class GraveyardBaker : Baker<GraveyardMono>
    {
        public override void Bake(GraveyardMono authoring)
        {
            AddComponent(new GraveyardProperties
            {
                FieldDimensions = authoring.FieldDimensions,
                NumberTombstonesToSpawn = authoring.NumberTombstonesToSpawn,
                TombstonePrefab = GetEntity(authoring.TombstonePrefab),
                //GetEntity:把GameObject变成Entity
                ZombiePrefab=GetEntity(authoring.Zombieprefab),
                ZombieSpawnRate= authoring.ZombieSpawnRate
            });

            AddComponent(new GraveyardRandom
            {
                Value = Random.CreateFromIndex(authoring.RandomSeed)
            }) ;
            AddComponent<ZombieSpawnPoints>();
            AddComponent<ZombieSpawnTimer>();
        }
    }

}

进行一个赋值

【不用找素材】ECS 游戏Demo制作教程(3) 1.17,游戏文章来源地址https://www.toymoban.com/news/detail-798849.html

using TMG.Zombies;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;

namespace ECSdemo
{
    public readonly partial struct GraveyardAspect:IAspect
    {
        public readonly Entity Entity;

        private readonly TransformAspect _transformAspect;

        private readonly RefRO<GraveyardProperties> _graveyardProperties;
        private readonly RefRW<GraveyardRandom> _graveyardRandom;
        private readonly RefRW<ZombieSpawnPoints> _zombieSpawnPoints;
        private readonly RefRW<ZombieSpawnTimer> _zombieSpawnTimer;

        public int NumberTombstonesToSpawn => _graveyardProperties.ValueRO.NumberTombstonesToSpawn;
        public Entity TombstonePrefab => _graveyardProperties.ValueRO.TombstonePrefab;

        public NativeArray<float3> ZombieSpawnPoints
        {
            get => _zombieSpawnPoints.ValueRO.Value;
            set => _zombieSpawnPoints.ValueRW.Value=value;
        }

        public UniformScaleTransform GetRandomTombstoneTransform()
        {
            return new UniformScaleTransform
            {
                Position = GetRandomPosition(),
                Rotation = GetRandomRotation(),
                Scale = GetRandomScale(0.5f)
            };
        }

        private float3 GetRandomPosition()
        {
            float3 randomPosition;
            do
            {
                randomPosition = _graveyardRandom.ValueRW.Value.NextFloat3(MinCorner, MaxCorner);
            } while (math.distancesq(_transformAspect.Position, randomPosition)<=BRAIN_SAFETY_RADIUS_SQ);
            
            
            return randomPosition;
        }

        private float3 MinCorner => _transformAspect.Position - HalfDimensions;
        private float3 MaxCorner => _transformAspect.Position + HalfDimensions;
        private float3 HalfDimensions => new()
        {
            x = _graveyardProperties.ValueRO.FieldDimensions.x * 0.5f,
            y = 0f,
            z = _graveyardProperties.ValueRO.FieldDimensions.y * 0.5f
        };
        private const float BRAIN_SAFETY_RADIUS_SQ = 100;

        private quaternion GetRandomRotation() => quaternion.RotateY(_graveyardRandom.ValueRW.Value.NextFloat(-0.25f, 0.25f));
        private float GetRandomScale(float min) => _graveyardRandom.ValueRW.Value.NextFloat(min, 1f);

        public float2 GetRandomOffset()
        {
            return _graveyardRandom.ValueRW.Value.NextFloat2();
        }

        public float ZombieSpawnTimer
        {
            get => _zombieSpawnTimer.ValueRO.Value;
            set => _zombieSpawnTimer.ValueRW.Value = value;
        }
        public bool TimeToSpawnZombie => ZombieSpawnTimer <= 0f;

    }
}

到了这里,关于【不用找素材】ECS 游戏Demo制作教程(3) 1.17的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包