Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Dozeworthy
Oct 9, 2012

Inverness posted:

Yes. I see when you create a component you have RF_Transient set, which might be the cause of this since PIE likely uses the serialization mechanism for copying the world.

So either remove that or re-create your components from PostLoad().

I removed RF_Transient and no improvement, and during PostLoad event in-game some calls like GetNumChildrenComponents return incorrect values.

Adbot
ADBOT LOVES YOU

Inverness
Feb 4, 2009

Fully configurable personal assistant.

Dozeworthy posted:

I removed RF_Transient and no improvement, and during PostLoad event in-game some calls like GetNumChildrenComponents return incorrect values.
In that case I wonder which component lists you're adding your new components to. Not all of them are serialized:
code:
private:
	/**
	 * All ActorComponents owned by this Actor.
	 * @see GetComponents()
	 */
	TArray<UActorComponent*> OwnedComponents;

	/** List of replicated components. */
	TArray<UActorComponent*> ReplicatedComponents;

public:

	/** Array of ActorComponents that are created by blueprints and serialized per-instance. */
	UPROPERTY(TextExportTransient, NonTransactional)
	TArray<UActorComponent*> BlueprintCreatedComponents;

private:
	/** Array of ActorComponents that have been added by the user on a per-instance basis. */
	UPROPERTY(Instanced)
	TArray<UActorComponent*> InstanceComponents;
My first suggestion is to call AddInstanceComponent() after your call to AddOwnedComponent(). The instance components property is actually serialized.

I did some digging around to see how AddInstanceComponent() is used:
code:
UActorComponent* FComponentEditorUtils::DuplicateComponent(UActorComponent* TemplateComponent)
{
	check(TemplateComponent);

	UActorComponent* NewCloneComponent = nullptr;
	AActor* Actor = TemplateComponent->GetOwner();
	if (!TemplateComponent->IsEditorOnly() && Actor)
	{
		Actor->Modify();
		UClass* ComponentClass = TemplateComponent->GetClass();
		FName NewComponentName = *FComponentEditorUtils::GenerateValidVariableName(ComponentClass, Actor);

		bool bKeepWorldLocationOnAttach = false;
		NewCloneComponent = ConstructObject<UActorComponent>(ComponentClass, Actor, NewComponentName, RF_Transactional, TemplateComponent);
		
		// ComponentToWorld is not a UPROPERTY, so make sure the clone has calculated it properly
		NewCloneComponent->UpdateComponentToWorld();

		// If the clone is a scene component without an attach parent, attach it to the root (can happen when duplicating the root component)
		auto NewSceneComponent = Cast<USceneComponent>(NewCloneComponent);
		if (NewSceneComponent && !NewSceneComponent->GetAttachParent())
		{
			USceneComponent* RootComponent = Actor->GetRootComponent();

			// There should be no situation in which a scene component is duplicated when a root doesn't exist
			check(RootComponent);

			NewSceneComponent->AttachTo(RootComponent, NAME_None, EAttachLocation::KeepWorldPosition);
		}

		// Add to SerializedComponents array so it gets saved
		Actor->AddInstanceComponent(NewCloneComponent);
		
		// Register the new component
		NewCloneComponent->RegisterComponent();
	}

	return NewCloneComponent;
}
Notice the comment alongside AddInstanceComponent(). You need to add it there to be saved. I assume this only applies because you're not setting the component instance directly to a UPROPERTY() which is the case for many C++ actors that create their components in the constructor.

Inverness fucked around with this message at 17:05 on Feb 22, 2015

MockingQuantum
Jan 20, 2012



Can anyone explain serialization errors in Unity? In a fashion that isn't totally over my non-programmer head? I'm getting a "serializaton depth limit exceeded" error thrown on play. It's generated by a block of code within an external Unitypackage I'm using in a project, and I'm 99% sure I can't actually access any of the source code in the package, so as far as I can tell, I'm stuck with these serialization errors. Do I need to worry? It doesn't appreciably affect performance, but I don't have any objective way of verifying that right now.

Jo
Jan 24, 2005

:allears:
Soiled Meat

MockingQuantum posted:

