Search Unity

Rotation is not being inherited from parent

Discussion in 'Entity Component System' started by spaceemotion, Feb 5, 2020.

  1. spaceemotion

    spaceemotion

    Joined:
    Sep 29, 2015
    Posts:
    95
    I think something with serialization/hierarchy is wrong.
    The idea is to copy the current directional light's rotation onto an object.

    I've tested this on two unconnected gameobjects: one rotating one and one that has the "RotateTo" component. The rotation is properly being copied.

    If I have the mesh renderer in a child though, the link to the parent is severed. It does not know about the parent being rotated.

    Any ideas?

    upload_2020-2-5_23-6-19.png

    - rotation_original has the Rotate script (just adds degrees to the Y axis
    - parent has the RotateTo script
    - Rotation_clone has the mesh renderer, and not being updated



    Code (CSharp):
    1. namespace Game.ECS {
    2.     using System.Collections.Generic;
    3.     using Unity.Entities;
    4.     using Unity.Transforms;
    5.     using UnityEngine;
    6.  
    7.     public struct RotateTo : IComponentData {
    8.         public Entity target;
    9.     }
    10.  
    11.     [AddComponentMenu("Components/RotateTo")]
    12.     class RotateToProxy : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
    13.     {
    14.         public Transform Reference;
    15.  
    16.         public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    17.         {
    18.             dstManager.AddComponentData(entity, new RotateTo {
    19.                 target = conversionSystem.GetPrimaryEntity(Reference.gameObject),
    20.             });
    21.         }
    22.  
    23.         public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
    24.         {
    25.             referencedPrefabs.Add(Reference.gameObject);
    26.         }
    27.     }
    28.  
    29.     public class RotateToSystem : ComponentSystem {
    30.         private EntityQuery query;
    31.  
    32.         protected override void OnCreate() {
    33.             query = GetEntityQuery(
    34.                 ComponentType.ReadWrite<Rotation>(),
    35.                 ComponentType.ReadOnly<RotateTo>()
    36.             );
    37.         }
    38.  
    39.         protected override void OnUpdate() {
    40.             Entities.With(query).ForEach((ref Rotation rot, ref RotateTo rotateTo) => {
    41.                 var targetRotation = EntityManager.GetComponentData<Rotation>(rotateTo.target).Value;
    42.                 rot.Value = targetRotation;
    43.             });
    44.         }
    45.     }
    46. }
    47.  
     
    Last edited: Feb 5, 2020
  2. Fribur

    Fribur

    Joined:
    Jan 5, 2019
    Posts:
    136
    Update: was to quick, you have an issue with rotation, not scale. I keep the rsponse anyway in case it might help anybody.


    Might be related rotation being ignored by CopyTransformFromGameObjectSystem.cs.

    I keep "fixing" this issue for my own project since ~1year by doing the left changes to the original file (right):

    upload_2020-2-5_19-35-3.png
    Code (CSharp):
    1.     public class CopyTransformFromGameObjectSystem : JobComponentSystem
    2.     {
    3.         struct TransformStash
    4.         {
    5.             public float3 scale;
    6.             public float3 position;
    7.             public quaternion rotation;
    8.         }
    9.  
    10.         [BurstCompile]
    11.         struct StashTransforms : IJobParallelForTransform
    12.         {
    13.             public NativeArray<TransformStash> transformStashes;
    14.  
    15.             public void Execute(int index, TransformAccess transform)
    16.             {
    17.                 transformStashes[index] = new TransformStash
    18.                 {
    19.                     scale       = transform.localScale,
    20.                     rotation       = transform.rotation,
    21.                     position       = transform.position,
    22.                 };
    23.             }
    24.         }
    25.  
    26.         [BurstCompile]
    27.         struct CopyTransforms : IJobForEachWithEntity<LocalToWorld>
    28.         {
    29.             [DeallocateOnJobCompletion] public NativeArray<TransformStash> transformStashes;
    30.  
    31.             public void Execute(Entity entity, int index, ref LocalToWorld localToWorld)
    32.             {
    33.                 var transformStash = transformStashes[index];
    34.  
    35.                 localToWorld = new LocalToWorld
    36.                 {
    37.                     Value = float4x4.TRS(
    38.                         transformStash.position,
    39.                         transformStash.rotation,
    40.                         transformStash.scale)
    41.                 };
    42.             }
    43.         }
    44.  
     
  3. spaceemotion

    spaceemotion

    Joined:
    Sep 29, 2015
    Posts:
    95
    @Fribur Thanks for trying though! My best guess is that Unity simply ignores the transform if there's nothing to render and only includes children of MeshRenderers.

    Edit: I tried to force the relationship by editing my conversion system on the MonoBehvaior. The Parent and Child components don't even want to show up...

    Edit v2: Finally figured it out: traditional hierarchies dont work with dynamic colliders,
    so remember to remove them from your mesh renderers.
     
    Last edited: Feb 7, 2020