Open CharlesLindberghMcGill opened 4 years ago
Okay so I've just looked through the .scml information and it does provide an actual width and height there. How could we access this information from this library? I would then only need to apply the animator.scale to it and use the GetBoundingBox function.
<obj_info name="bathitbox" type="box" w="145.833" h="483.333" pivot_x="0" pivot_y="0"/>
If I could get this information the "w" and "h" as well as the "name" I could do all of this using the provided GetBoundingBox function, as opposed to the one I made myself.
Something like Survivor.Animator.FrameData.BoxData.Get("bathitbox");
would be absolutely amazing to have.
I'm back. I've done a little bit of digging and I've managed to retrieve the object information that I was wondering about above. The only issue is that in this information the 'id' is set to 0. So I am not sure how to (cross reference, is that the word?) the object data retrieved by name, with the information within the frame data.
var objectData = Animator.Entity.ObjectInfos.First(d => d.Name.Equals("bathitbox"));
// objectData.Id is 0 here, so the following line does not work.
var objectFrameData = Animator.FrameData.BoxData[objectData.Id];
var objectScaled = new Vector2(objectData.Width, objectData.Height) * Animator.Scale;
var box = Animator.GetBoundingBox(objectFrameData, objectScaled.X, objectScaled.Y);
var path = new[]
{
box.Point1,
box.Point2,
box.Point3,
box.Point4
};
engineBatch.DrawShape(path, Color.Red);
Okay, so currently the hacky workaround is to add a name field to "SpriterObject"
public class SpriterObject : SpriterSpatial
{
[XmlAttribute("animation")]
public int AnimationId;
[XmlAttribute("entity")]
public int EntityId;
[XmlAttribute("folder")]
public int FolderId;
[XmlAttribute("file")]
public int FileId;
[XmlAttribute("pivot_x")]
public float PivotX;
[XmlAttribute("pivot_y")]
public float PivotY;
[XmlAttribute("t")]
public float T;
**public string Name;**
public SpriterObject()
{
PivotX = float.NaN;
PivotY = float.NaN;
}
}
Then within the "AddSpatialData" function set the name.
case SpriterObjectType.Box:
FrameData.BoxData[timeline.ObjectId] = info;
**FrameData.BoxData[timeline.ObjectId].Name = timeline.Name;**
break;
An example code would then be:
if(Animator.FrameData.BoxData.Any(d => d.Value.Name.Equals("bathitbox")))
{
var boxData = Animator.Entity.ObjectInfos.FirstOrDefault(d => d.Name.Equals("bathitbox"));
var frameData = Animator.FrameData.BoxData.FirstOrDefault(d => d.Value.Name.Equals("bathitbox"));
var collision = Animator.GetBoundingBox(
frameData.Value,
boxData.Width,
boxData.Height
);
engineBatch.DrawShape(
new []{collision.Point1, collision.Point2, collision.Point3, collision.Point4}, Color.Red, 1f);
}
I don't understand why there's no other way to cross reference the frame data with the object data. The ids are always set to zero for some reason.
Updated example code to map all boxes by their name.
FrameDataCalculator.cs
protected virtual void AddSpatialData(SpriterObject info, SpriterTimeline timeline, Spriter spriter, float deltaTime)
{
info.TimelineName = timeline.Name;
Entity.cs
public Dictionary<string, Box> ObjectBoxMap { get; } = new Dictionary<string, Box>();
protected virtual void OnAnimationChanged(string animation)
{
ObjectInfoMap.Clear();
ObjectBoxMap.Clear();
foreach (var obj in Animator.CurrentAnimation.Entity.ObjectInfos)
ObjectInfoMap[obj.Name] = obj;
}
var deltaTime = gameTime.ElapsedGameTime.Ticks / (float)TimeSpan.TicksPerMillisecond;
Animator.Update(deltaTime);
foreach (var info in Animator.FrameData.BoxData)
{
ObjectBoxMap[info.Value.TimelineName] = Animator.GetBoundingBox(
info.Value,
ObjectInfoMap[info.Value.TimelineName].Width,
ObjectInfoMap[info.Value.TimelineName].Height
);
}
The following question feels insufficiently answered as well as insufficiently documented: https://github.com/loodakrawa/SpriterDotNet/issues/80
What do we pass to the width and height as arguments provided we're talking about collision boxes?
I don't know how to get the width and height information for the object
box
. In Spriter Pro itself it also only provides a scale. What is the size the boxes are scaled from? Maybe I am not well informed enough about how Spriter Pro works and that's why I am so confused.I do know how to get this information for textures. That is simply the actual size of the image.
The following code is how I managed to get the information from the sprites that are being drawn - as you can see I can just multiply the scale of the animation to the size of the textures - however, I don't know where to find the 'size' of the box.