Will there be a tut for the 2019 version...

Tried to use this version for first time and the got a 1fps for my character system… :p…

You mean Unity 2019.x? if so, this is wrong forum section.

Thanks where sjould I put it…

2019.2 Beta
in
https://forum.unity.com/categories/betas-experimental-features.86/

Oh hold on, you are asking for tutorials/samples for ECS yes?
Correct me please, if I am wrong.

Can I move the thread to there without creating an new one…?

Yes

Well then, which tutorial / samples you are trying to run?
Does Unity editor itself works smoothly?
What are your work station parameters?

No unity editor do not response to any ket but the scene plays my player idle animation in 1 - 5fps…
I have to close the unity editor from task manager… Im using unity official tut and thirdperson assets

Does Unity 2018.x or 2017.x works on your work station?

Yes…

Ill share my ecs character system… If it would help… I have also found that getentities, inject and more has been depreciated… the new functions are implimented wrong in my code I think…

Yes, injection is deprecated, I’d follow their EntityComponentSystemSamples github closely for the latest updates/changes :slight_smile:

I got 20fps now… before using ecs I get 60 - 80fps… for my test scene…

Well without posting much information about your systems, it’s hard to state what’s wrong with it. We can only speculate what could be wrong. If you’ve got the time and won’t mind posting your systems, we can take a look and see what’s going on :slight_smile:

using System;
using Unity.Entities;
using UnityEngine;

[RequireComponent(typeof(CharacterData))]
public class CharacterUserInputData : MonoBehaviour
{
    public bool crouch;
    public bool m_Jump;
    public Vector2 m_Move;
}
public class CharacterUserInput : ComponentSystem
{
    private Transform m_Cam;                  // A reference to the main camera in the scenes transform
    private CharacterUserInputData Data;
    private EntityQuery query;

    protected override void OnCreate()
    {
        query = GetEntityQuery(ComponentType.ReadWrite<CharacterUserInputData>());
    }

    protected override void OnStartRunning()
    {
        // get the transform of the main camera
        if (Camera.main != null)
        {
            m_Cam = Camera.main.transform;
        }
        else
        {
            Debug.LogWarning(
                "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.");
            // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
        }
    }

    // Fixed update is called in sync with physics
    private void FixedUpdate(Vector3 forward, Vector3 right, bool hasCam, bool walk_Run, bool crouch, bool jump, float h, float v)
    {
        if (!Data.m_Jump)
        {
            Data.m_Jump = jump;
        }
        Data.crouch = crouch;

        // calculate move direction to pass to character
        if (hasCam)
        {
            // calculate camera relative direction to move:
            var m_CamForward = Vector3.Scale(forward, new Vector3(1, 0, 1)).normalized;
            Data.m_Move = v * m_CamForward + h * right;
        }
        else
        {
            // we use world-relative directions in the case of no main camera
            Data.m_Move = v * Vector3.forward + h * Vector3.right;
        }
#if !MOBILE_INPUT
        // walk speed multiplier
        if (walk_Run) Data.m_Move *= 0.5f;
#endif
    }

    protected override void OnUpdate()
    {
        bool crouch = Input.GetKey(KeyCode.C);
        float h = Input.GetAxis("Horizontal");
        bool jump = Input.GetButtonDown("Jump");
        float v = Input.GetAxis("Vertical");
        bool walk_Run = Input.GetKey(KeyCode.LeftShift);
        bool hasCam = m_Cam != null;
        Vector3 forward = m_Cam.forward;
        Vector3 right = m_Cam.right;
        Entities.With(query).ForEach((CharacterUserInputData data) => {Data = data; FixedUpdate(forward, right, hasCam, walk_Run, crouch,jump,h,v); });
    }
}
using Unity.Entities;
using UnityEngine;


[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class CharacterData : MonoBehaviour
{
    [SerializeField] public float m_MovingTurnSpeed = 360;
    [SerializeField] public float m_StationaryTurnSpeed = 180;
    [SerializeField] public float m_JumpPower = 12f;
    [Range(1f, 4f)] [SerializeField] public float m_GravityMultiplier = 2f;
    [SerializeField] public float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others
    [SerializeField] public float m_MoveSpeedMultiplier = 1f;
    [SerializeField] public float m_AnimSpeedMultiplier = 1f;
    [SerializeField] public float m_OrigGroundCheckDistance = 0.1f;
    [HideInInspector] public float m_CapsuleHeight;
    [HideInInspector] public Vector3 m_CapsuleCenter;
}

public class Character : ComponentSystem
{
    Transform transform;
    Rigidbody m_Rigidbody;
    Animator m_Animator;
    CapsuleCollider m_Capsule;
    CharacterData cData;
    CharacterUserInputData iData;
    bool m_IsGrounded;
    float m_GroundCheckDistance;
    const float k_Half = 0.5f;
    float m_TurnAmount;
    float m_ForwardAmount;
    Vector3 m_GroundNormal;
    bool m_Crouching;
    public EntityQuery query;
    protected override void OnCreate()
    {
        query = GetEntityQuery(ComponentType.ReadWrite<Transform>(), ComponentType.ReadWrite<Rigidbody>(), ComponentType.ReadWrite<Animator>(), ComponentType.ReadWrite<CapsuleCollider>(), ComponentType.ReadWrite<CharacterData>(), ComponentType.ReadWrite<CharacterUserInputData>());
    }


    public void Move(Vector3 move, bool crouch, bool jump)
    {

        // convert the world relative moveInput vector into a local-relative
        // turn amount and forward amount required to head in the desired
        // direction.
        if (move.magnitude > 1f) move.Normalize();
        move = transform.InverseTransformDirection(move);
        CheckGroundStatus();
        move = Vector3.ProjectOnPlane(move, m_GroundNormal);
        m_TurnAmount = Mathf.Atan2(move.x, move.z);
        m_ForwardAmount = move.z;

        ApplyExtraTurnRotation();

        // control and velocity handling is different when grounded and airborne:
        if (m_IsGrounded)
        {
            HandleGroundedMovement(crouch, jump);
        }
        else
        {
            HandleAirborneMovement();
        }

        ScaleCapsuleForCrouching(crouch);
        PreventStandingInLowHeadroom();

        // send input and other state parameters to the animator
        UpdateAnimator(move);
    }


    void ScaleCapsuleForCrouching(bool crouch)
    {
        if (m_IsGrounded && crouch)
        {
            if (m_Crouching) return;
            m_Capsule.height = m_Capsule.height / 2f;
            m_Capsule.center = m_Capsule.center / 2f;
            m_Crouching = true;
        }
        else
        {
            Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
            float crouchRayLength = cData.m_CapsuleHeight - m_Capsule.radius * k_Half;
            if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
            {
                m_Crouching = true;
                return;
            }
            m_Capsule.height = cData.m_CapsuleHeight;
            m_Capsule.center = cData.m_CapsuleCenter;
            m_Crouching = false;
        }
    }

    void PreventStandingInLowHeadroom()
    {
        // prevent standing up in crouch-only zones
        if (!m_Crouching)
        {
            Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
            float crouchRayLength = cData.m_CapsuleHeight - m_Capsule.radius * k_Half;
            if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
            {
                m_Crouching = true;
            }
        }
    }


    void UpdateAnimator(Vector3 move)
    {
        // update the animator parameters
        m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
        m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
        m_Animator.SetBool("Crouch", m_Crouching);
        m_Animator.SetBool("OnGround", m_IsGrounded);
        if (!m_IsGrounded)
        {
            m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
        }

        // calculate which leg is behind, so as to leave that leg trailing in the jump animation
        // (This code is reliant on the specific run cycle offset in our animations,
        // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
        float runCycle =
            Mathf.Repeat(
                m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + cData.m_RunCycleLegOffset, 1);
        float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
        if (m_IsGrounded)
        {
            m_Animator.SetFloat("JumpLeg", jumpLeg);
        }

        // the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,
        // which affects the movement speed because of the root motion.
        if (m_IsGrounded && move.magnitude > 0)
        {
            m_Animator.speed = cData.m_AnimSpeedMultiplier;
        }
        else
        {
            // don't use that while airborne
            m_Animator.speed = 1;
        }
    }


    void HandleAirborneMovement()
    {
        // apply extra gravity from multiplier:
        Vector3 extraGravityForce = (Physics.gravity * cData.m_GravityMultiplier) - Physics.gravity;
        m_Rigidbody.AddForce(extraGravityForce);

        m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? cData.m_OrigGroundCheckDistance : 0.01f;
    }


    void HandleGroundedMovement(bool crouch, bool jump)
    {
        // check whether conditions are right to allow a jump:
        if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
        {
            // jump!
            m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, cData.m_JumpPower, m_Rigidbody.velocity.z);
            m_IsGrounded = false;
            m_Animator.applyRootMotion = false;
            m_GroundCheckDistance = 0.1f;
        }
    }

    void ApplyExtraTurnRotation()
    {
        // help the character turn faster (this is in addition to root rotation in the animation)
        float turnSpeed = Mathf.Lerp(cData.m_StationaryTurnSpeed, cData.m_MovingTurnSpeed, m_ForwardAmount);
        transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
    }


    public void OnAnimatorMove()
    {
        // we implement this function to override the default root motion.
        // this allows us to modify the positional speed before it's applied.
        if (m_IsGrounded && Time.deltaTime > 0)
        {
            Vector3 v = (m_Animator.deltaPosition * cData.m_MoveSpeedMultiplier) / Time.deltaTime;

            // we preserve the existing y part of the current velocity.
            v.y = m_Rigidbody.velocity.y;
            m_Rigidbody.velocity = v;
        }
    }


    void CheckGroundStatus()
    {
        RaycastHit hitInfo;
#if UNITY_EDITOR
        // helper to visualise the ground check ray in the scene view
        Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
#endif
        // 0.1f is a small offset to start the ray from inside the character
        // it is also good to note that the transform position in the sample assets is at the base of the character
        if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
        {
            m_GroundNormal = hitInfo.normal;
            m_IsGrounded = true;
            m_Animator.applyRootMotion = true;
        }
        else
        {
            m_IsGrounded = false;
            m_GroundNormal = Vector3.up;
            m_Animator.applyRootMotion = false;
        }
    }
    protected override void OnStartRunning()
    {
        Entities.With(query).ForEach((Entity e, Rigidbody rig, CapsuleCollider cap, CharacterData _cData) =>
        {
            m_Rigidbody = rig;
            m_Capsule = cap;
            cData = _cData;
            cData.m_CapsuleHeight = m_Capsule.height;
            cData.m_CapsuleCenter = m_Capsule.center;
            m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
        });
    }
    protected override void OnUpdate()
    {
        Entities.With(query).ForEach((Entity e, Transform _transform, Animator anim, Rigidbody rig, CapsuleCollider cap, CharacterData cData, CharacterUserInputData data) =>
        {
            m_Animator = anim;
            m_Rigidbody = rig;
            m_Capsule = cap;
            this.cData = cData;
            iData = data;
            transform = _transform;
            m_GroundCheckDistance = cData.m_OrigGroundCheckDistance;
            Move(iData.m_Move, iData.crouch,iData.m_Jump);
        });
    }
}

Heres the code… Inputs are not read on instance but after a huge delay… Changed data structs to monobehaviour cause that decreased my fps and editor dosent take inputs…

the foreach is the problem… Also I cant find a solution too it…

I am trying to prepare a couple of self contained samples for the latest API, but to be honest it is hard to learn at the moment, even for me.

So there are a lot who is having trouble with new api… :smile:

I wrote a monobehavior to update them manually so they go in a order… but h and v is not updating…