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 sk00ter · Feb 07, 2015 at 09:57 AM · raycasttransformpositionhighlightlast

Getting transform position of last parent

So I'm writing a "highlight" code for when a user holds their mouse button down and moves over a tile of prefab cubes it renders a new "highlight texture" onto the cube at the mouses position.

I'm using raycasting from screen on mousebuttondown to create this effect but I have a problem: The texture change is permanent. After the mouse position leaves the last prefab cube, it needs to render the texture back to the original, unhighlighted texture. I'm unsure of how to accomplish this.

I'm on break at work right now, I'll add some code examples when I get home.

CODE:

 using UnityEngine;
 using System.Collections;
 
 public class createCube : MonoBehaviour {
 
     public float timeBetweenBlock = 0.15f;
     public GameObject prefab;
     public Texture highlightTexture;
     public Texture normalTexture;
     public int roomSize;
 
     GameObject[] prefabArray;
     
     float timer;
 
     Vector3 lastMouseCoordinate = Vector3.zero;
 
     Ray ray;
     Ray rayLast;
     RaycastHit hit;
     RaycastHit hitLast;
 
     Vector3 mouseDelta;
 
     // Use this for initialization
     void Start () {
         prefabArray = new GameObject[roomSize*2];
         for (int i = (-1*roomSize); i < roomSize; i++) {
             for (int j = (-1*roomSize); j < roomSize; j++) {
                 GameObject tileMap = Instantiate(prefab, new Vector3(i, 0, j), Quaternion.identity) as GameObject;
             }
         }
     }
     
     // Update is called once per frame
     void Update () {
         timer += Time.deltaTime;
 
         //If clicked on prefab
         if (Input.GetMouseButtonDown(0)){
             ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if(Physics.Raycast(ray, out hit, 100f)){
                 lastMouseCoordinate = hit.collider.transform.position;
             }
         }
 
 
         if (Input.GetMouseButton (0)) {
             ray = Camera.main.ScreenPointToRay(Input.mousePosition);
             if(Physics.Raycast(ray, out hit, 100f)){
                 Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.red);
                 mouseDelta = hit.collider.transform.position - lastMouseCoordinate;
                 float xmag = Mathf.Abs(mouseDelta.x);
                 float ymag = Mathf.Abs(mouseDelta.y);
                 float zmag = Mathf.Abs(mouseDelta.z);
 
                 hit.collider.renderer.material.SetTexture("_MainTex", highlightTexture);
 
                 if (mouseDelta.x > 0) {
                     Debug.Log("Up right");
                     if(Physics.Raycast(lastMouseCoordinate+Vector3.up, Vector3.down, out hitLast)){
                         Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                         hitLast.collider.renderer.material.SetTexture("_MainTex", normalTexture);
                         Debug.Log(normalTexture);
                     }
                 }
                 else if(mouseDelta.x < 0) {
                     Debug.Log("Down left");
                     if(Physics.Raycast(lastMouseCoordinate+Vector3.up, Vector3.down, out hitLast)){
                         Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                         hitLast.collider.renderer.material.SetTexture("_MainTex", normalTexture);
                     }
                 }
 
                 if (mouseDelta.z > 0) {
                     Debug.Log("Up Left");
                     if(Physics.Raycast(lastMouseCoordinate+Vector3.up, Vector3.down, out hitLast)){
                         Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                         hitLast.collider.renderer.material.SetTexture("_MainTex", normalTexture);
                     }
                 }
                 else if(mouseDelta.z < 0) {
                     Debug.Log("Down Right");
                     if(Physics.Raycast(lastMouseCoordinate+Vector3.up, Vector3.down, out hitLast)){
                         Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                         hitLast.collider.renderer.material.SetTexture("_MainTex", normalTexture);
                     }
                 }
                 lastMouseCoordinate = hit.collider.transform.position;
             }
         }
 
         if (Input.GetMouseButtonUp(0)) {
             if(timer >= timeBetweenBlock && Time.timeScale != 0){
                 spawnBlock ();
             };
 
             if (mouseDelta == Vector3.zero) {
                 Debug.Log("Didn't move");
                 if(Physics.Raycast(hit.collider.transform.position+Vector3.up, Vector3.down, out hitLast)){
                     Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                     hitLast.collider.renderer.material.SetTexture("_MainTex", normalTexture);
                 }
             }
         }
     }


