Announcement

Collapse
No announcement yet.

Problems with creating TextBlock from Behavior

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems with creating TextBlock from Behavior

    Hi there!

    I have a problem with my Debug-Message Behavior.
    What I want to achieve is to create a class inherited from Behavior, which displays the rotation of a Rigidbody3D in a TextBlock.

    Here's my code:

    Code:
    public class DebugTextBehavior : Behavior
        {
            [RequiredComponent]
            private RigidBody3D rigidBody;
    
            private TextBlock textBlock;
    
            float x = 0;
            float y = 0;
            float z = 0;
            protected override void Initialize()
            {
                base.Initialize();
                
                textBlock = new TextBlock()
                {
                    TextAlignment = TextAlignment.Center,
                    HorizontalAlignment = HorizontalAlignment.Center,
                    Margin = new Thickness(0,20,0,0),
                    Foreground = Color.Red
                };
                EntityManager.Add(textBlock);
            }
    
            protected override void Update(TimeSpan gameTime)
            {
                x = rigidBody.Transform3D.Rotation.X;
                y = rigidBody.Transform3D.Rotation.Y;
                z = rigidBody.Transform3D.Rotation.Z;
    
                textBlock.Text = x.ToString() + '\t' + y.ToString() + '\t' + z.ToString();
            }
        }
    Now, the problem is, that if I run the program it hangs on the Splashscreen and gives me following error:

    An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
    Additional information: Collection was modified; enumeration operation may not execute.


    The error occures in the file App.cs at line 95, at this.game.UpdateFrame(elapsedTime);

    I've got no idea how to solve this, so I hoped you could help me.

    Thanks in advance!

  • #2
    It is not a good idea to create Entities on the Initialize method of a behavior because that method is executed during framework initialization, and some internal process when adding entities.
    I suggest you to add the textblock entity in the first Update execution, something like this:

    Code:
    public class DebugTextBehavior : Behavior
    {
        private TextBlock textBlock;
    
        bool initialized;
    
        protected void InitializeBehavior()
        {
            textBlock = new TextBlock()
            {              
                Foreground = Color.Red
            };
    
           EntityManager.Add(textBlock);
           this.initialized = true;
    
        }
      
        protected override void Update(TimeSpan gameTime)
        {
            if (!initialized)
            {
                this.InitializeBehavior();
            }
    
            textBlock.Text = "tests";
        }
    
    }
    Hope this helps!

    Comment


    • #3
      But now you are checking a bool 60 times per second?

      Comment


      • #4
        Hi Nyanpasu !

        Yes, he is now checking a bool 60 times per second. If this is undesired behavior, you can use the EntityInitialized event that is available in newer versions of WaveEngine.

        I hope you find this useful.

        Comment


        • #5
          I wish I knew how to use it. I need an example to get started. I am currently trying to output the current position of the transform to a TextComponent but I have looked everywhere in the repositories and other example projects and can't seem to find how to do it. Please help.

          I assumed this would work but it only gives me nullpointer-errors:

          Code:
          [DataContract]
              class DistanceText : Behavior
              {
                  public TextComponent Test;
          
                  protected override void Initialize()
                  {
                      base.Initialize();
          
                      Test = EntityManager.Find<Entity>("distancer").FindComponent<TextComponent>();
                  }
          
                  protected override void Update(TimeSpan gameTime)
                  {
                      // Nyanpasu.
          
                      Test.Text = "Test";
                  }
              }

          Comment


          • #6
            Where is the null pointer exception generated? In the Find call or in the FindComponent call?

            Comment


            • #7
              It only says that line 26 is causing it, which is this:

              Code:
               
               Test = EntityManager.Find<Entity>("distancer").FindComponent<TextComponent>();
              I can mention that "distancer" is a child of another object, but I assumed that Find<> would ignore hierarchies.

              Comment


              • #8
                You can split that line into multiple lines to know which one is throwing the exception:

                Code:
                var entity = EntityManager.Find<Entity>("distancer");
                Test = entity.FindComponent<TextComponent>();
                But as you said "distancer" is not in the scene root, I'd say the Find() call is returning null. EntityManager.Find() needs the full path to the entity.

                Comment

                Working...
                X