Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
9
Question by SrBilyon · Jan 27, 2011 at 05:48 AM · cameracollisionplayertransparencyview

Make object transparent when between camera and player

In certain games, there is a function involved where if there is an object between the camera's view and the player, the object will either become transparent, or the player's silhouette is visible on the object. Would I need some sort of custom diffuse shader, or is there a function that will allow me to change the visibility of an object.

Also, how would I do a raycast/vector check to determine if the object is between the player and camera.

Would I need Pro for the transparency part?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jan 27, 2011 at 08:22 AM 0
Share

Oh i forgot: you don't need Pro for enything like that ;) have fun

11 Replies

· Add your reply
  • Sort: 
avatar image
13
Best Answer

Answer by Bunny83 · Jan 27, 2011 at 08:21 AM

Just do it like Jean said. The Unity script reference on RaycastAll gives you an example for exact your case except it does not revert the transparency. A list would be a solution, but it gets tricky to determine what renderers have to be reverted, which ones should stay transparent and which ones have to set transparent.

I would write a little script that you can attach dynamically to those renderes which should be transparent. In that script you can implement some kind of falloff and when it'sno longer needed it removes itself.

C#:

Here's an example script that gets dynamically attached to the renderer and the script that do the raycast.

using UnityEngine; using System.Collections;

public class AutoTransparent : MonoBehaviour { private Shader m_OldShader = null; private Color m_OldColor = Color.black; private float m_Transparency = 0.3f; private const float m_TargetTransparancy = 0.3f; private const float m_FallOff = 0.1f; // returns to 100% in 0.1 sec

 public void BeTransparent()
 {
     // reset the transparency;
     m_Transparency = m_TargetTransparancy;
     if (m_OldShader == null)
     {
         // Save the current shader
         m_OldShader = renderer.material.shader;
         m_OldColor  = renderer.material.color;
         renderer.material.shader = Shader.Find("Transparent/Diffuse");
     }
 }
 void Update()
 {
     if (m_Transparency < 1.0f)
     {
         Color C = renderer.material.color;
         C.a = m_Transparency;
         renderer.material.color = C;
     }
     else
     {
         // Reset the shader
         renderer.material.shader = m_OldShader;
         renderer.material.color = m_OldColor;
         // And remove this script
         Destroy(this);
     }
     m_Transparency += ((1.0f-m_TargetTransparancy)*Time.deltaTime) / m_FallOff;
 }

}

//And here the script for the camera to cast the ray / capsule ;

using UnityEngine; using System.Collections;

public class ClearSight : MonoBehaviour { public float DistanceToPlayer = 5.0f; void Update() { RaycastHit[] hits; // you can also use CapsuleCastAll() // TODO: setup your layermask it improve performance and filter your hits. hits = Physics.RaycastAll(transform.position, transform.forward, DistanceToPlayer); foreach(RaycastHit hit in hits) { Renderer R = hit.collider.renderer; if (R == null) continue; // no renderer attached? go to next hit // TODO: maybe implement here a check for GOs that should not be affected like the player

         AutoTransparent AT = R.GetComponent<AutoTransparent>();
         if (AT == null) // if no script is attached, attach one
         {
             AT = R.gameObject.AddComponent<AutoTransparent>();
         }
         AT.BeTransparent(); // get called every frame to reset the falloff
     }
 }

}

The two script files need to be named like the class names (AutoTransparent and ClearSight).
To ignore your player select your player and change the layer on top of the inspector. Just set the layer to "IgnoreRaycast".


edit I guess your camera script is also on the camera like my ClearSight script.

JS:

var myDistanceZoomed : float;

GetComponent.<ClearSight>().DistanceToPlayer = myDistanceZoomed;

But don't forget: you need the distance in units. If you have the distance already, great, just pass it to my script ;)

Comment
Add comment · Show 19 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jan 27, 2011 at 08:25 AM 1
Share

initially i just want to write a small example script but i ended up with a full example :D. But: it's not testet yet. Syntax should be right (at least Visual C# Express can't find errors)

avatar image SrBilyon · Jan 27, 2011 at 07:35 PM 0
Share

Cool, thanks! I will try this when I get to my work desk!

avatar image SrBilyon · Jan 27, 2011 at 10:04 PM 0
Share

Okay, so I attached this script to the object I wanted to become transparent. When you run the game, the object's alpha gradually changes (without the camera even viewing the object) then the object's shader becomes null.

avatar image Bunny83 · Jan 28, 2011 at 04:09 AM 1
Share

That's funny, in our hack and slash game i also created a avoid-collision-camera by zoo$$anonymous$$g in. Now that i wrote that little script for you i will implement that on top because at some places where little object are in the way the camera zooms in and out all the time. I imagine such a function long ago, but there was no need for, until now ;)