Can anyone explain serialization errors in Unity? In a fashion that isn't totally over my non-programmer head? I'm getting a "serializaton depth limit exceeded" error thrown on play. It's generated by a block of code within an external Unitypackage I'm using in a project, and I'm 99% sure I can't actually access any of the source code in the package, so as far as I can tell, I'm stuck with these serialization errors. Do I need to worry? It doesn't appreciably affect performance, but I don't have any objective way of verifying that right now.

Caveat: I'm far from a Unity expert.

If you're serializing something, you can imagine taking each of the pieces of it and laying it out flat as a text file. For a simple stricture 'myPoint', that might be just writing down the x and y coordinates. If your structure references OTHER structures, you have to flatten them out, too. myPointSet, if serialized, means writing down the serialized versions of each of the 'myPoints' inside. I'm GUESSING that since the depth limit is exceeded, there's a cycle somewhere. A -> B -> A. So to write A out as a flat file, you need to serialize B. But to write out B you need to serialize A. Repeat ad nauseum.

Spatial
Nov 15, 2007

Cycles are a trivial problem for any non-retarded serialiser. I sure hope that isn't it.

Lork
Oct 15, 2007
Sticks to clorf

Jo posted:

Caveat: I'm far from a Unity expert.

If you're serializing something, you can imagine taking each of the pieces of it and laying it out flat as a text file. For a simple stricture 'myPoint', that might be just writing down the x and y coordinates. If your structure references OTHER structures, you have to flatten them out, too. myPointSet, if serialized, means writing down the serialized versions of each of the 'myPoints' inside. I'm GUESSING that since the depth limit is exceeded, there's a cycle somewhere. A -> B -> A. So to write A out as a flat file, you need to serialize B. But to write out B you need to serialize A. Repeat ad nauseum.
However, according to this, there are ways to trigger the error even if you don't have an actual reference dependency loop on your hands. Since MockingQuantum is an external asset that someone thought was finished enough to give to other people, and it's not causing Unity to hang, we can probably assume that it's not a loop.

For example, it might just legitimately serialize more than 7 layers of objects. More likely is that the asset has private/protected fields that would cause an infinite loop if they were serialized. According to that link, even though private/protected fields aren't serialized unless you explicitly mark them as such, Unity will act as if they are and throw up that error unless you mark them as the opposite with the [NonSerialized] attribute.

Dylan16807
May 12, 2010

Jo posted:

Caveat: I'm far from a Unity expert.

If you're serializing something, you can imagine taking each of the pieces of it and laying it out flat as a text file. For a simple stricture 'myPoint', that might be just writing down the x and y coordinates. If your structure references OTHER structures, you have to flatten them out, too. myPointSet, if serialized, means writing down the serialized versions of each of the 'myPoints' inside. I'm GUESSING that since the depth limit is exceeded, there's a cycle somewhere. A -> B -> A. So to write A out as a flat file, you need to serialize B. But to write out B you need to serialize A. Repeat ad nauseum.

On the one hand, Unity is definitely dumb enough to follow A->B->A and exceed depth that way.

On the other hand, Unity has an even stupider problem with its serializer. It fills in every field with dummy objects, which can lead to an exponential amount of dummy objects, so it limits the depth of objects to seven.

And yes those errors are probably going to break something.

Nition
Feb 25, 2006

You really want to know?
A general Unity FYI:

code:
StartCoroutine("MyCoroutine");
StopCoroutine("MyCoroutine");
Stops. But isn't fun to use: No reference link and no error on misspelling etc.

code:
StartCoroutine(MyCoroutine());
StopCoroutine(MyCoroutine());
Doesn't stop.

code:
IEnumerator myEnumerator= MyCoroutine();
StartCoroutine(MyCoroutine());
StopCoroutine(myEnumerator);
Doesn't stop. This is just a transitional phase, bear with me...

code:
IEnumerator myEnumerator= MyCoroutine();
StartCoroutine(myEnumerator); 
StopCoroutine(myEnumerator);
Stops. Added in Unity 4.5.

Edit: Fixed spelling etc for clarity.

