Global to Local coordinates

Hi!

I've a created a simple script to make an object jitter. I've created it for global coordinates:

transform.position = new Vector3 (transform.position.x + translationValue, ...);

How can I easily alter the script to make the movement along the local axis?

When I use transform.forward there is an error concerning, that I can not add something to the forward value.


  • Jonathan Gonzalez(jgonzalez) replied

    For local position you can use transform.localPosition

    https://docs.unity3d.com/ScriptReference/Transform-localPosition.html

    Transform has a number of different local properties including rotation and position:

    https://docs.unity3d.com/ScriptReference/Transform.html

  • stefaniej replied

    Thank you Jonathan! I will take a closer look tomorrow, but what I can see already is, that I have no parent (I might create one?) I only have a simple object, a cone in this case.

  • Jonathan Gonzalez(jgonzalez) replied

    I'm not entirely sure what you're trying to do, but all game objects have a transform component on them. You can technically scale/rotate/position everything if you wanted through this component. 

  • stefaniej replied

    I have created a random value to generate the global x and z position. I add this to transform.position.x and transform.position..z. I want to add this random value to the local coordinates of the object, so that this random jitter movement happens around the local z instead of around the global y direction.

    The result will be spikes come out of the ground (like in the prince of Persia, just with jitter).

  • Jonathan Gonzalez(jgonzalez) replied

    If you post your script I can help you modify it to work this way. Should be relatively simple, I just need to know how you're going about it.

  • stefaniej replied

    Yes, I think it is simple (not for me!). 

    So here is the script:


    using System.Collections;

    using System.Collections.Generic;

    using UnityEngine;


    public class VibrateObject : MonoBehaviour {


    // public float speed = 1f;

    public float translationDelta = 1f;

    public int changeDirectionSpeed = 3;

    public int maxRandom = 7;

    public float faktor = 0.006f;

    public float maxY = -2;


    private float directionX = -1;

    private float directionZ = -1;

    private int counter = 0;


    private float randomDirectionX = 1;

    private float randomDirectionZ = 1;

    private float translationDeltaY = 1;


    // Use this for initialization

    void Start () {

    }


    // Update is called once per frame

    void Update () {

    translationDelta = Random.Range (1, maxRandom);



    // Jitter Movement

    counter++;

    if (counter == changeDirectionSpeed) {



    if (transform.position.y < maxY) {

    translationDeltaY = translationDelta * faktor;

    } else {

    translationDeltaY = 0;

    translationDelta = 0;

    }



    Debug.Log (transform.position.y);


    transform.position = new Vector3 (

    transform.position.x + translationDelta * faktor * directionX,

    transform.position.y + translationDeltaY,

    transform.position.z + translationDelta * faktor * directionZ);


    // Random Direction X

    randomDirectionX = Random.Range (1, 3);

    if (randomDirectionX == 2) {

    directionX = -directionX;

    }


    // Random Direction Y

    randomDirectionZ = Random.Range (1, 3);

    if (randomDirectionZ == 2) {

    directionZ = -directionZ;

    }


    // End Z

    if(transform.position.x == maxY){


    }


    counter = 0;

    }

    }

    }

  • Jonathan Gonzalez(jgonzalez) replied

    Sorry for the late reply. The script you provided didn't seem to do anything when I applied it to a game object. Not entirely sure how it's supposed to work as it was a bit confusing to me. Below is a simplified script that shakes along the local Z axis of an object you place this on:

    using UnityEngine;
    using System.Collections;

    public class Shake : MonoBehaviour
    {

    public float shakeDuration = 5f;
    public float shakeStrength = 3f;
    private Vector3 randomPos;


    void Update ()
    {
    ShakeLocal ();
    }

    void ShakeLocal()
    {
    if (shakeDuration > 0) {
     randomPos = transform.TransformDirection (0,0,Random.insideUnitSphere.z);
    transform.position = randomPos * shakeStrength;
    }
    }


    }


    To briefly explain it. The first variable is essentially just a timer, this is optional but just used to demonstrate the shake over a specified time. So in this case it'll shake the object for 5 seconds then stop. ShakeStrength is used to amplify the shake so it's more erratic. A higher value here means the shake will be a lot stronger and faster. Lastly the Vector3 RandomPos is used to store the new vector3 position for the object. In the ShakeLocal method we're checking to see if our shake duration value is greater than zero, if so we will continue doing whatever is inside the if statement.

     We assign a value to randomPos and use transform.TransformDirection which will convert from local  to global space. This takes in a Vector3, so we assign 0 for both x and Y. The last value is for the Z axis and instead of randomly generating this value ourselves we just use Random.insideUnitSphere, which randomly selects a point within a sphere as a vector 3. We need to specify we only want a random value from this for the Z axis. If you wanted to have random jitter along all three axis values you can replace it Random.insideUnitySphere as such:

    randomPos = transform.TransformDirection (Random.insideUnitSphere);


    We then set the transform position to equal that new vector3 and multiply that against our shakeStrength so that we can control how strong the shake is. You could also use Random.Range in each one of these values for the X, Y, and Z. Create separate floats then store them in that TransformDirection vector3. 

    If you need further clarification let me know. 




  • stefaniej replied

    Thank you, Jonathan! I am sorry for my confusing programming style. I am not really a programmer. Maybe I also have forgotten to copy parts of the code? (It basically worded with my objects.)

    I am so glad for your help! It is for a game project in school (1st year, I am one of the digital artists) and I have to animate some traps, this case it seemed to be better to write a little script. Soon I will try out what you have provided and will tell you how it went (:

  • Jonathan Gonzalez(jgonzalez) replied

    Great. Sometimes the simplest methods work best. What I posted above might not be a perfect fit for what you need, but it should give you a good idea of how you can implement it into your project with a little modification. 

  • stefaniej replied

    Hello Jonathan!

    The script works fine, but I  could not solve the problem that the above script puts the spike at a certain position. I have spikes placed somewhere in the game layout and I just want to put the script on any of them. They should stay at their current position and from there start the animation. I hope you have any idea, I have not so far ):

  • stefaniej replied

    Hello Jonathan!

    I think what I have written in my last post was a mistake. I was so confused about my different scripts, that I might have mixed it with another one. So forget about what I have written. Everything works fine (:

  • Jonathan Gonzalez(jgonzalez) replied

    Glad to hear you got it working!