Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by Steve Edwards · Jan 22, 2011 at 09:41 PM · materialchange

Changing and resetting materials dynamically?

Hi

I want to apply a given material to any object being directly looked at, and then have it reset back to it's original material when it is no longer being directly looked at.

I can handle the change to new material OK by doing a Physics.Raycast forward from the player camera, and setting rayHit.transform.renderer.material.

The problem is in reverting back to the original material. I have hundreds of game objects using any one of 10 materials. Obviously I want to avoid having to keep arrays of these objects to check they're no longer being looked at.

Is there a way to somehow know what just the penultimate object looked at was, so I only have to revert that single object's material?

Thanks

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

3 Replies

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

Answer by Jessy · Jan 22, 2011 at 11:30 PM

using UnityEngine;

public class MaterialEyes : MonoBehaviour {

[SerializeField] Material material;

[HideInInspector] [SerializeField] new Camera camera; [HideInInspector] [SerializeField] Vector3 screenCenter;

void Reset () { camera = GetComponent<Camera>(); screenCenter = new Vector3(.5F, .5F, 0); }

class ChangedObject { public Renderer renderer; public Material originalMaterial;

 public ChangedObject (Renderer renderer, Material material) {
     this.renderer = renderer;
     originalMaterial = renderer.sharedMaterial;
     renderer.material = material;
 }

}

ChangedObject changedObject; RaycastHit raycastHit; void Update () { Ray ray = camera.ViewportPointToRay(screenCenter); if (Physics.Raycast(ray, out raycastHit)) { Renderer hitRenderer = raycastHit.transform.renderer; if (hitRenderer) { if (changedObject != null) if (changedObject.renderer == hitRenderer) return; else changedObject.renderer.material = changedObject.originalMaterial; changedObject = new ChangedObject(hitRenderer, material); } } else if (changedObject != null) { changedObject.renderer.material = changedObject.originalMaterial; changedObject = 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 Steve Edwards · Jan 23, 2011 at 12:01 AM 0
Share

$$anonymous$$any thanks for this example Jessy, I was tying myself in knots with this :)

avatar image manutoo · Jun 26, 2014 at 08:00 AM 0
Share

I think you need to do this before line #40 to avoid a memory leak : Destroy(changedObject.renderer.material); as the instanced $$anonymous$$aterial is yours to free.

avatar image perza · Oct 11, 2019 at 06:38 AM 0
Share

Brilliant!

A little update for later Unity versions:

 Renderer hitRenderer = raycastHit.transform.GetComponentInChildren<Renderer>();
avatar image
1

Answer by Jason B · Jan 22, 2011 at 10:50 PM

Before you change the material, have a GameObject variable and Material variable set up to "capture" the material and game object you hit with a ray before you do anything else to it. Then when you leave it, you can tell the game object to revert back to the stored material value.

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 Jessy · Jan 22, 2011 at 11:32 PM 0
Share

Right, but you only need to store the Renderer, not the whole Game Object. $$anonymous$$y code example does this.

avatar image Steve Edwards · Jan 22, 2011 at 11:56 PM 0
Share

Thanks :)

avatar image
0

Answer by Steve Edwards · Jan 23, 2011 at 09:39 AM

This is Jessy's C# code changed to Javascript. (No advantage, I just needed to integrate it within an existing .js)

To recap, attach this script to a camera and it will temporarily change the material of the object you're looking at (in the centre of screen) to the one you assign to newMaterial

(Thanks again Jessy, as a C# newbie I learned a lot from studying your code)

var newMaterial : Material; private var screenCenter : Vector3; private var raycastHit : RaycastHit; private var theRenderer : Renderer; private var originalMaterial : Material;

function Start () { screenCenter = Vector3(.5F, .5F, 0); } function Update () { var ray : Ray = camera.ViewportPointToRay(screenCenter); // creates a ray going from camera to viewport center if (Physics.Raycast(ray, raycastHit)) { // get what that ray hits var hitRenderer : Renderer = raycastHit.transform.renderer; //get the renderer of the hit object if (hitRenderer) { if (theRenderer != null){ //if we've already assigned a renderer if (theRenderer == hitRenderer) return; //if this the same renderer do nothing else theRenderer.material = originalMaterial; // if it's a different one, put the original material back } theRenderer = hitRenderer; originalMaterial = hitRenderer.sharedMaterial; hitRenderer.material = newMaterial; } } else if (theRenderer != null) { // if we didn't hit anything and there exists a changed renderer, put the original material back theRenderer.material = originalMaterial; theRenderer = null; }
}

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

1 Person is following this question.

avatar image

Related Questions

Help Changing Materials On Button Click 0 Answers

How to change the material in the game, depending on an event? 1 Answer

Errors while assigning material to other object's by scripting. 1 Answer

change materials onmousedrag 2 Answers

change skybox via script help ? 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