One more:
code:
Coroutine myCoroutineReference = StartCoroutine(MyCoroutine());
StopCoroutine(myCoroutineReference);
Stops. Added in unity 4.6.

I actually left that one out because it used to have a bug where it'd throw an error if your coroutine had finished running and you tried to StopCoroutine it. The coroutine class gives no information on its state, so you had to remember to set it to null when your coroutine ended if you wanted to know if you should stop it or not later. However, it looks like that was just fixed. I'm on version 4.6.3f1 and it seems to be OK to call StopCoroutine on a Coroutine that's finished running now.

Nition fucked around with this message at 02:25 on Feb 23, 2015

Obsurveyor
Jan 10, 2003

Nition posted:

StartCoroutine(MyCouroutine());
StopCoroutine(MyCouroutine());
DOESN'T STOP.

I assume the typo is not important in this example but it makes sense why this wouldn't stop: these are separate invocations of the method, a new IEnumerator would be returned for each.

quote:

IEnumerator myCoroutine = CoroutineTest();
StartCoroutine(MyCouroutine());
StopCoroutine(myCoroutine);
DOESN'T STOP. Bear with me...

Is this some crazy C# compiler Unity hack? I haven't tried it but this doesn't look like working code to begin with.

rarbatrol
Apr 17, 2011

Hurt//maim//kill.

Obsurveyor posted:

I assume the typo is not important in this example but it makes sense why this wouldn't stop: these are separate invocations of the method, a new IEnumerator would be returned for each.


Is this some crazy C# compiler Unity hack? I haven't tried it but this doesn't look like working code to begin with.

No hacks, just a variable unfortunately named after a function.

That's my guess too. Unless there's a persistent reference to that enumerator (the last example), or the implementation of your coroutine has some sort of shared state, you're getting a new one each time you call it.

rarbatrol fucked around with this message at 01:09 on Feb 23, 2015

ErIog
Jul 11, 2001

:nsacloud:
I think some of that is expected behavior in C#, but some of it is certainly a horror from an implementation standpoint. I'm not a Unity or C# wizard by any stretch, though, so I'd appreciate if someone could correct anything I might get wrong.

Nition posted:

StartCoroutine("MyCouroutine");
StopCoroutine("MyCouroutine");
STOPS. But isn't fun to use: No reference link and no error on misspelling etc.

Stops because Unity is finding your Coroutine via the string, and then maintaining a reference to the instance of your running Coroutine so it can be stopped via the string. It only works because Unity is silently maintaining that reference for you. The annoying thing here is that it's unclear how you would manage concurrent instances of the same coroutine like this, but it's a convenience function so some limitations are to be expected. This probably should have been built as a separate function with a name that would signal this kind of difference in behavior from what happens below.

Nition posted:

StartCoroutine(MyCouroutine());
StopCoroutine(MyCouroutine());
DOESN'T STOP.

Coroutines work by creating an instance of a function as basically its own class. You're starting the Coroutine by passing in the function, but it doesn't work to stop it because the function itself does not have a reference to the currently running coroutine function. This is expected behavior from an OOP standpoint. The horror here is that they didn't build their convenience function above as a wrapper for this function instead of as a different constructor.

Nition posted:

IEnumerator myEnumerator= MyCoroutine();
StartCoroutine(MyCoroutine());
StopCoroutine(myEnumerator);
Doesn't stop. This is just a transitional phase, bear with me...

This is expected behavior. Again, StopCoroutine is not passing in a reference to an instance of a running coroutine. The reference its passing in is to the function definition itself.

Nition posted:

IEnumerator myCoroutine = CoroutineTest();
StartCoroutine(myCoroutine);
StopCoroutine(myCoroutine);
STOPS.

This is a little unintuitive, but also makes sense to me. You create a reference to your coroutine. When you StartCoroutine it replaces this reference to your function definition with a reference to the actual running coroutine. The reference is called the same thing in both lines, but what it's pointing to is changing. There probably should be better signposting on how StartCoroutine is going to behave for different input types, though.