avatar image Kevin__h · Dec 29, 2016 at 10:23 PM 2
Share

Just an update if anyone stumbles upon this and is using Unity 5 or higher, change every "renderer.material.shader" to "GetComponent().material.shader" because Unity apparently hates consistency throughout their different versions :')

Show more comments
avatar image
3

Answer by Ilya · Apr 03, 2011 at 08:17 PM

I've implemented the same script posted by Bunny83. Mine is in JavaScript and it changes the transparency gradually.

class AutoTransparent extends MonoBehaviour { private var m_OldShader : Shader = null; private var m_OldColor : Color; private var m_Transparency : float = 0.3;

 private var m_TargetTransparancy : float = 0.3;
 private var m_FallOff : float = 0.5; // returns to 100% in 0.5 sec

 private var shouldBeTransparent : boolean = true;

 function BeTransparent()
 {
     shouldBeTransparent = true;
 }

 function Start()
 {
     if (renderer.material)
     {   
         // Save the current shader
         m_OldShader = renderer.material.shader;
         renderer.material.shader = Shader.Find("Transparent/Diffuse");

         if (renderer.material.HasProperty("_Color") )
         {
             m_OldColor  = renderer.material.color;
             m_Transparency = m_OldColor.a;
         } else
         {
             m_OldColor = Color.white;
             m_Transparency = 1.0;
         }
     } else
     {
         m_Transparency = 1.0;
     }
 }

 function OnDestroy()
 {
     if (!m_OldShader) return;
     // Reset the shader
     renderer.material.shader = m_OldShader;
     renderer.material.color = m_OldColor;
 }

 function Update()
 {
     //Shoud AutoTransparent component be removed?
     if (!shouldBeTransparent &amp;&amp; m_Transparency &gt;= 1.0)
     {
         Destroy(this);
     }

     //Are we fading in our out?
     if (shouldBeTransparent)
     {
         //Fading out
         if (m_Transparency &gt; m_TargetTransparancy)
             m_Transparency -= ( (1.0 - m_TargetTransparancy) * Time.deltaTime) / m_FallOff;
     } else
     {
         //Fading in
         m_Transparency += ( (1.0 - m_TargetTransparancy) * Time.deltaTime) / m_FallOff;
     }

     renderer.material.color.a = m_Transparency;

     //The object will start to become visible again if BeTransparent() is not called
     shouldBeTransparent = false;
 }

}

Here's how you can use it:

var currentRenderer = hit.transform.gameObject.renderer;

//Make transparent if (currentRenderer) { var autoTransparent : AutoTransparent = currentRenderer.GetComponent("AutoTransparent");

 if (autoTransparent == null)
 {
     currentRenderer.gameObject.AddComponent(AutoTransparent);   
 }

 currentRenderer.SendMessage("BeTransparent");                       

}

Hope somebody finds this useful.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cymrix · Jul 23, 2011 at 02:49 AM 0
Share

Thank you. This script worked perfect right out of the box. It's exactly what I was looking for. I really look forward to deconstructing your code.

I use this code to call the transparent class and it seems perfect for what i'm needing.

var hit : RaycastHit;

if (Physics.Linecast(target.position, transform.position, hit)) { var currentRenderer = hit.transform.gameObject.renderer;

//$$anonymous$$ake transparent if (currentRenderer) { var autoTransparent : AutoTransparent = currentRenderer.GetComponent("AutoTransparent");

 if (autoTransparent == null) {
 currentRenderer.gameObject.AddComponent(AutoTransparent);   
 }

 currentRenderer.Send$$anonymous$$essage("BeTransparent"); 
 }

}

avatar image 686InSomNia686 · Mar 17, 2016 at 03:33 PM 0
Share

Your code works perfectly, it's exactly what I needed, thanks :)

avatar image
3

Answer by Antigen_Z · May 23, 2015 at 03:08 PM

Bunny83 script updated for multiple materials (uses Transparent material of your choice. Good for Unity5)

 public class ClearSight : MonoBehaviour {

     public float DistanceToPlayer = 5.0f;
     public Material TransparentMaterial = null;
     public float FadeInTimeout = 0.6f;
     public float FadeOutTimeout = 0.2f;
     public float TargetTransparency = 0.3f;

     private void Update() {
         RaycastHit[] hits; // you can also use CapsuleCastAll() 

         // TODO: setup your layermask it improve performance and filter your hits. 

         hits = Physics.RaycastAll(transform.position, transform.forward, DistanceToPlayer);
         foreach (RaycastHit hit in hits) {
             Renderer R = hit.collider.GetComponent<Renderer>();
             if (R == null) {
                 continue;
             }
             // no renderer attached? go to next hit 

             // TODO: maybe implement here a check for GOs that should not be affected like the player

             AutoTransparent AT = R.GetComponent<AutoTransparent>();

             if (AT == null) // if no script is attached, attach one
             {
                 AT = R.gameObject.AddComponent<AutoTransparent>();

                 AT.TransparentMaterial = TransparentMaterial;
                 AT.FadeInTimeout = FadeInTimeout;
                 AT.FadeOutTimeout = FadeOutTimeout;
                 AT.TargetTransparency = TargetTransparency;
             }

             AT.BeTransparent(); // get called every frame to reset the falloff
         }
     }
 }


