I'm creating simple game and I need to create extending cylinder. I know how to normally do it - by changing objects pivot point and scaling it up, but now I have texture on it and I don't want it to stretch.
I fought about adding small segments to the end of the cylinder when it has to grow, but this wont work smooth and might affect performance. Do you know any solution to this?
This the rope texture that I'm using right now(but it might change in the future):
Before scaling
After scaling
I don't want it to stretch
This is not easy to accomplish but it is possible.
You have two ways to do this.
1.One is to procedurally generate the rope mesh and assign material real-time. This is complicated for beginners. Can't help on this one.
2.Another solution that doesn't require mesh procedurally mesh generation. Change the tiles while the Object is changing size.
For this to work, your texture must be tileable. You can't just use any random texture online. Also, you need a normal map to actually make it look like a rope. Here is a tutorial for making a rope texture with normal map in Maya. There are other parts of the video you have to watch too.
Select the texture, change Texture Type to Texture, change Wrap Mode to Repeat then click Apply.
Get the MeshRenderer of the Mesh then get Material of the 3D Object from the MeshRenderer.Use ropeMat.SetTextureScale to change the the tile of the texture. For example, when changing the xTile and yTile value of the code below, the texture of the Mesh will be tiled.
public float xTile, yTile;
public GameObject rope;
Material ropeMat;
void Start()
{
ropeMat = rope.GetComponent<MeshRenderer>().material;
}
void Update()
{
ropeMat.SetTextureScale("_MainTex", new Vector2(xTile, yTile));
}
Now, you have to find a way to map the xTile and yTile values to the size of the Mesh. It's not simple. Here is complete method to calculate what value xTile and yTile should be when re-sizing the mesh/rope.
Related
I am talking about the Camera settings in Unity3D.
I'm trying to figure out if I can change (at least) the background color of the gray area in the screenshot. The limits of the camera are changed programmatically. The motivation lies in the fact that the playing area has to change dynamically based on whether a child or an adult is playing. The screen is huge around more than 83 inches. When rescaling the playing area, the area that is not drawn is gray and a bit ugly, I would like to know if you can define at least the color, or better still if possible with an image.
The screenshot you see is the screen capture in fullscreen mode, so it includes all the pixels.
After this brief explanation in words and images, let's go to the specifics of the technical details. This is how I resize the room design area:
public static void SetViewportCalibration()
{
var camera = Camera.main;
camera.pixelRect = new Rect(MinX, MinY, MaxX, MaxY);
}
Is it possible to set the color of that gray area outside the new Rect(MinX, MinY, MaxX, MaxY)?
There's two ways off the top of my head to accomplish this. Both ways use two Cameras.
The first way. Create a second Camera. The second Camera should have Depth LESS than the dynamic camera. This second, "Background" camera can then display anything you'd like, for example, a separate Skybox, a separate UI, other scene content, etc. etc.
The second way. Your dynamic camera is actually not resized dynamically. Instead, render your camera to a Target Texture. Use this texture in a material, and assign the material to a Quad mesh (most appropriate). This mesh can then be used in your scene like any other 3D object, which means not only can you position it, but scale it and even rotate it. The new camera that you added can have it's own Skybox, UI etc. etc.
I would opt for the second way. Partly personal preference, but also because it sounds like it might suit your situation better and be easier to implement. You can also implement many more effects for extra "wow".
Try to create another camera with no objects in its view and the following settings:
Clear Flags: Solid Color,
Background: Pick a color,
ViewPort Rect: X = 0, y = 0, w = 1, h = 1,
Depth: A smaller value than the other camera (Set the depth of this camera to 0 and the depth of the other camera to 1)
This camera will work as background of your screen.
I hope that I understood the question :)
Since my day one in Unity development, I've seen tips and stuff saying that we should never tint sprites. If we want sprites of different colors, create them and place them in the same texture, and then swap in the differently-colored sprites.
The reasoning is that tinting sprites will break batching.
I have created a small demo.
Situation 1
The same square sprite is used in 6 game objects. No surprise here. In the stats, there is 1 batch. 5 are saved by batching.
Situation 2
The same square sprite is used in 6 game objects again, but this time, all of them are tinted red with the same color value.
Shouldn't this be breaking batching already?
Situation 3
For the sake of completeness, I tinted the square sprites with different colors. Still, we have 1 batch and 5 saved. Nothing's changed.
Additional information
I captured Situation 1 & 2 during a single play through, and situation 3 in a separate play through.
I tried tinting the sprites directly in the editor by changing the "Color" field of SpriteRenderer and through scripts by changing SpriteRenderer.color. The results are the same.
Changing color of sprites on the SpriteRenderer component shouldn't break batching. What breaks batching is when you change the SpriteRenderer's sprite, the material or even when you try to access the material with SpriteRenderer.material property.
For example,
This breaks batching:
SpriteRenderer sr = GetComponent<SpriteRenderer>();
sr.material.color = Color.red;
because you are accessing the material. It will create new material instance when you access the material property for the first time.
This will not break batching:
SpriteRenderer sr = GetComponent<SpriteRenderer>();
sr.color = Color.red;
It will not because it is not accessing the material property. Even though it will not break batching, one issue with it is performance. It affects performance when you do this.
AFAIK, tinting is basically setting a vertex color. This is done for particles, where you can set random start colors and all the particles are rendered in a single draw call. Vertex color does not change/create a new material.
Not sure how that was handled in early Unity versions, but sprites should be simple quads and therefore support vertex colors. The Sprite shader probably works the same way in terms of tinting.
In general, you are right. Changing shader properties will create a duplicate of that material, or it will change the material itself and affect all instances using the material. Did you use the tint on the sprite material, or on the spriteRenderer?
By hand, I could think of using MaterialPropertyBlocks, but maybe Unity did exactly that for sprites.
Some more Detail to clarify:
A You have "Material01.mat" - it's green. You copy this material to 10 sprites. You want to have 10 colors? You have to create 10 materials, each holding the desired color - 10 Draw calls.
You can do the same by script, just change material.color. But Unity will duplicate the materials for you. Still 10 Draw calls. Some people are confused why it breaks batching until they hear about this.
B You changed the RENDERERs tint. This Sprite Renderer will write the tint color into your sprites vertices (probably 4?) - using the vertex color attribute. It's basically free, because they are transmitted to the gpu anyway (afaik)
As I said above, the same is used in the Particle System, to allow rainbow particles with 1 Drawcall.
So, any particle Shader, self-written shader, or Sprite Shader should work with this. All you need is a.albedo = c.rgb * IN.vert.color (a bit pseudo code here)
That means, the same shader, and the same material can be used for multiple objects, having different vertex colors. That won't break batching.
You can even have different objects of any shape and vertex count, giving them different vertex colors (per vertex, like gradients etc) and it will still batch.
Check Static whenever possible, feed information into vertex colors, and for moving objects, try to keep them under 300 verts, so dynamic batching can work.
But for Sprites, unity automated this for you, you simply need to use the SpriteRenderer - that's why you don't use a quad with a texture, but a "Sprite" and a SpriteRenderer.
Again, I could be wrong and the SpriteRenderer actually uses MaterialPropertyBlocks, but it works almost the same. These variables can be set per object and do not create new DrawCalls. The variable values are used in the shader, so the material/shader is the same for multiple objects.
I have a 2D polygon that is defined by a edgeCollider. Is there a way to hide everything that is outside of the shape and show only what is inside?
I tried using skyboxes and lights. I thought about creating a mask(but i dont know how to create such a mask).
Is there a way to only show what is inside the shape defined by edge collider?
What about using the colliders trigger events?
Set this polygon as a trigger in the edgeCollider2D component in the inspector. Then you can use the collider OnEnterTrigger2D.
Your gameobjects are all disabled until this edgeCollider collides with in. Then disable the gameobject OnExitTrigger2D.
If you wanted to limit it to a certain number of object only. You would set a layer to only hide/show these object.
void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.layer == "hiddenObject"){
other.gameObject.enable = true;
}
}
Then the reverse on the OnTriggerExit2D.
I'm not sure the effect that you are aiming for. So another solution could be a postprocessing shader.
I can only give a high level description on this however.
You would take the final screen image texture, and the current position of the polygon and then add the pixels from the screen texture to the polygon texture and output this texture. (this shader has to exists already).
But you want the inverse of these.
https://docs.unity3d.com/Manual/shader-TransparentCutoutFamily.html
You're wanting to keep what's in the hole and get rid of what's outside of it?
You can download the built in shaders to edit them here
https://unity3d.com/get-unity/download/archive
Just find your version of unity and select builtin shaders from the drop down.
Edit: "SPOTLIGHT!", try this but with your custom shape
http://www.shaderslab.com/demo-49---spotlight.html
I am working on a 3D game and it has lots of game objects in a scene. So I'm working on reducing draw calls. I'v used mesh combining on my static game objects. But my player is'n static and I can't use mesh combining on it. My player is nothing but combination of some cubes which uses the standard shader and some different color Materials on different parts. So I'm guessing, I can use texture atlasing on my player to reduce darw calls. But I don't know how to do it.
Is my theory of work right? If I'm right please help me with atlasing, and if I'm wrong please point out my fault.
Thanks in advance.
Put all the required images into the same texture. Create a material from that texture. Apply the same material to all of the cubes making up you character. UV map all cubes to the relevant part of the texture (use UV offset in the Unity editor if the UV blocks are quite simple, otherwise you'll need to move the UV elements in your 3D modelling program).
I'm totally new in game-dev and would like to know the best practice about above question.
Let me explain more.
I want to create 2D game with top-down view and with free movement (without snapping to the grid) just like any Zelda game on GameBoy.
How should I store map bounds? Is there a way to do this automatically? For example I have a texture with background and texture with foreground where black color should appear transparent and should allow to move in space of it.
Thanks in advance.
For easy 2D collision detection, you'll probably implement bounding boxes.
Basically you will create a rectangle that represents every Game Object. The coordinates and size of the rectangle will be the same as the Texture2D (it is common to make this a property on the given class). Every time you update the position of your Texture, you update the position of your bounding box.
Now to check for collision, just loop through your game objects and see if any of the bounding boxes intersect.
Once you get the idea, you'll see that its very easy to implement. XNA also provides some math helpers to abstract the math (though its simple addition and subtraction).
Try this link for a more in depth explanation with code examples: http://www.dreamincode.net/forums/topic/180069-xna-2d-bounding-box-collision-detection/