In my game I want to make the player object transparent for 2 seconds by scripting at run time if the player collided with a specific object during the game ... is it possible ?
Check for collision. When the collision that you want is triggered then you can change the transparency.
GameObject g;
// 50% Transparency.
g.renderer.material.color.a = 0.5f; // a is the alpha value.
// 100% Transparency.
g.renderer.material.color.a = 1.0f;
You can do just this to make your program wait time: http://docs.unity3d.com/Documentation/Manual/Coroutines.html
You will notice the example is exactly your question.
Try this extension method:
public static void ChangeAlpha(this Material mat, float alphaValue)
{
Color oldColor = mat.color;
Color newColor = new Color(oldColor.r, oldColor.g, oldColor.b, alphaValue);
mat.SetColor("_Color", newColor);
}
You can then call it by:
gameObject.renderer.material.ChangeAlpha( Your Alpha Value );
In Unity 5, the best way (TO MAKE AN OBJECT INVISIBLE) that worked for me was to:
Set all of the game object's materials you want to be invisible to transparent under the rendering mode.
Then, click on the small round button next to albedo and scroll down on the list of items given until you find one called UIMask.
Highlight it and press enter.
* Note that this is a hard fix and I'm not sure if you can change this with code.
** This was made for boundaries in roll-a-ball with a player jump function included. I needed to make the walls invisible but also collision-able to stop the air born player object.
This can be simply done with shaders, which you can quickly and efficiently change at runtime:
Create new material and set the shader to use the
Unlit/Transparent Cutout
Assign your game object to use this new material
Turn off all of the stuff in the mesh render of the game object: set cast shadows to off, receive shadows disabled, contribute to global illumination to disabled, turn off your light probes and reflections, set motion vectors to 'force no motion', turn off dynamic occlusion.
Also don't forget to remove the mesh collider of the game object.
Related
So I'm looking to create an effect of having a bubble around my player which, when he enters a hidden area (hidden by tilemaps) the bubble activates and it essentially has an xray effect. So I can see the background, the ground and all the items inside the area I just can't see the blocks themselves.
So pretty much going from this
To this
And as I go further in the more gets revealed
I have no idea what to even begin searching for this. So any direction would be greatly appreciated
First of all, I want to get something out of the way: Making things appear when they are nearby the player is easy, you use a light and a shader. Making things disappear when they are nearby the player by that approach is impossible in 2D (3D has flags_use_shadow_to_opacity).
This is the plan: We are going to create a texture that will work as mask for what to show and what not to show. Then we will use that texture mask with a shader to make a material that selectively disappears. To create that texture, we are going to use a Viewport, so we can get a ViewportTexture from it.
The Viewport setup is like this:
Viewport
├ ColorRect
└ Sprite
Set the Viewport with the following properties:
Size: give it the window size (the default is 1024 by 600)
Hdr: disable
Disable 3D: enable
Usage: 2D
Update mode: Always
For the Sprite you want a grayscale texture, perhaps with transparency. It will be the shape you want to reveal around the player.
And for the ColorRect you want to set the background color as either black or white. Whatever is the opposite of the color on the Sprite.
Next, you are going to attach a script to the Viewport. It has to deal with two concerns:
Move the Sprite to match the position of the player. That looks like this:
extends Viewport
export var target_path:NodePath
func _process(_delta:float) -> void:
var target := get_node_or_null(target_path) as Node2D
if target == null:
return
$Sprite.position = target.get_viewport().get_canvas_transform().origin
And you are going to set the target_path to reference the player avatar.
In this code target.get_viewport().get_canvas_transform().origin will give us the position of the target node (the player avatar) on the screen. And we are placing the Sprite to match.
Handle window resizes. That looks like this:
func _ready():
# warning-ignore:return_value_discarded
get_tree().get_root().connect("size_changed", self, "_on_size_changed")
func _on_size_changed():
size = get_tree().get_root().size
In this code we connect to the "size_changed" of the root Viewport (the one associated with the Window), and change the size of this Viewport to match.
The next thing is the shader. Go to your TileMap or whatever you want to make disappear and add a shader material. This is the code for it:
shader_type canvas_item;
uniform sampler2D mask;
void fragment()
{
COLOR.rgb = texture(TEXTURE, UV).rgb;
COLOR.a = texture(mask, SCREEN_UV).r;
}
As you can see, the first line will be setting the red, green, and blue channels to match the texture the node already has. But the alpha channel will be set to one of the channels (the red one in this case) of the mask texture.
Note: The above code will make whatever is in the black parts fully invisible, and whatever is in the white parts fully visible. If you want to invert that, change COLOR.a = texture(mask, SCREEN_UV).r; to COLOR.a = 1.0 - texture(mask, SCREEN_UV).r;.
We, of course, need to set that mask texture. After you set that code, there should be a shader param under the shader material called "Mask", set it to a new ViewportTexture and set the Viewport to the one we set before.
And we are done.
I tested this with this texture from publicdomainvectors.org:
Plus some tiles from Kenney. They are all, of course, under public domain.
This is how it looks like:
Experiment with different textures for different results. Also, you can add a shader to the Sprite for extra effect. For example add some ripples, by giving a shader material to the Sprite with code like this one:
shader_type canvas_item;
void fragment()
{
float width = SCREEN_PIXEL_SIZE.x * 16.0;
COLOR = texture(TEXTURE, vec2(UV.x + sin(UV.y * 32.0 + TIME * 2.0) * width, UV.y));
}
So you get this result:
There is an instant when the above animation stutters. That is because I didn't cut the loop perfectly. Not an issue in game. Also the animation has much less frames per second than the game would.
Addendum A couple things I want to add:
You can create a texture by other means. I have a couple other answer where I cover some of it
How can I bake 2D sprites in Godot at runtime? where we use blit_rect. You might also be interested in blit_rect_mask.
Godot repeating breaks script where we are using lockbits.
I wrote a shader that outputs on the alpha channel here. Other options include:
Using BackBufferCopy.
To discard fragments.
How to create your own animations in 2D unity? I mean, for example, Change of color, position and the like?
My point is how to make an animation that would, for example, change the color of the character to red, then normal, and so on - it could be an animation taking damage. So how do you do something like this? Yes, from total scratch!
Unity allows you to create an animator controller for any sprite. From there, you should able to create different animation clip via the animation window. In each animation clip, there are different properties you can manipulate either the sprite color, position.. etc. To make it work I'll suggest to push record in the the animation window to create your animation clip. From there, you can fix the animation transition between clips via animator window to your liking. It works similar in 3D but with gameObject.
Title pretty much sums it up. I am trying to adjust the scale of cloned prefabs during runtime, through a UI slider. However on first run the slider doesn't seem to have any effect on them, and on second run the Objects just keep one value from the slider and appear already taller or shorter. I need the slider to adjust the height of the objects dynamically, just as it does on a normal, not cloned, object. Any help will be greatly appreciated. Thanks!
The script works on normal objects, not clones.
Here is my slider method :
public void slideScale(float textNumber)
{
Vector3 scale = Wall.transform.localScale;
scale.y = textNumber;
Wall.transform.localScale = scale;
}
I expected to be able to change the height, while moving the slider.
A value is being stored and just takes place on second run while the slider still seems not to be affecting anything.
Looks like you're modifying the reference to the Prefab instead of the instance of a prefab (clone, in your words).
Here's how you store the reference to an instance of a prefab:
// Spawn an object based on a prefab "Wall"
// and store the spawned object in variable "instance"
GameObject instance = Instantiate(Wall);
// Modify the instance properties
instance.transform.localScale = scale;
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'm making a 2D Shooter game in XNA. I had been working on the shooting speed of the player (Every how often can the player shoot another bullet) and made it so that the player can only shoot again once the previous bullet has traveled a certain distance like so:
if (this.bulletList[0].BULLETS[(this.bulletList[0].BULLETS.Count) - 1].X >= Pos.X + attackSpeed)
canShoot = true;
Where bulletList is the available Projectiles the player can shoot, BULLETS is the List of Bullets already shot, and attackSpeed is the rate in which the bullets should be shot, or simply put: the distance the bullet has to travel until another bullet can be shot.
Now I've been working on Collisions. My method was to dispose of a bullet after it hits a target like so:
for (int i = 0; i < player.BULLETLIST[0].BULLETS.Count; i++)
{
if (CollisionManager.PlayerBulletOnBot(player.BULLETLIST[0].BULLETS[i], bot))
player.BULLETLIST[0].BULLETS.RemoveAt(i);
}
Problem is, if the bullet has been removed upon hitting a target, I can no longer ask if that bullet has passed the given distance for another bullet to be shot.
To solve that, I'd like the bullet to turn invisible upon hit, and afterwards it'll be disposed of in another function that's already been made.
Simply have a Visible flag for a Bullet instance:
class Bullet {
public bool Visible { get; set; }
}
When it hits.. make it invisible:
// ... hit
bulletInstace.Visible = false;
Then check before drawing it:
if (bulletInstance.Visible)
drawBullet(bullet);
If it isn't visible, your drawing code should just skip over it.
When you draw an object using spriteBatch.Draw(...) you have to select a color for the sprite itself.
We all know that the color is a mixture of "red, green and blue" values (or rgb). What not many people know is that, at least in XNA, there is a fourth value called alpha.
The alpha value indicates the transparency of your object, meaning that if you use it like the code below, your object will be half invisible (or half visible).
spriteBatch.Draw(..., Color.White * 0,5f,...);
You can play with that :)
Check a little more here, on the old XNA forums.
You need rate of fire (rof) property that you increase to some maxRof value when you hold down button. and when rof is equal to maxrof then you add bullet to a list of bullets (and reset rof to 0).
Do not make it invisible, remove it from list. Every instance of bullet should have "Active" property set to true on fire. (when you fire a bullet, add it to list) And when collsition happened set this property to false. pseudo code as example:
UPDATE
for each bullet in bullets
-- update bullet position
-- check collision if happened if yes then set Active to false
end for
bullets.removeall(function(c) NOT(c.active));
DRAW
for each bullet in bullets.findall(function(c) c.active)
-- draw your bullets
end for