What my code is doing right now is getting the direction the last prefab block was by getting its transform position and comparing it to the new position of the mouse. Through this I get a "Mouse moved to Top Right/Top Left/Bottom Right/Bottom Left from original position" function.

By that logic I'm just setting a new raycast from transform that is one transform Y value block above the last highlighted texture position and setting the texture back to the original on raycast hit.

It kind of works, but I think there's a better way to do it. For example, if the highlighted texture is on the "side" of a cube, the texture wont reset because the 2nd raycast can't hit that face from the above position. In other words, it only resets the highlight position on the top face of a prefab block because the reset texture raycast origin is ABOVE the block affected.

I could program this to recognize that the mouse is indeed over a side face of a block, but I'll have to do it for each blockface which turns out into really cluttered and redundant code.

There's got to be a better way.

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

2 Replies

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

Answer by giulio-pierucci · Feb 07, 2015 at 11:10 AM

Save original texture on a private field before change it. On mouse out, restore it from private field.

Comment
Add comment · Show 4 · 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 sk00ter · Feb 09, 2015 at 07:13 PM 0
Share

Exactly. The part I'm struggling with is creating the "On mouse out" code. I've added my code to my original post above. Right now my textures are public variables I pass in (I only have 2 textures currently a normal and a highlight) and after I fix the on mouse out code, I'll make them dynamic.

avatar image giulio-pierucci · Feb 09, 2015 at 08:43 PM 0
Share

Indeed, it appears that the code is redundant and repetitive. It seems to me that the lines:

 if(Physics.Raycast(last$$anonymous$$ouseCoordinate+Vector3.up, Vector3.down, out hitLast)){
                          Debug.DrawRay(rayLast.origin, rayLast.direction * hitLast.distance, Color.cyan);
                          hitLast.collider.renderer.material.SetTexture("_$$anonymous$$ainTex", normalTexture);
                      }

are the same in all "if" blocks.

What I can not understand is the reason for all that code.

If you just want to change the texture of a cube when the mouse passes over just a simple script, which implements these two methods:

http://docs.unity3d.com/ScriptReference/$$anonymous$$onoBehaviour.On$$anonymous$$ouseEnter.html http://docs.unity3d.com/ScriptReference/$$anonymous$$onoBehaviour.On$$anonymous$$ouseExit.html

Obviously, the script must be attached to the cube.

If you want to use the raycast, however, you can use:

 private gameobject last = null;
 
 [....]
 
 //If clicked on prefab
 if (Input.Get$$anonymous$$ouseButtonDown(0))
 {
      if(Physics.Raycast(ray, out hit, 100f))
      {
           last = hit.collider.gamoibject;
           hit.gameobject.renderer.material.texture = highlightTexture;
      }
      else
      {
           if(last!=null) last.renderer.material.texture = normalTexture;
           last = null;
      }
 
 }

If you think that i don't understand the problem, can you post a package?

avatar image sk00ter · Feb 10, 2015 at 02:38 AM 0
Share

Wonderful! Your first suggestion, On$$anonymous$$ouseOver, worked beautifully, thank you. It took a little re-working. I had to add very thin block colliders to the block faces (for some reason On$$anonymous$$ouseOver doesnt like meshcolliders, they need a thickness). After that it worked just fine :).

Do you have any suggestions on how to use an overlay texture? So I don't have to create a highlight texture for each block texture. Like a transparent overlay, that would work.

Any ideas?

avatar image giulio-pierucci · Feb 10, 2015 at 03:20 PM 1
Share

Yes, you can try with DECAL Shader

http://docs.unity3d.com/$$anonymous$$anual/shader-NormalDecal.html

avatar image
0

Answer by sk00ter · Feb 10, 2015 at 08:31 PM

I was actually able to figure this out last night shortly after posting this :) I ended up creating a shader that used two textures; an opaque "_MainTex" and an alpha "_BlendTex" with a blending float called "_Blend" with a range of 0 to 1, 1 being full blend. Now my OnMouseEnter/OnMouseOut sets that float instead of setting a new texture. Works beautifully!

Thank you for your help!

Comment
Add comment · Show 1 · 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 giulio-pierucci · Feb 10, 2015 at 08:45 PM 0
Share

You are welcome! :)

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

JS Dynamic Height Camera vibrating =( 1 Answer

Negative Positions Breaks Raycasts 1 Answer

NullReferenceException when using raycast 1 Answer

Trouble with raycasting 1 Answer

Help with moving instantiated object's transform 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