- Home /
 
Button over a in offset texture
I have a World Map texture, I put it in a plane and Im using the material offset to make the right - left movement. 
 I want to put a button right over a country and make this button follows the offset movement.
 
 How can I make the button follow a specific point in the planes material?
I kinda feel this is not the best approach, so I really appreciate any suggestion.
Answer by DCordoba · Feb 25, 2019 at 11:21 PM
like a pin on a blueprint eh? interesting way
ofcourse is more (at least for me) easy have a fixed offset, and move the plane relative to the camera put the "pin" as child of the plane and voila!, but seem to be a nice challenge, lets see if we can do it.
I finally had the time to do and test that, sorry the delay
I created a script that attached to a 3d object change the position relative to the offset to the plane behind it.

I also consider texture tiling, so the relative position keeps there even if the tiling isnt 1:1
so, on the creation of the button we need to get te original offset up to the plane, and its relative position to the center of the plane, also I dont know the orientation of the plane reltive to the world axis, so, I had to calculate it using the ughly switch that you see
if the button is a UIButton on screen space, leave the "pin" who have attached this script as empty gameobject(invisible), and use WorldToScreenPoint to set the UIButton at the same pos
 public enum RelativeAxis{X, Y, Z}
 
 public class MappingButton : MonoBehaviour {
     public GameObject plane;//the plane
 
     MeshRenderer mapRenderer;
     Vector2 startingOffset = Vector2.zero;//the offset when create it
     Vector2 mapSize = Vector2.one; //the size of the plane in world space units
     Vector2 textTiling;
     Vector2 LastOffset = Vector2.zero;
 
     public Vector3 StartingPos = Vector3.zero;
 
     public RelativeAxis FromXAxis = RelativeAxis.X;
     public RelativeAxis FromYAxis = RelativeAxis.Y;
 
     void Start(){
         //get the pos of the button to the map
         Vector3 worldPoint = transform.position;
         mapRenderer = plane.transform.GetComponent<MeshRenderer>();
         Vector3 mapcube = mapRenderer.bounds.size;
         //I dont know what are the 0 axis of your plane so I will check it manually
         if(mapcube.x < Mathf.Min(mapcube.y,mapcube.z)){
             FromXAxis = RelativeAxis.Y;
             FromYAxis = RelativeAxis.Z;
         }else if(mapcube.y < Mathf.Min(mapcube.x,mapcube.z))
         {
             FromXAxis = RelativeAxis.X;
             FromYAxis = RelativeAxis.Z;
         }
         else if (mapcube.z < Mathf.Min(mapcube.x,mapcube.y))
         {
             FromXAxis = RelativeAxis.X;
             FromYAxis = RelativeAxis.Y;
         }
         //get the relative pos of the point by the plane bounds
         GetPlaneSize();
         startingOffset = mapRenderer.material.mainTextureOffset;
         StartingPos = transform.position;
         textTiling = mapRenderer.material.mainTextureScale;
     }
 
     void Update(){
         //if to just updates on change
         if(0.001f<(LastOffset - mapRenderer.material.mainTextureOffset).sqrMagnitude)
             transform.position = SetPlanePos (mapRenderer.materials[0].mainTextureOffset);
     }
 
 
     void GetPlaneSize(){
         Vector3 mapcube = mapRenderer.bounds.size;
 
         switch (FromXAxis) {
         case RelativeAxis.X:
             mapSize.x = mapcube.x;
             break;
         case RelativeAxis.Y:
             mapSize.x = mapcube.y;
             break;
         default:
             mapSize.x = mapcube.z;
             break;
         }
 
         switch (FromYAxis) {
         case RelativeAxis.X:
             mapSize.y = mapcube.x;
             break;
         case RelativeAxis.Y:
             mapSize.y = mapcube.y;
             break;
         default:
             mapSize.y = mapcube.z;
             break;
         }
     }
 
 
     Vector3 SetPlanePos(Vector2 CurrentOffset){
         Vector3 ret = Vector3.zero;
         Vector2 RealOffset = startingOffset - CurrentOffset;
         ret = StartingPos;
         switch (FromXAxis) {
         case RelativeAxis.X:
             ret.x -= RealOffset.x*mapSize.x/textTiling.x;
             break;
         case RelativeAxis.Y:
             ret.y -= RealOffset.x*mapSize.x/textTiling.x;
             break;
         default:
             ret.z -= RealOffset.x*mapSize.x/textTiling.x;
             break;
         }
         switch (FromYAxis) {
         case RelativeAxis.X:
             ret.x = RealOffset.y*mapSize.y/textTiling.y;
             break;
         case RelativeAxis.Y:
             ret.y = RealOffset.y*mapSize.y/textTiling.y;
             break;
         default:
             ret.z = RealOffset.y*mapSize.y/textTiling.y;
             break;
         }
         return ret;
     }
 }
 
              I just realize to this can be used too, to attach fixed (external) objects to a dynamic (guided by texture) terrain, maybe with a few modifications can be used for that xd
Omg Ive been trying this for hours, thank you so much!
Your answer