Fake Stretching or Extruding an Object (Scale and Move)

I’m using the following code to fake a mesh extruding keeping one of its sides still and stretching on the other, it works fine when the object the script is on has not been rotated, but as soon as rotations get involved it goes squiffy.

I think I have to multiply the scaling by the rotation but I’m down to guessing at how to do that, any help would be greatly appreciated!

void Update () {   
        if (Input.GetMouseButtonDown(0)){
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            if (Physics.Raycast (ray, out hit, 2000.0f)){
                if ( hit.collider.transform == this.transform){
                    Trigger();
                }     
            }
        }
    }
   
    public void Trigger(){
        Vector3 initialPosition = this.transform.localPosition;
        Vector3 initialScale = this.transform.localScale;
       
        Vector3[] directionArray = new Vector3[]{Vector3.right,Vector3.up,Vector3.forward, Vector3.left, Vector3.down, Vector3.back};       
        Vector3 direction = directionArray[Random.Range(0,directionArray.Length)];
        float distance = Random.Range(-2f, 2f);

        Vector3 pos = initialPosition + (distance * direction);
        Vector3 sca = initialScale + (2 * distance * AbsVec3(direction));

        this.transform.DOLocalMove(pos, 0.2f);
        this.transform.DOScale(sca, 0.2f);
    }

    public Vector3 AbsVec3(Vector3 v){
        Vector3 v2 = new Vector3(0,0,0);
        v2.x = Mathf.Abs(v.x);
        v2.y = Mathf.Abs(v.y);
        v2.z = Mathf.Abs(v.z);
        return v2;
    }

…What even is that? Do you have extension methods somewhere?

Yep sorry, I’m using DOTween to tween things.

I guess the question I’m asking is is there a way to scale things on the global axis rather than the local axis, or convert from a local scale to a global one…

I’d take a look at transform.TransformPoint, .TransformDirection, and more importantly, .InverseTransformPoint and .InverseTransformDirection. The first two turn local space into world space, while the latter two will take a worldspace coordinate and return a local space coordinate.

That said, scaling is an odd thing in that there’s no way for a single transform to get “squished” or “stretched” along a diagonal axis (its local diagonal axis, that is). The only way to accomplish that effect would be to put it under a parent transform that’s rotated differently, along the axis you want to stretch/squish.

Thanks @StarManta I’m not after squishing on diagonal axes… the rotations I apply at 90,180,270,360. This is as far as I got unfortunately I think it’s beyond me,

// Update is called once per frame
    void Update () {   
        if (Input.GetMouseButtonDown(0)){
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
            if (Physics.Raycast (ray, out hit, 2000.0f)){
                if ( hit.collider.transform == this.transform){
                    Trigger();
                }     
            }
        }
    }
   
    public void Trigger(){
        Vector3 initialPosition = this.transform.position;
        Vector3 initialScale = this.transform.localScale;
       
        Vector3[] directionArray = new Vector3[]{Vector3.right,Vector3.up,Vector3.forward, Vector3.left, Vector3.down, Vector3.back};       
        Vector3 direction = directionArray[Random.Range(0,directionArray.Length)];
        float distance = Random.Range(-2f, 2f);

        Vector3 pos = initialPosition + (distance * direction);
        Vector3 sca = initialScale + (2 * distance * AbsVec3(direction));
        Vector3 thePosition = this.transform.InverseTransformPoint(pos);
        Debug.Log(thePosition);

        this.transform.DOMove(thePosition, 0.2f);
        this.transform.DOScale(sca, 0.2f);
    }

    public Vector3 AbsVec3(Vector3 v){
        Vector3 v2 = new Vector3(0,0,0);
        v2.x = Mathf.Abs(v.x);
        v2.y = Mathf.Abs(v.y);
        v2.z = Mathf.Abs(v.z);
        return v2;
    }

Got it!

public void TriggerWorks(){
        Vector3 initialPosition = this.transform.position;
        Vector3 initialScale = this.transform.localScale;
      
        Vector3[] directionArray = new Vector3[]{Vector3.right, Vector3.up, Vector3.forward, Vector3.left, Vector3.down, Vector3.back};      
      
      
      
            Vector3 direction = directionArray[Random.Range(0, directionArray.Length)];
            float distance = Random.Range(-2f, 2f);

            Vector3 pos = initialPosition + (distance * transform.InverseTransformDirection(direction));
            Vector3 sca = initialScale + (2 * distance * transform.InverseTransformDirection(AbsVec3(direction)));
      

        this.transform.DOMove(pos, 0.2f);
        this.transform.DOScale(sca, 0.2f);
    }

    public Vector3 AbsVec3(Vector3 v){
        Vector3 v2 = new Vector3(0,0,0);
        v2.x = Mathf.Abs(v.x);
        v2.y = Mathf.Abs(v.y);
        v2.z = Mathf.Abs(v.z);
        return v2;
    }