用Unity ECS DOTS做一个烟花,附代码
时间: 2023-12-03 07:42:22 浏览: 139
烟花源代码
3星 · 编辑精心推荐
以下是用 Unity ECS DOTS 实现的简单烟花示例代码:
```csharp
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
public class FireworkSystem : SystemBase
{
private EntityQuery fireworkQuery;
private EntityQuery explosionQuery;
protected override void OnCreate()
{
fireworkQuery = GetEntityQuery(typeof(Firework), typeof(Translation), typeof(Velocity));
explosionQuery = GetEntityQuery(typeof(Explosion), typeof(Translation));
}
protected override void OnUpdate()
{
// 更新烟花位置和速度
Entities.With(fireworkQuery).ForEach((ref Translation translation, ref Velocity velocity) =>
{
velocity.Value += new float3(0, -9.81f, 0) * Time.DeltaTime;
translation.Value += velocity.Value * Time.DeltaTime;
}).Run();
// 检查烟花是否需要爆炸
Entities.With(fireworkQuery).ForEach((Entity entity, ref Firework firework, ref Translation translation) =>
{
if (translation.Value.y <= firework.Height)
{
// 生成爆炸粒子
var explosionEntity = EntityManager.CreateEntity(typeof(Explosion), typeof(Translation));
EntityManager.SetComponentData(explosionEntity, new Translation { Value = translation.Value });
EntityManager.DestroyEntity(entity);
}
}).Run();
// 更新爆炸粒子位置和寿命
Entities.With(explosionQuery).ForEach((Entity entity, ref Explosion explosion, ref Translation translation) =>
{
explosion.Lifetime -= Time.DeltaTime;
if (explosion.Lifetime <= 0)
{
EntityManager.DestroyEntity(entity);
}
else
{
var size = explosion.Size * (1 - explosion.Lifetime / explosion.MaxLifetime);
translation.Value += explosion.Velocity * Time.DeltaTime;
EntityManager.SetComponentData(entity, new Scale { Value = size });
}
}).Run();
}
}
public struct Firework : IComponentData
{
public float Height;
public float3 Velocity;
}
public struct Explosion : IComponentData
{
public float Lifetime;
public float MaxLifetime;
public float3 Velocity;
public float Size;
}
public struct Velocity : IComponentData
{
public float3 Value;
}
public class FireworkSpawner : MonoBehaviour
{
public GameObject fireworkPrefab;
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
var mousePosition = Input.mousePosition;
var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, 10));
SpawnFirework(worldPosition);
}
}
private void SpawnFirework(float3 position)
{
var fireworkEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(fireworkPrefab, World.Active);
EntityManager.SetComponentData(fireworkEntity, new Translation { Value = position });
EntityManager.SetComponentData(fireworkEntity, new Firework { Height = Random.Range(5f, 15f), Velocity = new float3(Random.Range(-5f, 5f), Random.Range(5f, 15f), Random.Range(-5f, 5f)) });
EntityManager.AddComponentData(fireworkEntity, new Velocity());
}
}
```
这个示例中,我们定义了 `Firework` 和 `Explosion` 两个组件,分别表示烟花和爆炸粒子。在 `FireworkSpawner` 中,我们监听鼠标左键点击事件,然后在鼠标位置生成一个烟花。在 `FireworkSystem` 中,我们使用 `Translation` 和 `Velocity` 组件来更新烟花的位置和速度,并且在烟花达到一定高度时生成爆炸粒子。爆炸粒子的位置和大小会随时间变化,当寿命结束时,会自动销毁。
阅读全文