Harald

  • Inscrit 13 nov. 2018
  • @Harald Thanks for your tips!

    It worked nicely in our project.
    I also noticed that the texture also gets unloaded when you repack a skin, which is quite nice (probably because the original Skin is not in use anymore, right?).

    One last question about memory optimization: to use compressed atlases for our Spine objects and to support repacking, is it enough to:

    • Change the target texture format when repacking
    • Ensure that all attachments follow the rules required by the target compression. For example: all with dimensions multiple of 4.

    Is that it?

      Harald In general it's always highly recommended to automate your exports using bash (or batch) scripts.

      @Harald, Spine doesn't support partial export, so they can't export a skeleton per skin from the CLI. They could export to JSON and then write a script to hack that up, but I don't recommend that.

    • This scene does not contain skin switching @Harald . I know this scene but it cant help us. With one skin everything is fine but when i change skin this issue comes up

      There's currently no way to emulate spine-unity's GetRepackedSink() in spine-godot, as that'd require a way to:

      1. Access the pixel data of all involved atlas' pages
      2. Recombine a subset of that pixel data (regions) into a new atlas, doing some form of rectangle packing
      3. Load that new atlas on the fly

      You can get the pixel data from the textures in a SpineAtlasResource. However, you'd still need to load all the involved atlases to pick out the regions you need for the customized character. That'd be a loading step due to how much time it takes to do all that work.

      You'd have to create a new texture, draw the regions you need from the atlas pages to it (along with packing them in a sensible way to not waste texture space). Then you'd need to construct a new atlas. Currently, there's no way to create a new SpineAtlasResource on the fly, as the API needed to create texture regions is not exposed.

      The alternative to creating a full-blown atlas would be to set create and set your own attachments on a SpineSprite (or rather, its internal SpineSkeleton) via SpineSprite::set_attachment. The problem with that is that:

      1. There's currently no way to set an actual attachment instance
      2. Even if we had that method, memory management would be rather hard, as you'd be in charge of ensuring that any custom attachment (consisting of a texture and texture coordinates that describe the region in the texture to be used by the attachment) is freed up when no longer needed.

      Long story short: it's currently not possible. I have to think of a way how to expose all this in such a way, that your apps don't blow up due to memory related crashes.

      I've added an issue here you can follow
      EsotericSoftware/spine-runtimes2767

      I'll consult with @Harald on how to best go about this. It will take a while to materialize.

      • @Harald I see, but would it be bad performance wise to use URP 3D for a 2D project?
        I converted my project to URP 3D, but now the colors on my Spine character look washed out. When I place the 3D lights into the scene they don't affect anything, neither my sprite objects or Spine objects. Which materials do I need to use? Will the shadows cast onto the surface behind based on the Z world position of the surface and the strength of the light? Do I need to have a light parented to each dynamic game object in order to cast the shadow behind them, or can I have just one global light for the shadows?

        • @Harald Apologies for the late response, but I have some great news, sfter a few restarts and a reinstallation, the old Spine version is now running smoothly.
          The issue turned out to be minor, but it was causing some frustration whenever I tried to debug. Thankfully, everything seems to be working perfectly now.
          Thank you so much for your support and guidance! It really helped me work through the problem.

        • Misaki no need to feel sorry, diff do help a lot on tracking modification of docs. I have to thank you and @Harald for not tired about posting diffs here 😛

          BTW I am done with spine-pixi doc's translation:

          zh-cn-spine-pixi.zip
          9kB

          pls check it

          • @Misaki @Harald ok, let's do some quick updates:
            spine-c:

            ZH_CN_spine-c_doc.zip
            18kB

            spine-cpp:

            ZH_CN_spine-cpp_doc_render_update.zip
            16kB

            spine-unity-faq:

            ZH_CN_spine-unity-faq_add_item.zip
            5kB

            PS: your diffs expired so quick that I have to save the webpage lol @Misaki
            spine-pixi almost done, will be available soon

            • @Spinebot These are very helpful, I will inform the artist

              @Harald Yes, I have already thought of that but it is not a viable option for our needs. For full on helmets yes that is completely doable but for other hats, we cannot just change hair.

            • @Harald Sorry for late reply.

              In short, I have created a paper doll system using spine that covers eyes, mouths, hair, eyewear, hats, outfits and even full heads. What made it a bit more complex is the need to recolor skin and hair.
              So I have created a separate material for skin, hair, eyewear (needed their own material to control transparency of glass material), a material just for full heads, and lastly for full avatar without those.
              The algorithm dynamically picks up slots using prefixes in spine slots and assign them to the correct material that gets recolored.

              The atlas got bigger due to the introduction of full heads paper doll. Full heads are big.
              So what I really want to do is create two png exports, one for all of the avatar and one just for the heads.

              Currently our Spine image folder has two main folders full heads and avatar.

              How can I export properly two have two png atlases one for each folder and ofcourse with the correct binary configs export.

              • Thank you @Harald !
                This was really helpful!

                I'm gonna give it a try and see how far I can get with the 3D workaround suggested in the Github Thread.
                I'll also check if i can re-create the Pixel Grid as shader.
                In case somebody already got something like this running, any link or help is appreciated!

                One last thing though:
                When using a custom build of Godot - do you think it will work with releases for consoles? Some companies offer additional source code for console builds, so where does the Spine build fit in there?

                Thank you and happy weekend!

              • Hello @Harald !

                What happens is that, being a child of a hierarchy of objects (bones) that have their scale modified at some points in the hierarchy, the weapon’s final scale is affected (not by itself, but by its parent objects).

                I’m not sure if I fully understood how to use the BoneFollower, but I discovered that I can achieve this behavior, as if it were a child of a specific bone, without actually being part of that hierarchy. That is, the weapon is now a "free" object, but it inherits the position and rotation just as if it were "contained" within the R-WeaponHolder bone.

                I’m not sure if this is the correct way to use this component, but for now, it seems to be working. However, if there is any mistake in this approach, I’d appreciate it if you could point it out so I can learn to use it properly.

                Thank you very much for your time and patience!!

                • @Harald Thanks for reply.I will try my best to describe the trouble I have encountered and the help I want to get(with ai translations) .
                  1, our team artists loves the physical feature in 4.2:

                  2, it works in unity(2022.3.40f1) with spine4.2 runtime. But it dosn't works while SkeletonAnimation.timescale = 0;
                  [SerializeField] private SkeletonAnimation image;
                  image.timeScale = 0;

                  this equals to
                  Set Component(SkeletonAnimation) Time Scale to 0 in inspector.
                  3, i need to set it to 0 cuz i need to control animation playing by my deltaTime, like this:
                  `
                  public TimelineNode DoActionOnce(string actionId, string key, out float inSec, out List<(string key, float elapsed)> eventPoints)
                  {
                  inSec = 0;
                  eventPoints = new List<(string key, float elapsed)>();
                  if (_imageData == null) return TimelineNode.Nothing;

                      Spine.Animation sa = _imageData.FindAnimation(actionId);
                      if (sa == null || sa.Duration <= 0) return TimelineNode.Nothing;
                      inSec = sa.Duration;
                  
                      if (!string.IsNullOrEmpty(key))
                      {
                          var tls = sa.Timelines.FindAll(t => t is EventTimeline);
                          foreach (Spine.Timeline t in tls)
                          {
                              EventTimeline et = (EventTimeline)t;
                              foreach (Spine.Event se in et.Events)
                              {
                                  //判断se中是否带有key,如果是,才有可能,约定key的string后面+个"_"才是搜索关键字
                                  if (se.Data.Name.Contains(key + "_"))
                                  {
                                      //se.Time是发生的时间点,动画开始后算起(秒)
                                      eventPoints.Add((se.Data.Name, se.Time));
                                  }
                              }
                          }
                          eventPoints.Sort((ep1, ep2)=>ep1.elapsed.CompareTo(ep2.elapsed));
                      }
                      
                  
                      float elapsed = 0;
                      float totalInSec = inSec;
                      return new TimelineNode(e =>
                      {
                          if (!image || !gameObject) return true;
                          if (e <= 0)
                          {
                              image.AnimationState.SetAnimation(0, actionId, false);
                              elapsed = 0;
                          }
                          image.AnimationState.Update(e - elapsed);
                          elapsed = e;
                  
                          if (e >= totalInSec)
                          {
                              image.AnimationState.SetAnimation(0, _defaultAction, true);
                              return true;
                          }
                  
                          return false;
                      });
                  }`

                  in a timelineNode(not unity timeline but classic JRPG timeline),i update the animation by my own deltaTime that i can do many things like faster or slower the game running. and every timelineNode is only a part of the performance for a turn after player gives command.
                  4, a battle turn performance in our game is nearly Unicorn Overlord:

                  from 3:10 to 3:35, the whole battle turn performance is composed of many individual timeline nodes that are very complex. Each one is calculated through separate script logic. I need to calculate it well at the beginning, and then gradually play it for players to watch. During the process, players can freely speed up or slow down the playback. So I have to set timeScale to 0, otherwise it will update twice by unity mono update.
                  5, And then, SkeletonAnimation.timeScale == 0 leads to physical stop working. I just wanna the character can have drag effect(artists makes them in spine4.2) while character moving and their SkeletonAnimation.timeScale==0.
                  So I think I should be given another update that allows me to set it to 1 so that I can fully enjoy the new physical characteristics in 4.2.

                • @Harald
                  Hi, I've encountered another question and wanted to confirm something. In the GeometryNotEqual method of SkeletonRenderInstruction, this piece of code only takes effect when the SPINE_TRIANGLECHECK switch is turned off:

                  // In normal immutable triangle use, immutableTriangles will be initially false, forcing the smartmesh to update the first time but never again after that, unless there was an immutableTriangles flag mismatch..
                  if (a.immutableTriangles || b.immutableTriangles)
                  return (a.immutableTriangles != b.immutableTriangles);

                  return true;

                  I'm wondering, are SkeletonRenderer's immutableTriangles and SPINE_TRIANGLECHECK mutually exclusive? I searched the code and found that the variable immutableTriangles is only used in GeometryNotEqual.

                • Misaki hi, I have done the translation of spine-ios at here:

                  zh_CN_spine-ios.zip
                  9kB

                  @Harald and I still working on the update of spine-unity due to full text proofreading. spare me more patience please, and thanks for your patience in advance

                  • Hi @Harald
                    So to assign the mesh within a particle system, I need to have a script that gets the Mesh from Meshfilter using MeshFilter.sharedMesh and does this mean to be able to access it, I will need to have the Mesh filter in settings disabled or does it not longer matter?

                    • @Harald I figured out what the issue was. It was a side effect of the change I made and also setting 'UnscaledTime' to true which sometimes resulted in a large update time that would cause the physics simulation to get really unstable. I'm fixing this by making sure we still step the physics over multiple smaller steps if the time value is greater than 100ms. This seems to fix the weird glitches that I was seeing.

                    • @Nate thanks again for taking the time to look into this, I realize it's not a simple fix!

                      Adding the option for interpolation sounds like a great solution, this is what Unity offers for their physics system that works well but yes it would have a 1 frame physics delay.

                      For us, removing the fixed timestep would be the best short term option and we do have a quick and dirty solution in our fork here: Noeski/spine-runtimes but I've noticed a few weird glitches that occur when changing the global Unity timescale.

                      I'm sure you and @Harald have a better idea of how to update to properly support this.

                      Thanks!

                      • Hi @Harald, is there any progress on this? Thanks!