Basically Unity is trying to make using Coroutines convenient, but in doing so has obscured some of the underlying mechanics in a way that can lead to misunderstandings. Unity is filled with this kind of stuff. It feels like much of the library is convenience functions they wrote so that their tutorials would be easy to write. It swear like half the articles about programming in Unity I read are like, "the manual/tutorial says do it like <x>, but this is (bullshit/slow/weird/limited/wrong). Here's the way you do it properly..." The Vector3.Lerp official tutorial still has a pretty :psyduck: example.

ErIog fucked around with this message at 01:45 on Feb 23, 2015

Dozeworthy
Oct 9, 2012

Inverness posted:

My first suggestion is to call AddInstanceComponent() after your call to AddOwnedComponent(). The instance components property is actually serialized.


AddInstanceComponent doesn't seem to be a member of AActor, and I can't find any reference to it in the documentation. Where did you find that code?

MockingQuantum
Jan 20, 2012



Dylan16807 posted:

On the one hand, Unity is definitely dumb enough to follow A->B->A and exceed depth that way.

On the other hand, Unity has an even stupider problem with its serializer. It fills in every field with dummy objects, which can lead to an exponential amount of dummy objects, so it limits the depth of objects to seven.

And yes those errors are probably going to break something.

Hmm, okay. Well there's nothing I can do, I guess, except not use the package. I haven't been able to pinpoint what element of it is throwing the error. I put it in as bug report to the developer, now I wait...

Nition
Feb 25, 2006

You really want to know?
Sorry, I totally messed up my spelling etc in that Unity example. I've fixed it to read how I meant it to read now, and added one more.

Coroutine myCoroutineReference = StartCoroutine(MyCoroutine());
StopCoroutine(myCoroutineReference);
Stops. Added in unity 4.6.

I actually left that one out because it used to have a bug where it'd throw an error if your coroutine had finished running and you tried to StopCoroutine it. The coroutine class gives no information on its state, so you had to remember to set it to null when your coroutine ended if you wanted to know if you should stop it or not later.

However, it looks like that was just fixed. I'm on version 4.6.3f1 and it seems to be OK to call StopCoroutine on a Coroutine that's finished running now.

Nition fucked around with this message at 02:24 on Feb 23, 2015

Inverness
Feb 4, 2009

Fully configurable personal assistant.

Dozeworthy posted:

AddInstanceComponent doesn't seem to be a member of AActor, and I can't find any reference to it in the documentation. Where did you find that code?
I was looking at 4.7, so nevermind that.

In earlier versions you need to add the component to the SerializedComponents array in AActor which is public. There is also a helper method:
code:
	/**
	 * Helper function to register the specified component, and add it to the serialized components array
	 * @param	Component	Component to be finalized
	 */
	void FinishAndRegisterComponent(UActorComponent* Component);

Dozeworthy
Oct 9, 2012
That worked! Thanks.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Old post but I thought I'd write back here.

Flownerous posted:

I'm not familiar with Unity's system so this is not going to be that useful but there should be a way to extract motion from a bone in the animation? Then the animation would be centered around that bone and you get a vector which can be used to move the game object.

I think I found this. In the inspector view with the imported model, I went to the "Rig" section, and there was a field for a root node. Under that, it had awareness of my armature and the root bone. The tip of the root bone was at the center of mass, so I am seeing how well that worked.

I have other Unity-specific questions now if somebody familiar with it can answer.

Can I group animation states together? I have various idle animations I'd like to fluctuate between. However, when I start into another animation, I don't want to have to draw states out from all of the idle animations into these new states. The idles all start and end at the same position.

Is there a way to see just a model's specific animations when assigning them to the states? In the asset view, I'm getting a raw dump of all possible animations. I have another model imported, and it's obnoxious to wade throw the different model's animations in the general list that I presents to me. If it matters, I import these models from Blender, and it's taking in the animations as actions from Blender. I am wondering if I should be representing my data differently.

Jo
Jan 24, 2005

:allears:
Soiled Meat

Rocko Bonaparte posted:

Old post but I thought I'd write back here.
Can I group animation states together? I have various idle animations I'd like to fluctuate between. However, when I start into another animation, I don't want to have to draw states out from all of the idle animations into these new states. The idles all start and end at the same position.

