Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by Czar-Man · Jun 24, 2016 at 06:15 PM · cameratransparencythird-personocclusion culling

How Do I Occlude Objects Between the Player and a 3rd-Person Camera?

I've been trying to figure this out for days, trying out various techniques to no success. Note that I am not using a Third Person Character Controller because my object uses ball movement.

Here's what I currently have for my Third Person Camera. This creates a ray that always points directly at the player. It gets an array of all objects it points at. If these are not player, and they have an OccludeWhenPointed script, it calls the TogglePointed function :

  float m_dist;
     void Start ()
     {
         //Create a ray at the object's position and rotation
         m_dist = GetComponent<ThirdPersonCamera>().GetDistance();
     }
     
     // Update is called once per frame
     void Update ()
     {
         int x = Screen.width / 2;
         int y = Screen.height / 2;
 
         Ray ray = Camera.main.ScreenPointToRay(new Vector3(x, y, 0));
         RaycastHit hit;
         RaycastHit[] allHits = Physics.RaycastAll(ray, m_dist);
         foreach (var rayHit in allHits)
         {
             if (rayHit.collider.gameObject.CompareTag("Player"))
             {
 
             }
             else if (!rayHit.collider.gameObject.layer.Equals("EditorCameraIgnore") && !rayHit.collider.gameObject.CompareTag("Ground"))
             {
                 //Call HitByRay function
                 if(rayHit.collider.gameObject.GetComponent<OccludeWhenPointed>() != null)
                 {
                     //print("Ready to point");
                     rayHit.collider.gameObject.GetComponent<OccludeWhenPointed>().TogglePointed();
                 }
                 //Material e_mat = rayHit.collider.gameObject.GetComponent<MeshRenderer>().material;
             }
         }
  
 Here's the pseudocode I've been trying to follow:
         //keep the ray in the camera's position and rotation
         //if the ray is colliding with something other than the player ball, 
         //If there is no transparency material of the object
         //Add a transparency material to it
         //Else
         //Set object's alpha to a lower number
         //if the ray is not colliding with it
         //Set object's alpha to full
     }
 }


Meanwhile, each object that I want to be transparent has both a material in Transparent rendering mode and this script. When it's pointed at, it reduces its alpha to 0.5: using UnityEngine; using System.Collections;

 public class OccludeWhenPointed : MonoBehaviour {
     [SerializeField]
     bool m_PointedAtByRay = false;
     bool m_Switched = false;
     float m_OcclusionTime = 1.0f;
     float m_Timer;
     Color newColor;
     Material mat;
     void Start()
     {
         mat = GetComponent<MeshRenderer>().material;
         m_Timer = m_OcclusionTime;
     }
 
     public void TogglePointed()
     {
         if (m_PointedAtByRay == false)
             m_PointedAtByRay = true;
         else
             m_PointedAtByRay = false;
 
         m_Switched = false;
     }
 
     // Update is called once per frame
     void Update ()
     {        
         if(m_PointedAtByRay)
         {
             print("Pointing is " + m_PointedAtByRay);
             print("Switched is " + m_Switched);
             if (!m_Switched)
             {
                 print("Turning Transparent");
                 newColor.a = 0.5f;
                 mat.color = newColor;              
                 m_Switched = true;
             }
 
             if (m_Timer > 0)
             {
                 m_Timer -= Time.deltaTime;
             }
             else
             {
                 TogglePointed();
                 m_Timer = m_OcclusionTime;
             }
         }
         else
         {
             if (m_Switched)
             {
                 print("Un-Turning Transparent");
                 newColor.a = 1.0f;
                 mat.color = newColor;
                 m_Switched = false;
             }
         }        
     }
 }

The result I do get is that when my camera points at objects, they still look solid.

If anyone knows how to solve this problem, or more efficient alternatives that can be instructed step-by-step, your help would be greatly appreciated.

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by cjake2299 · Jul 11, 2018 at 08:28 PM

It's a few years late and you probably found a solution already, but your question helped me create a solution to my issue and I wanted to share my results with you and says thanks for asking the question:

