In my game I have an area of water (The water is a plane), It looks realistic, but when I go under that plane and look up, you can’t see it. How do I make it so that not only can it be seen from the below, but also so that everything under that plane has a bluish tint? I am a beginner so sorry if this sounds basic or if it’s not even possible. (I’ve only had Unity for 6 days)
4 Answers
4The simplest solution in your case would be to double face the water plane, so that it would be rendered even from behind: attach the script from this answer to the water plane, and it will become double faced at Start.
The second part is the underwater effect. A very reasonable (and widely used) underwater effect is to turn a bluish fog on when the camera goes below the water plane. This can be done with a script like the one below attached to the player (for First Person games):
var underwaterDens: float = 0.15;
var underwaterColor: Color = Color(0.1, 0.3, 0.4, 1.0);
private var oldFog: boolean;
private var oldDens: float;
private var oldColor: Color;
private var oldMode: FogMode;
private var curWater: Transform;
private var underwater = false;
function OnTriggerEnter(other: Collider){
if (other.tag=="Water"){ // if entering a waterplane
if (transform.position.y > other.transform.position.y){
// set reference to the current waterplane
curWater = other.transform;
}
}
}
function OnTriggerExit(other: Collider){
if (other.transform==curWater){ // if exiting the waterplane...
if (transform.position.y > curWater.position.y){
// null the current waterplane reference
curWater = null;
}
}
}
function Update(){
// if it's underwater...
if (curWater && Camera.main.transform.position.y < curWater.position.y){
if (!underwater){ // turn on underwater effect only once
oldFog = RenderSettings.fog;
oldMode = RenderSettings.fogMode;
oldDens = RenderSettings.fogDensity;
oldColor = RenderSettings.fogColor;
RenderSettings.fog = true;
RenderSettings.fogMode = FogMode.Exponential;
RenderSettings.fogDensity = underwaterDens;
RenderSettings.fogColor = underwaterColor;
underwater = true;
}
}
else // but if it's not underwater...
if (underwater){ // turn off underwater effect, if any
RenderSettings.fog = oldFog;
RenderSettings.fogMode = oldMode;
RenderSettings.fogDensity = oldDens;
RenderSettings.fogColor = oldColor;
underwater = false;
}
}
Remember to tag the water plane as “Water”, or nothing will happen.
Underwater tutorial: Kostiantyn Dvornik :: Ideas: Unity world's coolest tutorial about water, girls and sky with FREE assets
Look here:
http://forum.unity3d.com/threads/20222-Water-plane-and-flip-texture
This goes into the details and has a sample script and video.
tldr; Make two water planes and flip one upside down…
I had to make some changes to make it work, I do not know why but the standard code posted which used a variable of type transform you blocking at the point “curWater = other.transform;”. Instead of following the correct code to those who need it. Excellent solution in any case! ![]()
var underwaterDens: float = 0.15;
var underwaterColor: Color = Color(0.1, 0.3, 0.4, 1.0);
private var oldFog: boolean;
private var oldDens: float;
private var oldColor: Color;
private var oldMode: FogMode;
private var curWater: GameObject; //CHANGED (Previous: Transform)
private var underwater = false;
function OnTriggerEnter(other: Collider){
if (other.tag=="Water"){ // if entering a waterplane
if (transform.position.y > other.transform.position.y){
// set reference to the current waterplane
curWater = other.gameObject; //CHANGED
}
}
}
function OnTriggerExit(other: Collider){
if (other.gameObject==curWater){ // if exiting the waterplane...
// CHANGED
if (transform.position.y + 0.6 > curWater.transform.position.y) {
// null the current waterplane reference
curWater = null;
}
}
}
function Update(){
// if it's underwater...
//CHANGED
if (curWater && Camera.main.transform.position.y < curWater.transform.position.y + 0.2){
if (!underwater){ // turn on underwater effect only once
oldFog = RenderSettings.fog;
oldMode = RenderSettings.fogMode;
oldDens = RenderSettings.fogDensity;
oldColor = RenderSettings.fogColor;
RenderSettings.fog = true;
RenderSettings.fogMode = FogMode.Exponential;
RenderSettings.fogDensity = underwaterDens;
RenderSettings.fogColor = underwaterColor;
underwater = true;
}
}
else // but if it's not underwater...
if (underwater){ // turn off underwater effect, if any
RenderSettings.fog = oldFog;
RenderSettings.fogMode = oldMode;
RenderSettings.fogDensity = oldDens;
RenderSettings.fogColor = oldColor;
underwater = false;
}
}
While for those who want the c # version:
public float underwaterDens = 0.15F;
public Color underwaterColor = new Color(0.1F, 0.3F, 0.4F, 1.0F);
private bool oldFog;
private float oldDens;
private Color oldColor;
private FogMode oldMode;
private GameObject curWater;
private bool underwater = false;
void OnTriggerEnter(Collider other){
if (other.tag=="Water"){ // if entering a waterplane
if (transform.position.y < other.transform.position.y){
// set reference to the current waterplane
curWater = other.gameObject;
}
}
}
void OnTriggerExit(Collider other){
if (other.gameObject==curWater){ // if exiting the waterplane...
if (transform.position.y + 0.6F > curWater.transform.position.y){
// null the current waterplane reference
curWater = null;
}
}
}
void Update(){
// if it's underwater...
if (curWater && Camera.main.transform.position.y < curWater.transform.position.y + 0.2F){
if (!underwater){ // turn on underwater effect only once
oldFog = RenderSettings.fog;
oldMode = RenderSettings.fogMode;
oldDens = RenderSettings.fogDensity;
oldColor = RenderSettings.fogColor;
RenderSettings.fog = true;
RenderSettings.fogMode = FogMode.Exponential;
RenderSettings.fogDensity = underwaterDens;
RenderSettings.fogColor = underwaterColor;
underwater = true;
}
} else // but if it's not underwater...
if (underwater){ // turn off underwater effect, if any
RenderSettings.fog = oldFog;
RenderSettings.fogMode = oldMode;
RenderSettings.fogDensity = oldDens;
RenderSettings.fogColor = oldColor;
underwater = false;
}
}
I'm not sure why you needed to make any changes... I've not tried or tested this, but, when coding... var myTransform : Transform; myTransform = other.transform; myTransform.position = Vector3.zero; ... should be the same as: var myGameObject : GameObject; myGameObject = other.gameObject; myGameObject.transform = Vector3.zero; ... but practically, it's easier to use the first example where everything is a Transform, rather than a GameObject, as it doesn't require then looking up the GameObject's Transform with each operation.
– Adam-BucknerYes, sure! But on my version (4.6.1f1 free) transform solution not work. I also extended slightly limits (0.2, 0.6) in order to avoid some problems in graphics output phase from the surface.
– FaberViNow I only noticed the downvote ... sure before doing so you could at least try. Certainly I do not find useful to publish stuff changed if it does not solve a real problem. :/ I also converted the code in c#, that as it was "easy" to do it, some people can definitely make use of it without having to do it by hand.
– FaberViThe main reason for the down-vote is the inefficiency of looking up a GameObject's Transform with every action, which is inefficient and definitely not recommended. I appreciate the effort put into the suggested answer, but didn't want to promote a non-recommended solution. The best solution would be getting the cached transform to work. When I'm back from holiday, I'll see if I can find the error with the accepted solution.
– Adam-Buckner
and you could place a particle emitter in front of the camera to create a few bubbles to make it look a little better
– tommy1235Thank You! I'll give it a try.
– MackswelI tried it but it didn't work. Want do think I did wrong? I took the script and attached it to the camera. When I walked through the water nothing happened.
– MackswelI tried it but it didn't work. Want do think I did wrong? I took the script and attached it to the camera. When I walked through the water nothing happened.
– MackswelRead the answer very carefully : This can be done with a script like the one below attached to the player
– AlucardJay