You can probably make an animation state with a blend-tree as a sub-node. See this: https://www.youtube.com/watch?v=HeHvlEYpRbM

The different is, instead of blending based on 'direction' or something, you can probably generate a random number each time so it will blend randomly between your idles.

Ranzear
Jul 25, 2013

SnowblindFatal posted:

Plz patch in more features. We gonna lan this mofo in like a month or two.

E: Could you give sources or something so we can run this locally? :D
It's possible I could put some code out if you know how to get Node.js going. I keep as much of it shared between client and server as possible using a symlink to the libs directory. It gets a little funny when I change something in the player class and don't restart the server and they start arguing what the state is, but the server has authority outside of the input and position properties (and quite a bit of enforcement on the latter).

It'd need a small tweak to generate its own client IDs, as those come from PHP on page load and embedded to the page to be passed back through the websocket to authenticate, meanwhile half the client ID becomes your object ID.

I feel like a lot of people see the login screen and balk at giving a password, even though my db is more secure than most forums'. Maybe I'll just make it optional.

And yes, Thunderstruck, I do keep the console open and watch for people connecting to play with :3

ZombieApostate
Mar 13, 2011
Sorry, I didn't read your post.

I'm too busy replying to what I wish you said

:allears:

Ranzear posted:

It's possible I could put some code out if you know how to get Node.js going. I keep as much of it shared between client and server as possible using a symlink to the libs directory. It gets a little funny when I change something in the player class and don't restart the server and they start arguing what the state is, but the server has authority outside of the input and position properties (and quite a bit of enforcement on the latter).

It'd need a small tweak to generate its own client IDs, as those come from PHP on page load and embedded to the page to be passed back through the websocket to authenticate, meanwhile half the client ID becomes your object ID.

I feel like a lot of people see the login screen and balk at giving a password, even though my db is more secure than most forums'. Maybe I'll just make it optional.

And yes, Thunderstruck, I do keep the console open and watch for people connecting to play with :3

Your game is fun even though I'm bad at it :v:. I'm apparently permanently dead now, though.

SnowblindFatal
Jan 7, 2011

Ranzear posted:

It's possible I could put some code out if you know how to get Node.js going. I keep as much of it shared between client and server as possible using a symlink to the libs directory. It gets a little funny when I change something in the player class and don't restart the server and they start arguing what the state is, but the server has authority outside of the input and position properties (and quite a bit of enforcement on the latter).

It'd need a small tweak to generate its own client IDs, as those come from PHP on page load and embedded to the page to be passed back through the websocket to authenticate, meanwhile half the client ID becomes your object ID.

I feel like a lot of people see the login screen and balk at giving a password, even though my db is more secure than most forums'. Maybe I'll just make it optional.

And yes, Thunderstruck, I do keep the console open and watch for people connecting to play with :3

Just unload whatever. Maybe I'll get lucky and get it running without problems. :)

Quiet_
Sep 15, 2007

Ranzear posted:

I started a 'quick' prototype for my major project that in four cracked-out days turned into almost a standalone game in itself.

Now I need to find like 100 people to play it at once to see if my server can handle later plans.

http://streamsnipe.me/BeamDuel.php

That was great fun Ranzear!

Ranzear
Jul 25, 2013

ZombieApostate posted:

Your game is fun even though I'm bad at it :v:. I'm apparently permanently dead now, though.

I've set it up to be more fun with a ton of people, sniping each other from the fog and whatnot, but even mano a mano is pretty interesting.

Still haven't seen more than five players at once, and that was classmates.

Still not sure what to do about >150ms ping. If you have too much forward-simulation (lag correction) the firing cycle gets really glitchy, but I've used NEWT to play pretty well up to that.

Like I mentioned, this thing kinda turned into its own beast now, but it's been really helpful for finding major issues (Safari hates mp3) and working out minor technical things viz. not applying latency to the forward-sim of your own (local) ship.

BillyJoe here? You were really jittery. Platform? Browser?

Ranzear fucked around with this message at 00:07 on Feb 24, 2015

ZombieApostate
Mar 13, 2011
Sorry, I didn't read your post.

