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.

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

I was actually able to figure this out last night shortly after posting this :slight_smile: 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!