Jump to content

[SOLVED] SetCollision не отключает коллизию в коде C#


Recommended Posts

Posted (edited)

По примеру отсюда создаю в коде несколько сфер, которые по физике притягиваются в некоторую точку (демо работы трубки осциллографа)

При создании сферы функция  OMD.SetCollision(false, 0) почему-то не отключает коллизию и сферы сталкиваются между собой, а мне столкновения не нужны.

https://youtu.be/uwDZNJbXqHc

Подскажите где я ошибся?

Вот мой код, в сцену надо добавить Dummy с именем CathodeDummy и в настройках мира нужно обнулить гравитацию

image.png.ce8d95ed5710af9c087cda96c1a713c7.png

Spoiler
using System.Collections;
using System.Collections.Generic;
using Unigine;
 
[Component(PropertyGuid = "cf1779da44f5db9b596a72d5b9691824fb28b657")]
public class Oscilloscope : Component
{
    List<BodyRigid> ElectronList = new List<BodyRigid>();
    int ElectronCount = 10;
    Node NodeCathodeDummy = World.GetNodeByName("CathodeDummy");
 
   
    BodyRigid CreateElectron()
    {
        ObjectMeshDynamic OMD = Primitives.CreateSphere(0.05f, 12, 12);
        // OMD.Transform = MathLib.Translate(0.0f, 0.0f, 1.0f);
        OMD.SetCollision(false, 0);
        OMD.SetMaterialParameterFloat4("albedo_color", new vec4(255, 255, 0, 1.0f), 0);
        BodyRigid br = new BodyRigid(OMD);
        br.AddShape(new ShapeSphere(0.1f));
               
        OMD.Body.GetShape(0).Mass = 1f;
        return br;
    }
 
    void Init()
    {
        for (int i = 0; i < ElectronCount; i++)
        {
            BodyRigid el = CreateElectron();
            ElectronList.Add(el);
        }
 
        for (int i = 0; i < ElectronCount; i++)
        {
            float x,y,z;
            float forceMax = 2f;
            x = MathLib.RandFloat(-forceMax,forceMax);
            y = MathLib.RandFloat(-forceMax,forceMax);
            z = MathLib.RandFloat(-forceMax,forceMax);
           
            // vec3 x = MathLib.RandVec3((-1)*vec3.ONE, 1*vec3.ONE);
            ElectronList[i].AddWorldForce(vec3.ZERO, new vec3(x,y,z));  
        }
        Visualizer.Enabled = true;
       
    }
 
    void Update()
    {
        float Attr1X=0.5f, Attr1Y=1, Attr1Z=1;
        vec3 Attr1Pos = new vec3(Attr1X, Attr1Y, Attr1Z);//координаты 1го ускорителя        
        Visualizer.RenderVector(vec3.ZERO,Attr1Pos,vec4.RED);
 
        for (int i = 0; i < ElectronList.Count; i++)
        {
            //притяжение к ускорителю 1
            vec3 VecDist2Attract1 = (vec3)(Attr1Pos - ElectronList[i].Position);//векторное расстояние
            float Dist2Attract1 = VecDist2Attract1.Length2;//линейное расстояние
            float ForceAttr1 = 1/(Dist2Attract1+0.1f);//закон тяготения
            ElectronList[i].AddWorldForce(ElectronList[i].Position, ForceAttr1*VecDist2Attract1.Normalized);
                   
            // Visualizer.RenderVector(ElectronList[i].Position,0.1*VecDist2Attract1,vec4.GREEN,0.1f);
 
            double d = MathLib.Distance2 (ElectronList[i].Position, vec3.ZERO);
            if (d > 20 )
            {
                float x=0,y=0,z=0;
                //возврат электрона в нить накала
                z = MathLib.RandFloat(0, 0.5f);
                ElectronList[i].Position = new vec3(0,0,z);
                //после возврата снова добавляем толчок электрону чтобы он улетел
                float forceMax = 0.5f;
                x = MathLib.RandFloat(-forceMax,forceMax);
                y = MathLib.RandFloat(-forceMax,forceMax);
                z = MathLib.RandFloat(-forceMax,forceMax);
                vec3 forceEmission = new vec3(x,y,z);
                // ElectronList[i].AddWorldForce(vec3.ZERO, forceEmission);
 
               
                // Log.Message("{0}"+'\n', VecDist2Attract1);
               
            }  
        }
           
    }
 
}

Заранее спасибо

 

Edited by sevas55
Posted

Здравствуйте!


Пока сразу на что обратил внимание. Вы создаете для объектов физическое тело(BodyRigid), а метод SetCollision  вызываете у самого объекта, этот метод нужен когда у объекта нет физического тела оно статично находится в сцене но мы хотим, чтобы физичные объекты получали информацию о коллизиях с ними. Но когда у объекта есть физическое тело настройки коллизий у поверхностей не учитываются. 

Попробуйте выставлять в параметры шейпа который добавляете в тело маску Exclusion. Например setExclusionMask(1).

https://developer.unigine.com/en/docs/future/principles/physics/collision/ - задесь можно прочитать о том что я хотел объяснить, если Вы не доконца поняли о чем я говорю.

  • Like 1
Posted

Добавил 

OMD.Body.GetShape(0).ExclusionMask = 1;

Теперь объекты не сталкиваются между собой.

 

Подскажите, как решить задачу правильно, я сделал как смог, но не уверен, что оптимально с точки зрения эффективности кода.

Мне принципиально иметь возможность применять к объекту силу функцией AddWorldForce, чтобы движок сам просчитывал их движение, учитывая массу и было похоже на симуляцию движения в гравитационном поле. Но также важно чтобы объекты не сталкивались между собой.

Код не прошу, хотя бы тезисно: создаем RigidBody=> и так далее.

Благодарю за помощь.

Posted

Здравствуйте!

Я так понимаю, что задача решена и Вы просто хотите убедиться в эффективности решения? 

В общем пайплайн правильный создаете объект, добавляете к нему RigidBody, к RigidBody добавляете шейпы, если важно можете настроить их как нужно и придавать силу в нужной точке, а не в центре объекта, это позволит достичь более точной симуляции. Если же вы рассматриваете объекты как материальные точки то шейпа сферы будет достаточно и придавать силу в центре шейпа. Так же в настройках щейпа можно выставить маски колизий, по ним будут определяться объекты с которыми шейп может коллизится, можете выставить какую-то опредленную маску этим объектам и объектам с которыми ваши созданные объекты должны колизится. Маска Exclusion нужна чтобы объекты с одинаковими такими масками не колизились, то есть для своих объектов надо выставлять такие маски. Если все объекты у Вас одинаковые, то можете подготовить такой объект в редакторе и сохранить его как NodeReference, а потом в коде уже просто их создавать из NodeReference без дополнительных настроек.

  • Like 1
Posted

Да, задача решена. SOLVED

Cпасибо за пояснения и помощь!

 

Posted

Единственное что забыл уточнить, что работать с физикой нужно в методе UpdatePhysics, а не в обычном Update. Так как в UpdatePhysics стабильный фреймрейт и и физичный движок вызывает эту функцию перед каждым своим обновлением.

  • silent changed the title to [SOLVED] SetCollision не отключает коллизию в коде C#
×
×
  • Create New...