I'm too busy replying to what I wish you said

:allears:
I noticed that the laser jumps back slightly to a previous position when it actually fires if you're spinning while charging. It also sometimes it looked like you clipped through the laser without it playing the hit sound/taking damage. But I was right around that 150ms ping you're talking about. It just made it a little harder to judge where I should be aiming. Do you have anything like lag compensation? If I understand you correctly, your forward-sim is input prediction from that article?

Ranzear
Jul 25, 2013

Yeah, forward-sim is the simulation since the last frame, and for non-local objects it also adds half your ping as latency compensation.

Aside: This is in comparison to 'reverse-sim' on the server where the game state is rolled back to the client's and pretty much retconned with their inputs. I've avoided this for being too :pgi:

To solve some of the major sync issues above 150ms ping I tried capping that addition of half of your ping at 80ms, so once you're over 160ms you start seeing the usual latency effects. It's a tradeoff against inconsistent firing cycles. I could stand to raise this to 100ms.

The lazer jumping back is your aim direction getting locked at 3/4 charge which is more for consistency, but that might be removable now that lag compensation is far better then it was. Do note that the final firing direction is very consistent across clients though. I'll try getting rid of the aimlock and see if it stays consistent.

So that >150ms consistency might not be coincidental in being 1/4 the firing charge time, but it's more likely related to the 144ms major tick rate (minor tick rate is 24ms). Tick rate shouldn't really affect positional authority though.

So the aimlock could be reduced down to the minor tick rate of 24ms if final firing direction isn't consistent without it.

Ranzear fucked around with this message at 01:58 on Feb 24, 2015

SnowblindFatal
Jan 7, 2011

Ranzear posted:

Yeah, forward-sim is the simulation since the last frame, and for non-local objects it also adds half your ping as latency compensation.

Aside: This is in comparison to 'reverse-sim' on the server where the game state is rolled back to the client's and pretty much retconned with their inputs. I've avoided this for being too :pgi:

To solve some of the major sync issues above 150ms ping I tried capping that addition of half of your ping at 80ms, so once you're over 160ms you start seeing the usual latency effects. It's a tradeoff against inconsistent firing cycles. I could stand to raise this to 100ms.

The lazer jumping back is your aim direction getting locked at 3/4 charge which is more for consistency, but that might be removable now that lag compensation is far better then it was. Do note that the final firing direction is very consistent across clients though. I'll try getting rid of the aimlock and see if it stays consistent.

So that >150ms consistency might not be coincidental in being 1/4 the firing charge time, but it's more likely related to the 144ms major tick rate (minor tick rate is 24ms). Tick rate shouldn't really affect positional authority though.

So the aimlock could be reduced down to the minor tick rate of 24ms if final firing direction isn't consistent without it.

I thought the aiming locking at some point was a feature and a very good one! Gave your opponent the chance to dodge it like a platformer boss's attack! :D

Ranzear
Jul 25, 2013

What I should do is get the hell on with it and give rotation rate towards the aim direction which slows as you charge and is also coupled to the energy bar. This would give more purpose to forward movement having more thrust and whatnot. To go with that, I'd grab the thrust direction instead of aim direction for applying dash.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
I think the rotation isn't wrapping around properly. i.e. if the mouse position is just below straight left, and you move it just above straight left, then the ship will do a very long counter-clockwise rotation instead of a short clockwise rotation.

Ranzear
Jul 25, 2013

OneEightHundred posted:

I think the rotation isn't wrapping around properly. i.e. if the mouse position is just below straight left, and you move it just above straight left, then the ship will do a very long counter-clockwise rotation instead of a short clockwise rotation.

Yeah, I was still working on it when you dropped in. That sign flip is a bitch and it took me too long to remember how to do it right.

All good now, though needs some tuning.

Fun times: I like to put <!doctype html> at the top of my php files so I can preview them with a drag into chrome, but this causes the window innerWidth and innerHeight to be wildly misreported and cause scrollbars to appear. So stupid and weird.

Ranzear fucked around with this message at 05:07 on Feb 24, 2015

Lil Miss Clackamas
Jan 25, 2013

