So first of all, I would like to spawn a GamObject
, and then convert it to an entity, through code.
Then, since some pretty important scripts need to communicate with it, and the GameObject
itself has one or two scripts on it, I would like the Monobehaviour
scripts to be able to call functions (voids) that are in the GameObject
(this GameObject
would now be an entity) script(s).
I would love any help on this since I am spawning a lot of these GameObject
s at once… and by doing that, I’m slowing down the performance.
Here is a most basic example showing how you can communicate with a specific entity from a MonoBehaviour
:
- Attach
PlayerAuthoring
& ConvertToEntity
components to a capsule shape GameObject
& make sure it’s visible to main camera
- Attach
PlayerController
to an empty GameObject
- Hit play; capsule shape should move according to your
Horizontal
/ Vertical
axis input.
PlayerAuthoring.cs
using UnityEngine;
using Unity.Entities;
namespace Sandbox
{
public class PlayerAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
[SerializeField] int _index;
void IConvertGameObjectToEntity.Convert ( Entity e , EntityManager dst , GameObjectConversionSystem cs )
{
dst.AddComponentData( e , new Player{
Index = _index
} );
dst.AddComponent<HumanInput>( e );
}
}
}
PlayerController.cs
using UnityEngine;
using Unity.Mathematics;
using Unity.Collections;
using Unity.Entities;
using Unity.Transforms;
namespace Sandbox
{
public class PlayerController : MonoBehaviour
{
[SerializeField] int _index;
[SerializeField] float _speed = 5f;
EndSimulationEntityCommandBufferSystem _commandBufferSystem;
EntityQuery _query;
void Start ()
{
var world = World.DefaultGameObjectInjectionWorld;
var entityManager = world.EntityManager;
_commandBufferSystem = world.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
_query = entityManager.CreateEntityQuery( typeof(Player) , typeof(HumanInput) );
}
void Update ()
{
int numHumanPlayers = _query.CalculateEntityCount();
if( numHumanPlayers!=0 )
{
var cmd = _commandBufferSystem.CreateCommandBuffer();
var entityArray = _query.ToEntityArray( Allocator.Temp );
var playerArray = _query.ToComponentDataArray<Player>( Allocator.Temp );
for( int i=0 ; i<numHumanPlayers ; i++ )
{
Player player = playerArray;
if( player.Index==_index )
{
Entity entity = entityArray*;
cmd.SetComponent( entity , new HumanInput{
Horizontal = Input.GetAxis("Horizontal") * _speed,
Vertical = Input.GetAxis("Vertical") * _speed
} );
}
}
}
}
}
public struct Player : IComponentData
{
public int Index;
}
public struct HumanInput : IComponentData
{
public float Horizontal, Vertical;
}
[UpdateInGroup( typeof(SimulationSystemGroup) )]
public partial class HumanInputSystem : SystemBase
{
protected override void OnCreate ()
{
base.OnCreate();
RequireForUpdate( EntityManager.CreateEntityQuery( typeof(HumanInput) ) );
}
protected override void OnUpdate ()
{
float deltaTime = Time.DeltaTime;
var camera = Camera.main;
if( camera==null )
{
Debug.LogWarning("main camera not found");
return;
}
var camTransform = camera.transform;
float3 dirforward = camTransform.forward;
float3 dirright = camTransform.right;
Entities
.WithChangeFilter<HumanInput>()
.ForEach( ( ref Translation translation , ref Rotation rotation , in HumanInput input ) =>
{
float3 stepforward = new float3(dirforward.x,0,dirforward.z) * input.Vertical;
float3 stepright = new float3(dirright.x,0,dirright.z) * input.Horizontal;
float3 step = ( stepforward + stepright )*deltaTime;
translation.Value += step;
if( math.any(step!=0) )
{
float3 movdir = math.normalize(step);
rotation.Value = quaternion.LookRotation( movdir , new float3(0,1,0) );
}
} )
.WithBurst()
.ScheduleParallel();
}
}
}