This does not work, ships end up at 0,0,0, they should end up 160-200 units away from origin.
This works fine if I forego the ECB and use TransformAspect directly (can’t get TransformAspect of a provisional entity), but writing WorldTransform alone does not seem to work. This is [UpdateInGroup(typeof(InitializationSystemGroup))], too, so physics copying or something shouldn’t interfere, right?
I tried this with LocalTransform instead, that also does not work.
PS: I am aware of the ECS RandomSpawn sample, but I need to understand why setting the component doesn’t work here; and also scheduling a job for this feels quite off (but is a great tool once this becomes fully procgen population of the game world - current system is a test system only)
WorldTransform is not for user writing but only reading. You should use LocalTransform for that (and data from parent if you have hierarchy, or ParentTransform which is storing parent WorldTransform)
Thanks. However, Local Transform also doesn’t work in my example.
In fact, it gets weirder, the component is set, but LocalToWorld still reflects the old world transform.
Decorating the system with either
[WriteGroup(typeof(LocalTransform)]
[WriteGroup(typeof(LocalToWorld)]
[WriteGroup(typeof(WorldTransform)] or
[WriteGroup(typeof(TransformAspect)]
using Jovian.Components;
using Sisus.Debugging;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Rendering;
using Unity.Transforms;
using Random = UnityEngine.Random;
namespace Jovian
{
[RequireMatchingQueriesForUpdate]
[UpdateInGroup(typeof(InitializationSystemGroup))]
public partial struct VesselSpawningSystem : ISystem
{
private EntityQuery _bubbles;
public void OnCreate(ref SystemState state)
{
_bubbles = state.EntityManager.CreateEntityQuery(typeof(Bubble), typeof(TagRequestSpawn));
state.RequireForUpdate<ShipRegistryElement>();
state.RequireForUpdate<TagRequestSpawn>();
}
public void OnDestroy(ref SystemState state)
{
_bubbles.Dispose();
}
public void OnUpdate(ref SystemState state)
{
var rolling = 0;
var ecb = new EntityCommandBuffer(Allocator.Temp);
var registry = SystemAPI.GetSingletonBuffer<ShipRegistryElement>();
foreach (var bubble in SystemAPI.Query<Bubble>().WithAll<TagRequestSpawn>())
{
for (var i = 0; i < 10; i++)
{
var ship = ecb.Instantiate(registry[rolling++ % registry.Length].prefabs);
var transform = LocalTransform.FromPositionRotation(
Random.onUnitSphere * Random.Range(160, 200),
quaternion.identity);
ecb.SetComponent(ship, transform);
//ecb.SetComponentForLinkedEntityGroup(ship, WTFisaMASK, new ReqBubbleEntry {root = bubble});
//Important, so freshly spawned ships do not leak into the void world (or are rendered)
ecb.RemoveComponent<PhysicsWorldIndex>(ship);
ecb.AddComponent<DisableRendering>(ship);
}
//all bubble requests have been processes, remove them all.
ecb.RemoveComponent<TagRequestSpawn>(bubble.root);
Dev.Log($"Spawning {rolling} ships in {bubble.root}");
}
ecb.Playback(state.EntityManager);
ecb.Dispose();
}
}
public struct TagRequestSpawn : IComponentData
{
}
}
Well, you’re using physics (we don’t use that since the beginning) can’t say much about how it affects stuff these days in 1.0. Out of curiosity - where entity will appear if you comment lines 50 and 51?
Something, likely DisableRendering, causes LocalToWorld from being updated. Which is both sensible and insensible. The combined Matrix is used by a UI system I use to “see” the invisible entities.
Oddly enough WorldTransform doesn’t seem to work properly, especially when physics get involved. Documentation says it’s reflecting one thing, but on my side it doesn’t even update. I’ve mentioned that here - WorldTransform doesn't change on child entity .
There are quite a few basic things not working properly. Sometimes I question if it’s actually a bug or some kind of a feature, cuz it’s so basic - it should work day 1.
I’m refactoring my system of child entities to something that spawns an entirely unrelated set of entities for UI representation, and then establishes links itself.
Those Unity structures (parent/child, linkedentitygroup, etc.) are just too opaque and unreliable for someone not knowing them inside out.
Spawning an entity with physcis and set its position by setting WorldTransform and LocalTransform at the same time between FixedStepSimulationGroup and TransformSystemGroup solved this problem.