In order for these 2 scripts to work you need a few things:

  1. A "Resources" folder with a material inside called "Transparent"

  2. The "Transparent" material should be standard > fade, with the color set to a low alpha level in the inspector windows color selector (like 5 or 10) and white.

  3. The objects with the material you want to occlude must have colliders, the OccludeWhenPointed script and it's material all on the same object

Here is the script to go on the main camera: using UnityEngine;

 public class CameraOcclude : MonoBehaviour
 {
     public Transform m_player = null; //inspector assigned variable
     public LayerMask mask = -1; //inspecotr assigned variable, defalut is "Everything"
     public float m_radiusOffset = 1.5f;
     float m_dist = 1.0f;
     float m_radius = 3.0f; //the radius of the sphere being cast
 
     /// <summary>
     /// Set the Layer Mask in the inspector window
     /// members of this layer mask will need to have a collider and the OccludeWhenPointed script
     /// otherwise they will not change
     /// 
     /// m_sphereCastTarget should be a sphere attached to the player, the size of the thickness
     /// and offset behind the player between the player and camera.
     /// 
     /// this is because the thickness of the sphere will extend beyon the player, causing objects infront of the
     /// player to become transparent.
     /// </summary>
     void Update()
     {
         m_dist = Vector3.Distance(m_player.position, transform.position); //Camera distance may change in the future
         m_dist -= (m_radius + m_radiusOffset); //reduce the distance of the SphereCast so objects infront of the player do not become transparent
         m_dist = Mathf.Max(0.1f, m_dist); //ensures that m_dist is never less than 0.1f
         Vector3 fwd = transform.TransformDirection(Vector3.forward);
         RaycastHit[] hits = Physics.SphereCastAll(transform.position, m_radius, fwd, m_dist, mask);
 
         for (int i = 0; i < hits.Length; i++)
         {
             RaycastHit hit = hits[i];
             OccludeWhenPointed occlude = hit.collider.gameObject.GetComponent<OccludeWhenPointed>();
             if (occlude != null) //make sure what we collided with has the script
             {
                 occlude.ChangeMatAlpha();
             }
         }
     }
 }


and then the OccludeWhenPointed script:

 using UnityEngine;
 
 public class OccludeWhenPointed : MonoBehaviour
 {
     public bool m_Switched = false; //incase we want to set this from an external function later
     private float m_OcclusionTime = 0.1f;
     private float _Timer;
     private Material m_StartMat, m_Transparent;
     public Renderer m_Renderer;
 
     void Start()
     {
         m_Renderer = GetComponent<Renderer>();
         m_StartMat = m_Renderer.material; //this is the game object original material
         m_Transparent = Resources.Load<Material>("Transparent");
         /*Transparent material must be located inside of the resources folder
          * ./Resources/Transparent.mat
          * or it cannot be loaded and used. Also, the transparent material should be "fade" and not "transparent"
          * or it will how an outline.
          * */
     }
 
     /// <summary>
     /// Camera will trigger
     /// Function will change alpha and set timer to "m_OcclusiongTime"
     /// This keeps the object transparent as long as the camera ray hits it
     /// Update function will handle transition back
     /// </summary>
     public void ChangeMatAlpha()
     {
         m_Switched = true;
         m_Renderer.material = m_Transparent;
         _Timer = m_OcclusionTime;
     }
 
     /// <summary>
     /// This function will return the object to it's original material once
     /// time has expired. It also sets the bool m_Switched back to false
     /// </summary>
     private void ReturnMat()
     {
         m_Switched = false;
         m_Renderer.material = m_StartMat;
     }
     // Update is called once per frame
     void Update()
     {
         if(m_Switched)
         {
             //now we check the timer
             if (_Timer > 0.0f)
                 _Timer = Mathf.Max(0.0f, _Timer - (1.0f * Time.deltaTime)); //1.0f * Time.deltaTime to get transition over 1 second
             else
             {
                 ReturnMat();
             }
         }
     }
 }



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

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

71 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 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 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 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

Camera rotate X degree based on player rotate 0 Answers

Camera Rotation Switching Problem 0 Answers

How do i make so the player rotates when the camera does? 2 Answers

Rotate Camera with player vehicle 0 Answers

Weird Camera glitch after occlusion baking 0 Answers


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