stride-community-toolkit icon indicating copy to clipboard operation
stride-community-toolkit copied to clipboard

GetCamera functions bug

Open SamiG42 opened this issue 2 years ago • 8 comments

Before first frame rendered this code always prints

GetCamera was null
GetCamera('Main') was null
GetFirstCamera was null

Other frames print these

GetCamera was null
GetCamera('Main') was null
using Stride.CommunityToolkit.Engine;
using Stride.Engine;
using Stride.CommunityToolkit.ProceduralModels;
using Stride.Core.Mathematics;

using var game = new Game();

game.Run(start: (Scene rootScene) =>
{
    game.SetupBase3DScene();

    var entity = game.CreatePrimitive(PrimitiveModelType.Capsule);

    entity.Transform.Position = new Vector3(0, 50, 0);
    entity.Add(new Test());
    entity.Scene = rootScene;
});
public class Test : SyncScript
{
    public override void Update()
    {
        if (this.GetCamera() is null)
        {
            Console.WriteLine("GetCamera was null");
        }
        if (this.GetCamera("Main") is null)
        {
            Console.WriteLine("GetCamera('Main') was null");
        }
        if (this.GetFirstCamera() is null)
        {
            Console.WriteLine("GetFirstCamera was null");
        }
    }
}

(Sorry for my english)

SamiG42 avatar Dec 08 '23 19:12 SamiG42

GetCamera() and GetCamera("Main") are basically the same as they both look for a Camera with the name Main in the GraphicsCompositors. I dont know why but Stride has an issue with initializing the camera 2-3 frames into a running game which is why the camera is null at first.

https://github.com/stride3d/stride-community-toolkit/blob/74ac438ebf88eca6705bd5f65803cd846e918667/src/Stride.CommunityToolkit/Engine/GameExtensions.cs#L134

Maybe something can be done in the above but for now there is only the workaround of waiting for Stride to initialize the Camera in the compositor.

Doprez avatar Dec 12 '23 20:12 Doprez

Same but there is another bug Game.SetupBase3DScene and Game.SetupBase does not name main camera as "Main" https://github.com/stride3d/stride-community-toolkit/blob/74ac438ebf88eca6705bd5f65803cd846e918667/src/Stride.CommunityToolkit/Engine/GameExtensions.cs#L100 and https://github.com/stride3d/stride-community-toolkit/blob/74ac438ebf88eca6705bd5f65803cd846e918667/src/Stride.CommunityToolkit/Engine/GameExtensions.cs#L81 bug fixable by changing line like this

game.AddCamera("Main");

SamiG42 avatar Dec 13 '23 20:12 SamiG42

In this line I adding Test script to the entity. Is this correct way? I don't know because no documentation or example for adding script to entity in Stride Community Toolkit entity.Add(new Test());

game.Run(start: (Scene rootScene) =>
{
    game.SetupBase3DScene();

    var entity = game.CreatePrimitive(PrimitiveModelType.Capsule);

    entity.Transform.Position = new Vector3(0, 50, 0);
    entity.Add(new Test()); //  ---- This Line
    entity.Scene = rootScene;
});

SamiG42 avatar Dec 13 '23 20:12 SamiG42

Ohh, that reminds me, I have to add some simple example how to add a script!!

You can have a look at this example (which I am working on), how I am adding a script called RaycastHandler()

https://github.com/stride3d/stride-community-toolkit/blob/74ac438ebf88eca6705bd5f65803cd846e918667/examples/code-only/Example_CubicleCalamity/CubeStacker.cs#L44

but there might be other ways. Maybe @Doprez can suggest other alternatives.

VaclavElias avatar Dec 13 '23 23:12 VaclavElias

@Doprez, when I am adding a default camera in the SetupBase3DScene() I don't name it. Should it be called Main?

VaclavElias avatar Dec 13 '23 23:12 VaclavElias

If I remember correctly it gets the name from the camera slot in the GraphicsCompositor so naming through AddCamera would not work with that extension, BUT you could use that and then search through Scene entities instead of the GC. SceneSystem.SceneInstance.RootScene.Entities.First(x => x.Name == "Main"); this may work better since it doesnt require messing with the GraphicsCompositor which is a little complex.

But yes @VaclavElias you might want to name it "Main" in the GraphicsCompositor camera slots otherwise that extension will never work unless the user adds a new slot to the GC named "Main". And it wont hurt to name the Entity itself to either "Main" or "MainCamera".

Doprez avatar Dec 14 '23 00:12 Doprez

This https://github.com/stride3d/stride-community-toolkit/blob/74ac438ebf88eca6705bd5f65803cd846e918667/examples/code-only/Example_CubicleCalamity/CubeStacker.cs#L42-L45 compiles like this so this is the right way

var entity = new Entity("GameManager") ;
entity.Add(new RaycastHandler());

SamiG42 avatar Dec 14 '23 19:12 SamiG42

ScriptComponent.GetCamera()
ScriptComponent.GetCamera(string)
ScriptComponent.GetFirstCamera()

Have replaced the old GetGCCamera functions. These ones should work on scene load now.

This also releases 2 Entity extensions for making getting componenst in an Entity a little easier.

Entity.FindEntityRecursive()
Entity.GetComponentInChildren<T>()

These are all using recursion so use sparingly.

Doprez avatar Mar 02 '24 19:03 Doprez