Does changing multiple sprites on a single animation affect performance? - unity3d

I have been building a 2D sprite based game for which I want to have the player be able to customize their equipment. This means that although I am fine with drawing the content, I'd need to ensure animations in the game run fine on top of each other. For this, I have been preparing a game object with several children to account for the equipment:
Each of the children runs a single animation and should have to follow the player, which I accomplish by using transform.localPosition = Vector2.zero; on the Update of the script each takes, so they hook to the parent's pivot and follow the player. While this has worked for the most part, there are moments in which all of the objects are not synchronized and as such sometimes the parent object (the body) is seen where it shouldn't since the other game objects should render on top:
Aside from that, to make it easy for the children to follow the parent position I had made sprites which are all the same size, which risks me having to load a lot of transparent space per sprite.
Another problem that I just noticed as I'm trying to address the issue of loading too many useless pixels involves the positioning with other objects such as the Sword game object, which doesn't follow the player fully if I use sprites that are not perfect squares (see this question for details How to align sprites of smaller sizes to a moving gameobject sprite? and this one Sibling sprite doesn't appear to follow main GameObject sprite even when transform.position updates)
I tried to fix this by making the Sword a child of the Hero, but even then changing the position through a function that sets values to add on to transform values of the sword game object only change the position of it relative to the initial value. I attempted changing the pivot of the sword sprites to a custom value to guess where the center of it would align with the main game object and appear in the right position, but even that doesn't seem to work.
I'm kind of getting tired with my current process, as I have to rely on several animations for each of the game objects, both parent and children, so that these obey to different layers in a single animator (or in the case of the sword, a separate animator), all to ensure there is some synchronization that doesn't always occur:
I really don't mind the web that is turning out in what I'm doing, but the fact that I have to repeat it across multiple layers with no real guarantee that all the objects would appear right on top of each other due to the fact of having multiple animations playing, and loading multiple sprites with empty space is becoming more of a chore than enjoyment.
So I think I came up with a possible solution: If I could make a single animation for the whole equipment used at any given point (whether only wearing pants or wearing full equipment), then having this single animation could guarantee synchronization across parent and children without the need for animator layers or special functions to update position or worrying about pivots or square sprites if I can set the position of non-square sprites in the animation, with the downside that I would need to account for every single animation for each possible equipment variation (so if I had even 3 of each sword, pants, boots, etc. that would mean 3^6 animations) and make a more complex web of animator states. The only thing I'd be worried about in this case, however, would be the performance, if having too many animations for a player would affect how fast these load. But at the benefit of eliminating the other problems mentioned, my question boils down to this:
Is it better to have a single game object with animations that change multiple sprites across children game objects and a single animator that chooses states based on multiple variables, or game objects with multiple animations that change a single sprite for each, and a single or multiple animators with multiple layers that choose states based on multiple variables?

There isn't really a set answer for something like this. It really just depends on how good your/the players computer is when playing the game. Sorry if this isn't what you wanted.

Related

How to align sprites of smaller sizes to a moving gameobject sprite?

I used to have a game object used as a sword with sprites with a specific size, despite including quite a bit of transparent space, to ensure these are aligned properly with the player game object:
This ensures the sword follows the player as he jumps by making use of the hero transition like this transform.position = hero.transform.position; , and though there may be issues with sprite changes I would address these later.
However, since I want to have several different equipment, and other sprites of this same sword might need a bigger dimension to look good (such as a sword attack while standing on the ground), I could either make even bigger sprites which would eventually affect performance due to transparent pixels loading, or I thought of making sprites with specific sizes:
(if this works I'd make sure to draw and put them close together instead of being separate)
And although when I prepare the animation I make sure to shift the position of the new sword to where it would be based on the player sprite on its own air attack animation (thus I had to modify this frame by frame,
The sword doesn't seem to follow the player, even when its game object still uses the script that makes use of the player's transform position:
I'm assuming something else has to be changed frame by frame, but what could it be? Is there a way to align or anchor a smaller sprite to follow the pivot of a bigger sprite?
All rotation or changing of sprites is done relative to the sprite's Pivot Point.
When you currently swap your sprites, your sword looks like it is rotating on it's blade rather than the handle.
Change the Pivot point to the handle, and it will do most of the work.
The rest is just making sure the handle of the sword follows the character's hands.

How to avoid edge collisions in tile-based physics (Unity2D Physics)?

I'm working on a 2D side-scrolling physics-based game.
The maps for this game are created following a tile-based system that reads from a text file, and blocks are created on the game to draw the level. Some objects, using physics' gravity, need to "slide" across sections of multiple blocks placed together (like floors, but built from different blocks, due to the tile-based system).
Even though blocks are placed "mathematically" exactly one by the other, because each block has its own BoxCollider2D, the physics engine still detects the "edge" sometimes, and the object that should be sliding across the multiple block section (which also has a BoxCollider2D, plus a RigidBody2D) just crazily bounces off off the surface (I'm assuming because of edge / edge collision).
I've tried adding a small edge radius, but it doesn't really work. Is there any way in which I could easily "link" those block sections together, or to "smooth" the edges in such a way that the physics engine wouldn't realise they are there?
I'm attaching 4 images to make everything more understandable and clear:
Floor block BoxCollider2D inspector properties.
Moving object BoxCollider2D and RigidBody2D properties.
Game screenshot (moving object standing on a "floor" formed by various independent blocks; note that the sprite is rounded, by the BoxCollider2D attached to the object is not).
Game screenshot on editor, with various blocks highlighted to show how their BoxCollider2D boxes (supposedly) overlap, which shouldn't leave any edge for the moving object to collide with.
Thanks in advance!

How do I force orbital movement around a point in space, while maintaining forward/backwards capability on a player?

Long-winded question out of the way, I'll provide a diagram of what I am going for:
The red square represents the character, the blue rectangle represents the camera, the green dot represents the center of the "stage", and the black circle is the stage itself.
What I desire is to essentially lock the player's movement around the "center" of the stage, so that anytime you move left or right you are more or less rotating around said center. However, I also want the player to be able to move forwards and backwards to/from the center as well. Keep in mind I want the camera to always stay directly behind the player. I have tried many different methods, and the latest is the following:
I took a default actor, attached a spring arm, attached a child actor to that (gets possessed to become the playable character), attached another spring arm, and finally the camera to that. I then added the blueprint code to the first spring arm so that it was the one being controlled by the left/right controls. However, upon hitting play, the only thing that moves is the camera, and it can only move forwards and backwards.
I'm admittedly pretty new to Unreal Blueprints, so any help would be appreciated.
Alright, I figured it out.
Here's the setup needed if anyone else wants something similar.
For the player themselves, you'll need something like this:
The important thing is to center the root mesh where you want to rotate around. The spring arm's target arm length will be affected for the player mesh movement, giving the illusion you are physically moving the character. The second spring arm isn't necessary unless you wish to have more control over the camera to player distance.
For the rotation Blueprint, you'll need this:
The target is whatever you named the root mesh. (Mine was called Center) Drag and drop it from the hierarchy.
For the forward/backward movement, you'll need this:
The target is what you named the spring arm. (I left mine as the default "SpringArm") Again, just drag and drop it from the hierarchy.
Adjustments in Project Settings:
Yes, my inputs are backwards from what you'd think. I felt it was quicker just to reverse the inputs instead of adjusting whatever was causing the movement to be backwards in the first place. (It's probably just the sphere orientation.) Also, you'll notice I have the w and s inputs set to 5 or -5 instead of 1 or -1. This is due to the fact the movement was slow otherwise. I'm sure there's a fix that doesn't involve changing the input axis scale, but honestly I won't really have a reason to alter the values at any point in my project. If it ever comes up where I do need to, I'm sure there's a bypass to change the values from within blueprints anyways.
End result:
End Result Video
If I remember correctly, child actor components are a bit different from other components in that they are transformation independent, that is they do not update their transformation when their parent component moves around.
I find it a bit strange that you would separate your player actor and the camera component. Normally, the player "pawn" contains the mesh and camera components for one player.
I would suggest you do the following:
Create a player actor (e.g. a "pawn" or "character" class)
Create the following component hierarchy:
Root Scene -> Spring arm -> Skeletal or static mesh -> spring arm -> camera
Your root scene is the green center in your drawing. You can then basically use the blueprint you already have to rotate and move your player.

Automatically add platform area tile as player approaches the edge of current tile

Firstly, I'm new to Unity and I'm currently learning c#, please be gentle!
As a project, I'd like to create a simple 3d platform game. The idea being the player starts on a square tile, which is the game platform playing area. They explore different elements on this tile by moving around.
The perspective is 3rd person, so the player is looking down on the action. As they approach the edge of the tile Unity recognises this and adds another tile to the existing one, basically doubling the playing area.
As the player moves around further to the tiles edge, other tiles are added, increasing the discovered areas each time.
My thinking to achieve this would be to have 5 tile game objects, that have different elements like trees already built on them. The question is what is the best way to achieve this.
Would it be to build the complete level with all tiles and then using code restrict how far ahead the player can see, basically to the width and length of the tiles.
Or would it be better to trigger a new tile to appear as the player approaches the edge of the current tile.
Thought, links to example code that I could recycle would be very handy.
Thank you.
The question is primarily opinion based, but here is some advise:
There is no right way to make a game in unity. The correctness is mainly focused on performance; memory and processing.
There are two approaches here:
condition: Your world is endless (or very large) and player moves very slowly over time (say each tile takes more than a second to traverse).
solution: Do not instantiate everything at start, instead when player reaches the edge of a tile look for the next tile in your level structure to retrieve its data and then instantiate its objects.
condition: Your world is not very large (say it has less than overall 10K objects) OR player can move fast (as in Age of Empires game).
solution: Instantiate everything in loading phase and deactivate the game objects as they are being instantiated so that nothing is getting processed at the start of the game. In this case the level structure is a collection of game objects where you activate or deactivate them.
Hints:
Pooling is a good practice when it comes to repetitive objects. Pool is basically an empty game object with a script, and many many deactivated children.
e.g. If you have 1K trees of the same kind you better have a tree pool. Create a game object named tree pool, add a pool script to it and make that script generate 1K deactivated tree game objects in the loading phase. Then whenever your level generator needs a new tree just fetch a tree from tree pool and activate and reposition it. Make sure you clean up the pool after the game ends to prevent memory leak.
you can implement the pool as you like to provide object variations for a specific pool.
Instantiation in run-time is costly especially in mobile devices. Whenever you need to instantiate several game objects at once consider using a coroutine to prevent lag or freeze (this applies to loading phase too).
e.g.
IEnumerable CreateObjects(Data[] data)
{
foreach(var e in data)
{
Instantiate(e);//instantiate here and then wait
yield return null;//this line prevents lag
}
}
//...
StartCoroutine(CreateObjects(data));
//...
Having many active game objects is also costly especially in mobile devices. If many active game object have heavy scripts, the update methods will ruin performance. If many active game objects have rigidbodies or colliders the physics engine processing gets heavy.
Activating game objects is costly but less than instantiation, since it only runs Start method on its script if any, and also causes the physics engine to re-evaluate its structure if it has static collider or rigidbody.
Rendering is costly if only the rendered visuals are (fully or partially) visible to the cameras.
Create an editor project where you can design your levels. in this project you will make use of unity's editor classes to generate some kind of data (JsonObject) which represents your whole world. (collection of levels, tiles in each level and objects in each tile). Moreover you can have other data such as objectives and stuff each stored in a different JsonObject. Then use this data in your game by reading it and storing its structure in memory.
The reason I recommend JsonObject to store data is its size, portability, flexibility, accessibility and simplicity to work with. JsonObject is a dictionary stored as a plain text. and since it's a text you can encrypt it as you like

How to handle a game world that wraps, using cocos2d on the iPhone

I have a game world that's much bigger than the view port, the main character stays in the center of the view port at all times and the background layer is moved around to give the impression of the character moving. I want to make it so that the game world wraps, meaning if the the character keeps traveling either left or right they will eventually end up back at the starting position. There will be moving entities in the game world so the biggest problem I foresee is that if you go to the far right of the map you should be able to see any of the moving entities that are within the first small section of the far left of the map.
I've thought a bit about this and any solution I've come up with seems far too complicated. Like creating two identical game worlds side by side and moving them around accordingly. I live in hope that there is an elegant solution to this. Any expertise you can share would be greatly appreciated.
I'm using cocos2d on the iPhone just in case that makes any difference.
An example might be to have an x,y offset for your camera, and a multidimensional array of sprite objects.
As the player moves, the offset value changes, e.g., xMove = -1.4 and yMove = +2.6.
Then you would iterate and change the positions of all the tiles by that amount.
Next, you would identify the sprites that are too far away from the center of the screen (0,0) and re-position them to the opposite side, so they will always be visible.
This would all be done on the same scheduled 'tick' so no graphical artifacts occur.
I'm pretty surprised no one has made a wrappable tile map yet for cocos2d.
I can't give cocos2d specific advice, but I would say the most common way to do this is to create one game world, draw (parts of it) multiple times and make sure that your logic for things like collisions and AI checks for wrap-around where appropriate.
So if your player character is close to the corner of the world, you'd draw the world four times with different offsets. This needn't actually draw every single thing in the world four times any more than you would normally need to draw the entire world when only a small part of it is on-screen.