ich habe aids
Is there a difference between scripting a mesh in Unity versus importing one? I'm trying to create a quadsphere, and I'm not sure how to do it from scratch with C#. Are there any downsides to creating a polysphere in Blender and then importing that?

ModeSix
Mar 14, 2009

I'm working on a project in Unity and I want to store/retrieve data from an XML file.

I was wondering if anyone could point me at a relevant tutorial for using XML as a database solution within Unity, Google is throwing up a lot of garbage answers.

Obsurveyor
Jan 10, 2003

ModeSix posted:

I'm working on a project in Unity and I want to store/retrieve data from an XML file.

I was wondering if anyone could point me at a relevant tutorial for using XML as a database solution within Unity, Google is throwing up a lot of garbage answers.

Just look up "C# XML serialization". There's nothing special about Unity and XML unless you're looking to serialize Unity objects to XML and even then, it's probably easier to start with regular C# object serialization and then figure out the Unity gotchas, if any.

My personal opinion: You should use JSON(see Json.NET) instead of XML.

xgalaxy
Jan 27, 2004
i write code
Unless you need the extra features of Json.Net the community made MiniJSON outperforms it in every imaginable way. Surprising for a 1 file json (de)serializer that exists in a github gist instead of a proper repo. Json.Net is slow and eats a ton of memory, just fyi.

BabelFish
Jul 20, 2013

Fallen Rib
UE4 4.7 is out, and dang does it have some cool stuff:
https://www.unrealengine.com/blog/unreal-engine-47-released

Blueprint merging!

BabelFish fucked around with this message at 22:32 on Feb 24, 2015

Ranzear
Jul 25, 2013

xgalaxy posted:

Unless you need the extra features of Json.Net the community made MiniJSON outperforms it in every imaginable way. Surprising for a 1 file json (de)serializer that exists in a github gist instead of a proper repo. Json.Net is slow and eats a ton of memory, just fyi.

Definitely JSON for anything you don't have to use human eyes on. Can be a lot smaller too. BeamDuel was made just to have a handle on how much JSON I could cram through a websocket. Answer: A lot.

Obsurveyor
Jan 10, 2003

xgalaxy posted:

Unless you need the extra features of Json.Net the community made MiniJSON outperforms it in every imaginable way. Surprising for a 1 file json (de)serializer that exists in a github gist instead of a proper repo. Json.Net is slow and eats a ton of memory, just fyi.

Thanks for this, very good to know. I've only ever used Json.NET for playing around so performance wasn't a huge deal. I see the huge memory usage in the profiler now though.

Adhemar
Jan 21, 2004

Kellner, da ist ein scheussliches Biest in meiner Suppe.

Ranzear posted:

Definitely JSON for anything you don't have to use human eyes on.

How so? I would say JSON (and XML) are for when you DO need human eyes on it. If not, and you want maximum performance (and profiling shows serialization as your bottleneck), use a binary format like Protobuf, Cap'n Proto, or SBE.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

XML is for when someone forced you at gunpoint to use XML.

Don't protobufs and cap'n proto have optional human-readable encodings?

Shalinor
Jun 10, 2002

Can I buy you a rootbeer?

Subjunctive posted:

XML is for when someone forced you at gunpoint to use XML.
It's still better than JSON. JSON is human readable like urine is perfectly safe to drink.

Adbot
ADBOT LOVES YOU

Unormal
Nov 16, 2004

Mod sass? This evening?! But the cakes aren't ready! THE CAKES!
Fun Shoe

Subjunctive posted:

XML is for when someone forced you at gunpoint to use XML.

Don't protobufs and cap'n proto have optional human-readable encodings?

XML is sometimes also useful for when you need schema validation or structured queries and transforms. This doesn't happen that much in game dev.

XML is also way more readable to designers than JSON is. JSON is readable to developers, but not to designers, because lots of designers have worked with HTML at least a little, but JSON is more out there.

I use SimpleJSON a lot, because I can just paste that one file into a project where I need some json parsing, and I'm off to the races with minimum fuss.

http://wiki.unity3d.com/index.php/SimpleJSON

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply