Untitled

mail@pastecode.io avatar
unknown
plain_text
12 days ago
18 kB
1
Indexable
Never
using System;
using System.Collections;
using System.Collections.Generic;
using QFSW.QC;
using TMPro;
using Unity.Entities;
using UnityEngine;
using UnityEngine.UI;
using UnityS.Mathematics;
using UnityS.Physics;
using UnityS.Physics.Extensions;
using UnityS.Transforms;
using Material = UnityS.Physics.Material;
using RaycastHit = UnityEngine.RaycastHit;

public class GameCommands : MonoBehaviour
{
    public static List<ObjectEntity> Balls;
    public static ObjectEntity Plane;
    public static List<ObjectEntity> Rail;

    [Header("UI")] 
    public TMP_Dropdown Dropdown;

    [Header("Prefabs")] 
    public BallTextInfo BallTextPrefab;

    [Header("Configs")]
    [SerializeField] TMP_InputField PlaneFric;
    [SerializeField] TMP_InputField PlaneResti;
    [SerializeField] TMP_InputField BallFric;
    [SerializeField] TMP_InputField BallResti;
    [SerializeField] TMP_InputField RailFric;
    [SerializeField] TMP_InputField RailResti;
    [SerializeField] TMP_InputField Timestep;
    [SerializeField] TMP_InputField Gravity;
    [SerializeField] TMP_InputField VelDrag;
    [SerializeField] TMP_InputField AngDrag;
    [SerializeField] TMP_InputField Solverinteration;

    [Header("Physics")] 
    public LayerMask BallLayer;
    
    private EntityManager Manager;
    private Entity physicsStep;
    
    //default value
    public static Material BallMaterial;
    public static PhysicsParams BallPhysicsParams;

    public static PhysicsParams RailPhysicsParams;
    
    public static Material PlaneMaterial;
    public static PhysicsParams PlanePhysicsParams;

    public static float VelDragValue;
    public static float AngDragValue;
    public static float TimeStepValue;
    public static float GravityValue;
    public static int SolverIterationCountValue;


    [Header("Test")] public List<GameObject> Rails;
    public List<GameObject> Ballss;
    public GameObject Surface;
    public void Init()
    {
        Manager = World.DefaultGameObjectInjectionWorld.EntityManager;
        TimeStepValue = 0.004f;
        //0.002f
        World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<FixedStepSimulationSystemGroup>().Timestep = (float)((sfloat)TimeStepValue);//(float)(sfloat.One / (sfloat)1000.0f);
        physicsStep = Manager.CreateEntity(typeof(PhysicsStep));
        PhysicsStep physicsStepParams = PhysicsStep.Default;
        physicsStepParams.SolverStabilizationHeuristicSettings = new Solver.StabilizationHeuristicSettings
        {
            EnableSolverStabilization = true,
            EnableFrictionVelocities = true,
            InertiaScalingFactor = (sfloat)0.0f,
            VelocityClippingFactor = (sfloat)0.0f
        };
        
        // Gravity = -22f;
        // VelDrag = 
        GravityValue = -22f;
        SolverIterationCountValue = 1;
        physicsStepParams.SolverIterationCount = SolverIterationCountValue;
        physicsStepParams.MultiThreaded = 1;
        physicsStepParams.Gravity = new float3(sfloat.Zero, (sfloat)(GravityValue), sfloat.Zero);
        Manager.SetComponentData(physicsStep, physicsStepParams);

        //
        // BallMaterial = UnityS.Physics.Material.Default;
        // BallMaterial.Friction = (sfloat)0.1f;
        // BallMaterial.Restitution = (sfloat)1f;
        // BallMaterial.FrictionCombinePolicy = Material.CombinePolicy.Maximum;
        // BallMaterial.RestitutionCombinePolicy = Material.CombinePolicy.Minimum;

        // BallPhysicsParams = PhysicsParams.Default;
        // BallPhysicsParams.isDynamic = true;
        // BallPhysicsParams.startingLinearVelocity = float3.zero; // = new float3(sfloat.One * (sfloat)25.0f,sfloat.Zero,(sfloat)15f);
        // BallPhysicsParams.mass = (sfloat)0.25f;
        // BallPhysicsParams.angularDamping = sfloat.Zero;
        // BallPhysicsParams.linearDamping = sfloat.Zero;
        
        
        PlaneMaterial = UnityS.Physics.Material.Default;
        PlaneMaterial.Friction = (sfloat)0.25f;
        PlaneMaterial.Restitution = (sfloat)0;
        PlanePhysicsParams = PhysicsParams.Default;
        PlanePhysicsParams.isDynamic = false;

        
        // RailMaterial = UnityS.Physics.Material.Default;
        // RailMaterial.Friction = (sfloat)0.2f;
        // RailMaterial.Restitution = (sfloat)1f;
        // RailMaterial.FrictionCombinePolicy = Material.CombinePolicy.Maximum;
        // RailMaterial.RestitutionCombinePolicy = Material.CombinePolicy.Minimum;

        RailPhysicsParams = PhysicsParams.Default;
        RailPhysicsParams.isDynamic = false;

        VelDragValue = 0.5f;
        AngDragValue = 0f;

        AddEventListener();
    }

    void CreatePlaneAndRail()
    {
        if (GameCommands.Rail == null)
            GameCommands.Rail = new List<GameCommands.ObjectEntity>();
        var result = EntitiesCreator.CreateBox(
            Surface.transform.position.ToFloat3(), 
            Surface.transform.localScale.ToFloat3(), 
            quaternion.identity, 
            Material.PlaneMaterialDefault, 
            PhysicsParams.DefaultStaticParam);
        GameCommands.Plane = new GameCommands.ObjectEntity()
        {
            GameObject = result.Item1,
            Entity = result.Item2
        };


        for (int i = 0; i < Rails.Count; i++)
        {
            result = EntitiesCreator.CreateBox(
                Rails[i].transform.position.ToFloat3(),
                Rails[i].transform.localScale.ToFloat3(),
                (quaternion)Rails[i].transform.rotation,
                Material.DefaultRail, 
                PhysicsParams.DefaultStaticParam, 
                "Rail");
            GameCommands.Rail.Add(new GameCommands.ObjectEntity()
            {
                GameObject = result.Item1,
                Entity =  result.Item2
            });
        }
        
        for (int i = 0; i < Ballss.Count; i++)
        {
            var transf = Ballss[i].transform;
            (Entity,GameObject) objectEntity = EntitiesCreator.CreateBall(transf.position.ToFloat3(), (sfloat)(transf.lossyScale.x/2), Material.DefaultBall, PhysicsParams.BallParams);
            Balls.Add(new ObjectEntity()
            {
                Entity = objectEntity.Item1,
                GameObject = objectEntity.Item2,
            });
        }
        
        //Set up rails
        // result = EntitiesCreator.CreateBox(
        //     new float3(-(sfloat)6, -(sfloat)1, sfloat.Zero),
        //     new float3(sfloat.One, (sfloat)15f, (sfloat)15f),
        //     (quaternion)Quaternion.Euler(90, 0, 0),
        //     Material.DefaultRail, 
        //     RailPhysicsParams, 
        //     "Rail");
        // GameCommands.Rail.Add(new GameCommands.ObjectEntity()
        // {
        //     GameObject = result.Item1,
        //     Entity =  result.Item2
        // });
        // result = EntitiesCreator.CreateBox(new float3((sfloat)6, -(sfloat)1, sfloat.Zero),
        //     new float3(sfloat.One, (sfloat)15f, (sfloat)15f),
        //     (quaternion)Quaternion.Euler(90, 0, 0),
        //     Material.DefaultRail,
        //     RailPhysicsParams, 
        //     "Rail");
        // GameCommands.Rail.Add(new GameCommands.ObjectEntity()
        // {
        //     GameObject = result.Item1,
        //     Entity = result.Item2
        // });
        // result = EntitiesCreator.CreateBox(new float3(sfloat.Zero, -(sfloat)1, (sfloat)3f),
        //     new float3((sfloat)15f, (sfloat)15f, sfloat.One),
        //     quaternion.identity,
        //     Material.DefaultRail,
        //     RailPhysicsParams, 
        //     "Rail");
        // GameCommands.Rail.Add(new GameCommands.ObjectEntity()
        // {
        //     GameObject = result.Item1,
        //     Entity =  result.Item2
        // });
        //
        // EntitiesCreator.CreateBox(new float3(sfloat.Zero, -(sfloat)1, -(sfloat)3f),
        //     new float3((sfloat)15f, (sfloat)15f, sfloat.One),
        //     quaternion.identity,
        //     Material.DefaultRail,
        //     RailPhysicsParams, 
        //     "Rail");
        // GameCommands.Rail.Add(new GameCommands.ObjectEntity()
        // {
        //     GameObject = result.Item1,
        //     Entity =  result.Item2
        // });



    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            Debug.Break();
        }
    }


    void AddEventListener()
    {
        Dropdown.onValueChanged.AddListener(ShowCase);
    
        // PlaneFric.text = PlaneMaterial.Friction.ToString();
        // PlaneFric.onSubmit.AddListener((val) =>
        // {
        //     PlaneMaterial.Friction = (sfloat)float.Parse(val);
        // });
        // PlaneResti.text = PlaneMaterial.Restitution.ToString();
        // PlaneResti.onSubmit.AddListener((val) =>
        // {
        //     PlaneMaterial.Restitution = (sfloat)float.Parse(val);
        // });
        //
        // BallFric.text = BallMaterial.Friction.ToString();
        // BallFric.onSubmit.AddListener((val) =>
        // {
        //     BallMaterial.Friction = (sfloat)float.Parse(val);
        // });
        // BallResti.text = BallMaterial.Restitution.ToString();
        // BallResti.onSubmit.AddListener((val) =>
        // {
        //     BallMaterial.Restitution = (sfloat)float.Parse(val);
        // });
        //
        //
        // RailFric.text = RailMaterial.Friction.ToString();
        // RailFric.onSubmit.AddListener((val) =>
        // {
        //     RailMaterial.Friction = (sfloat)float.Parse(val);
        // });
        // RailResti.text = RailMaterial.Restitution.ToString();
        // RailResti.onSubmit.AddListener((val) =>
        // {
        //     RailMaterial.Restitution = (sfloat)float.Parse(val);
        // });
        //
        //
        // Timestep.text = TimeStepValue.ToString();
        // Timestep.onSubmit.AddListener((val) =>
        // {
        //     TimeStepValue = float.Parse(val);
        //     World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged<FixedStepSimulationSystemGroup>().Timestep = (float)((sfloat)TimeStepValue);//(float)(sfloat.One / (sfloat)1000.0f);
        // });
        //
        // Gravity.text = GravityValue.ToString();
        // Gravity.onSubmit.AddListener((val) =>
        // {
        //     GravityValue = float.Parse(val);
        //     PhysicsStep step = Manager.GetComponentData<PhysicsStep>(physicsStep);
        //     step.Gravity = new float3(sfloat.Zero, (sfloat)(GravityValue), sfloat.Zero);
        //     Manager.SetComponentData(physicsStep,step);
        // });
        //
        // VelDrag.text = VelDragValue.ToString();
        // VelDrag.onSubmit.AddListener((val) =>
        // {
        //     VelDragValue = float.Parse(val);
        // });
        //
        // AngDrag.text = AngDragValue.ToString();
        // AngDrag.onSubmit.AddListener((val) =>
        // {
        //     AngDragValue = float.Parse(val);
        // });
        //
        // Solverinteration.text = SolverIterationCountValue.ToString();
        // Solverinteration.onValueChanged.AddListener((val) =>
        // {
        //     SolverIterationCountValue = Int32.Parse(val);
        //     PhysicsStep step = Manager.GetComponentData<PhysicsStep>(physicsStep);
        //     step.SolverIterationCount = SolverIterationCountValue;//new float3(sfloat.Zero, (sfloat)(GravityValue), sfloat.Zero);
        //     Manager.SetComponentData(physicsStep,step);
        // });
    }
    private void OnDisable()
    {
        Dropdown.onValueChanged.RemoveListener(ShowCase);
    }

    private void Awake()
    {
        Balls = new List<ObjectEntity>();
    }

    private void Start()
    {
        Init();
        CreatePlaneAndRail();
    }

    public void ShowConsole()
    {
        QuantumConsole.Instance.Toggle();
    }

    private void ResetCase()
    {
        foreach (var ball in Balls)
        {
            Manager.DestroyEntity(ball.Entity);
            Destroy(ball.GameObject);
        }
        Balls.Clear();
    }


    public void ShowCase(int val)
    {
        switch (val)
        {
            case 1:
                ShowCase1();
                break;
            case 2:
                ShowCase2();
                break;
            case 3:
                ShowCase3();
                break;
            case 4:
                ShowCase4();
                break;
            case 5:
                ShowCase5();
                break;
            case 6:
                ShowCase6();
                break;
            default:
                break;
        }
    }
    
    
    public void ShowCase1()
    {
        // ResetCase();
        // CreateBall(new Vector2(0, 0));
        for (int i = 0; i < Balls.Count; i++)
        {
            float x = UnityEngine.Random.Range(1, 5);
            float y = UnityEngine.Random.Range(1, 5);
            float z = UnityEngine.Random.Range(1, 5);
            SetForce(i,new Vector3(x,0,z));
        }
        // CreateBall(new Vector2(-4, -1));
        // CreateBall(new Vector2(3.25f, 1.2f));
        // CreateBall(new Vector2(-2.5f, 0.5f));
        //Debug.Log(t);
    }
    
    public void ShowCase2()
    {
        ResetCase();
        CreateBall(new Vector2(0, 1));
        SetForce(0,new Vector3(5,0,-3f));
        CreateBall(new Vector2(-3, -2));
        CreateBall(new Vector2(3.5f, 1.5f));
        CreateBall(new Vector2(-4.5f, 1.2f));
        //Debug.Log(t);
    }
    
    public void ShowCase3()
    {
        ResetCase();
        CreateBall(new Vector2(0, 1));
        SetForce(0,new Vector3(4,0,-1.5f));
        CreateBall(new Vector2(-3, -2));
        CreateBall(new Vector2(3.5f, 1.5f));
        CreateBall(new Vector2(-4.5f, 1.2f));
        CreateBall(new Vector2(4f, 0.6f));
        CreateBall(new Vector2(-4f, -0.6f));
        CreateBall(new Vector2(3f, 1.28f));
        //Debug.Log(t);
    }

    public void ShowCase4()
    {
        ResetCase();
        CreateBall(new Vector2(0, 0));
        CreateBall(new Vector2(2,0));
        
        //Raycast to get point
        Vector3 startPoint = new Vector3(-0.3f, 0.55f, 0);
        // Vector3 dir = (b.position - a.position).normalized * 3;

        Physics.Raycast(startPoint, new Vector3(1f, 0f, 0f), out RaycastHit hit, int.MaxValue, BallLayer);
        if (hit.collider != null)
        {
            SetForceAtPosition(0, new Vector3(2,0,0), hit.point);
        }
        
        //ball radius
    }
    
    public void ShowCase5()
    {
        ResetCase();
        CreateBall(new Vector2(0, 0));
        CreateBall(new Vector2(2,0));
        
        //Raycast to get point
        Vector3 startPoint = new Vector3(-0.3f, 0.75f, 0);
        Physics.Raycast(startPoint, new Vector3(1f, 0f, 0f), out RaycastHit hit, int.MaxValue, BallLayer);
        if (hit.collider != null)
        {
            SetForceAtPosition(0, new Vector3(2, 0, 0), hit.point);
        }

        //ball radius
    }

    [Header("Direction calculator")] 
    public Transform a;
    public Transform b;
    public void ShowCase6()
    {
        Vector3 dir = (b.position - a.position).normalized * 3;
        
        ResetCase();
        CreateBall(new Vector2(-2, 0));
        CreateBall(new Vector2(3, 0));
        //Raycast to get point
        Vector3 startPoint = new Vector3(-0.15f - 2, 0.65f, -0.1f);
        Physics.Raycast(startPoint, new Vector3(1f, 0f, 0f), out RaycastHit hit, int.MaxValue, BallLayer);
        if (hit.collider != null)
        {
            Debug.Log($"{hit.point}");
            SetForceAtPosition(0, dir, hit.point);  //6,0,0
        }

        //ball radius
    }
    
    

    private static void BallInfomation()
    {
        Debug.Log($"Ball trong khoang [-5,-2] => [5,2]");
    }
    private void CreateBall(Vector2 position)
    {


        //GameController.Instance.CreateBall(new float3(sfloat.Zero,(sfloat)5.0f,sfloat.Zero), sfloat.One, material, physicsParams);
        (Entity,GameObject) objectEntity = EntitiesCreator.CreateBall(new float3((sfloat)(position.x),(sfloat)0.65f,(sfloat)position.y), (sfloat)0.15f, Material.DefaultBall, PhysicsParams.BallParams);
        BallTextInfo info = Instantiate(BallTextPrefab);
        info.SetAttach(objectEntity.Item2);
        Balls.Add(new ObjectEntity()
        {
            Entity = objectEntity.Item1,
            GameObject = objectEntity.Item2,
        });
    }
    
    private static void SetForce(int ballID,Vector3 direction) //float x, float y, float z
    {
        EntityManager manager = World.DefaultGameObjectInjectionWorld.EntityManager;
        PhysicsVelocity physicsVelocity = manager.GetComponentData<PhysicsVelocity>(Balls[ballID].Entity);
        PhysicsMass physicsMass = manager.GetComponentData<PhysicsMass>(Balls[ballID].Entity);
        //physicsVelocity.Linear = direction.ToFloat3();
        float3 dir = direction.ToFloat3();
        physicsVelocity.ApplyLinearImpulse(in physicsMass, in dir);
        //param.ApplyImpulse();
        manager.SetComponentData(Balls[ballID].Entity,physicsVelocity);
    }

    private static void SetForceAtPosition(int ballID, Vector3 direction, Vector3 pointHit)
    {
        EntityManager manager = World.DefaultGameObjectInjectionWorld.EntityManager;
        PhysicsVelocity physicsVelocity = manager.GetComponentData<PhysicsVelocity>(Balls[ballID].Entity);
        PhysicsMass physicsMass = manager.GetComponentData<PhysicsMass>(Balls[ballID].Entity);
        //physicsVelocity.Linear = direction.ToFloat3();
        float3 dir = direction.ToFloat3();
        Translation t = manager.GetComponentData<Translation>(Balls[ballID].Entity);
        Rotation r = manager.GetComponentData<Rotation>(Balls[ballID].Entity);
        //physicsVelocity = PhysicsComponentExtensions.ApplyImpulse(physicsVelocity, physicsMass, t, r, dir, pointHit.ToFloat3());
        var point = pointHit.ToFloat3();
        physicsVelocity.ApplyImpulse(in physicsMass, in t, in r, in dir, in point);
        //param.ApplyImpulse();
        manager.SetComponentData(Balls[ballID].Entity,physicsVelocity);        
    }
    
    
    


    public class ObjectEntity
    {
        public Entity Entity;
        public GameObject GameObject;
    }
}
Leave a Comment