And AutoTransparent class with fade in/out:

 public class AutoTransparent : MonoBehaviour {
 
         private Material[] oldMaterials = null;
 
         private float m_Transparency = 1.0f;
         public float TargetTransparency { get; set; }
 
         public float FadeInTimeout { get; set; }
 
         public float FadeOutTimeout { get; set; }
 
         public Material TransparentMaterial { get; set; }
 
         private bool shouldBeTransparent = true;
 
         public void BeTransparent() {
             shouldBeTransparent = true;
         }
 
         private void Start() {
             // reset the transparency;
             m_Transparency = 1.0f;
 
             if (oldMaterials == null) {
                 // Save the current materials
                 oldMaterials = GetComponent<Renderer>().materials;
 
                 Material[] materialsList = new Material[oldMaterials.Length];
 
                 for (int i = 0; i < materialsList.Length; i++) {
                     // repalce material with transparent
                     materialsList[i] = Object.Instantiate(TransparentMaterial);
                     materialsList[i].SetColor("_Color", oldMaterials[i].GetColor("_Color"));
                 }
 
                 // make transparent
                 GetComponent<Renderer>().materials = materialsList;
             }
         }
 
         // Update is called once per frame
         private void Update() {
             if (!shouldBeTransparent && m_Transparency >= 1.0) {
                 Destroy(this);
             }
 
             //Are we fading in our out?
             if (shouldBeTransparent) {
                 //Fading out
                 if (m_Transparency > TargetTransparency) {
                     m_Transparency -= ((1.0f - TargetTransparency)*Time.deltaTime)/FadeOutTimeout;
                 }
             }
             else {
                 //Fading in
                 m_Transparency += ((1.0f - TargetTransparency)*Time.deltaTime)/FadeInTimeout;
             }
 
             Material[] materialsList = GetComponent<Renderer>().materials;
             for (int i = 0; i < materialsList.Length; i++) {
                 Color C = oldMaterials[i].GetColor("_Color");
 
                 C.a = m_Transparency;
                 materialsList[i].color = C;
             }
 
             //The object will start to become visible again if BeTransparent() is not called
             shouldBeTransparent = false;
         }
 
         private void OnDestroy() {
             // restore old materials
             GetComponent<Renderer>().materials = oldMaterials;
         }    
     }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
2

Answer by Jean-Fabre · Jan 27, 2011 at 06:14 AM

Hi SirVictory,

Raycasting would be a start, that is, you raycast from the player position and whatever is hit before the player should be send a message or dealt in some way to become semi transparent. you would need to maintain a list so that you can toggle semi transparent models back when not anymore in front of the player,

Else, you could actually have a box collider starting from the player and pointing at the camera where its size emcopass the player bounds, then anything that collides to that are also in the way.

Otherwise, Physics.CapsuleCast could be also an alternative to building a collider, but very similar in principle, tho the start point would need to be sligtly tweacked and not start right where the player is but slightly closer to the camera to not hit the ground or things to close to the player.

As for the shader, I would replace it with a specific simple one while in front, you might want to have front and backface material for object very close to the camera.

Hope it helps,

Jean

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by Nomibuilder · Apr 18, 2015 at 12:35 PM

Try this One. M Sure it will help.

 void Update() {
         if (Input.GetKeyDown("f")) {
             StartCoroutine("Fade");
         }
     }
 
 IEnumerator Fade() {
     for (float f = 1f; f >= 0; f -= 0.1f) {
         Color c = renderer.material.color;
         c.a = f;
         renderer.material.color = c;
         yield return null;
     }
 }

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Sorenzo · Apr 18, 2015 at 12:37 PM 1
Share

thanks it helped :)

avatar image Nomibuilder · Apr 18, 2015 at 12:39 PM 1
Share

You are welcome

avatar image rginn · Jan 26, 2019 at 08:34 PM 0
Share

Does it make sense to use an animation triggered by a hit?

  • 1
  • 2
  • 3
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

19 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Bounds of players on screen 2 Answers

3rd person camera script 2 Answers

Camera Transparency 1 Answer

Realistic Water effects 1 Answer

Phone doesn't show what my unity camera is showing. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges