Forum rules - please read before posting.

How to translate GameObjects to a specific value along one axis only?

edited June 2020 in Technical Q&A

Hello,

I have two dozens of objects, scattered in different places (in x and z) of a 3D scene, that need to move up and down (along the y-axis) when clicked upon. The final position of their movement along the y-axis depends on the value of one out of 24 vars which is specific to each of these 24 objects, but a var's value is regenerated after every click. There are 6 possible values these vars can take, so there are 6 different stop positions on the y-axis.

Ideally I would like to

  • have hotspots on each of these 24 objects,
  • that trigger one and the same parameterised ActionList with the GameObjectToMoveAlongY as param1 and the corresponding VAR as param2
  • that perform an "Object: Transform/ Translate to"- Action for that purpose …

… but this action forces me to enter values for x and z, too … which I do not know.

So I thought about running an "Object:Record Transform" for the clicked upon GameObject first and save it temporarily to a Vector 3 Var … but how would I transfer the two recorded x-pos and z-pos values to an "Object: Transform/ Translate to" Vector 3 unchanged, while changing the y-pos value on the way?

The third option "Object: Transform/ Translate by" does not work either for me, as the GameObject's starting position along the y-axis is unknown, too, so I would not know how far to "translate by".

Is there another easy way to achieve what I want – without writing a separate "Object: Transform/ Translate to" action for every single GameObject?

Or would it be possible to optionally "lock" single axes in this action?

Best, Jensen

Comments

  • … and by the way, @ChrisIceBox : how does the compare function in "Variable: Check - Type Vector3 – Magnitude Greater Than" work? I am not familiar with this and cannot find it documented, but maybe this can help solve my problem.

    Thanks!

  • edited June 2020

    The longer I am working on this, the more I would appreciate an option to send FLOATs as parameters to single (!) Vector 3 value fields, like

    ActionList (use parameters):

    • Param1: ValueForPositionX / Type: Float
    • Param2: ValueForPositionZ / Type: Float
    • Param3: ObjectToMove / Type: GameObject
    1. Object: Record Transform / Object: [param3]
    2. Object: Transform / Translate to Position / Vector is from Vector 3 Var "NNN"

    … and then have an option to show the fields (x) (y) (z) in order to allow me to override some of their values like this: ([param1]) (NNN) ([param2])

  • Sounds like quite a unique scenario. I'd say it's best to hook into the OnBeginActionList custom event, where you can generate the value of a Vector3 parameter based on the GameObject's current position, and the value of the "var" parameter:

    using UnityEngine;
    using AC;
    
    public class SetVectorParameter : MonoBehaviour
    {
    
        public ActionListAsset myMoveObjectActionList;
        public int varParameterID, gameObjectParameterID, vectorParameterID;
    
        private void OnEnable () { EventManager.OnBeginActionList += OnBeginActionList; }
        private void OnDisable () { EventManager.OnBeginActionList -= OnBeginActionList; }
    
        private void OnBeginActionList (ActionList actionList, ActionListAsset actionListAsset, int startingIndex, bool isSkipping)
        {
            if (actionListAsset == myMoveObjectActionList)
            {
                ActionParameter gameObjectParameter = actionList.GetParameter (gameObjectParameterID);
                Vector3 currentPosition = gameObjectParameter.gameObject.transform.position;
    
                ActionParameter varParameter = actionList.GetParameter (varParameterID);
                Vector3 newPosition = new Vector3 (currentPosition.x, varParameter.floatValue, currentPosition.z);
    
                ActionParameter vectorParameter = actionList.GetParameter (vectorParameterID);
                vectorParameter.vector3Value = newPosition;
            }
        }
    
    }
    

    This requires three parameters:

    1. The "var" to set the object's y-position to (presumed to be a float, but could be casted from an int)
    2. The GameObject to move
    3. The Vector3 to move the object to
  • edited June 2020

    Thanks, Chris, for creating this script …

    … but so far, I could not get it work. Whatever I try, the Vector3 won't get updated.

    Here is what I tried to do so far:


    I assumed that the ActionList executing this custom script OnBegin should essentially consist of an "Object: Transform - Translate to" action.
    So I created this ActionList asset and named it "Recalc Vector3".
    This ActionList uses three parameters in the following order:

    • YFLOAT: a Float parameter for the new Y-position value
    • THING: a GameObject parameter for the object to reposition
    • XYZ: a Vector3 parameter

    The "Object: Transform" action reads:
    --> Moveable Object: (param) 1: THING
    Translate to
    Vector is: entered here
    --> Value: (param) 2. XYZ
    etc.

    Then I created the script as you described and attached it to this ActionList in the script's inspector.

    The ActionList finally gets run by a common "Hotspot interaction: Use" for all 24 Game Object hotspots with "Set Interaction Parameters" component:

    • a discrete value of -0.25 entered for YFLOAT
    • the GameObject sending itself as parameter to THING
    • the XYZ unset (which equals to x:0 y:0 z:0)

    In this case each THING will translate to X:0 Y:0 Z:0.

    Neither is THING's original position read, nor is it's Y-position recalculated

    (As a variation, I set the default value of XYZ to x:0 y:0 z:5 in order to find our if these preset values matter at all; they seem to: THINGs now translate to X:0 Y:0 Z:5)


    Next I assumed that your script does not read THING's position by itself but expects a pre-recorded value for XYZ.
    So I changed XYZ from "Vector3" to "Global Variable"; the new parameter setup for "Recalc Vector3" reads now:

    • YFLOAT: a Float parameter for the new Y-position value
    • THING: a GameObject parameter for the object to reposition
    • XYZ Var: a Global Variable parameter, with its default value set to the Global Var "RECORDER"

    Then I added an "Object: Record Transform" action to save THING's original position to RECORDER (and I can confirm from the Variables Manager, that this action works).
    Immediately after that, action "Recalc Vector3" gets run with:

    • a discrete value of -0.25 entered for YFLOAT
    • the GameObject sending itself as parameter to THING
    • XYZ set to RECORDER

    Now the "Object: Transform" action reads:
    --> Moveable Object: (param) 1: THING
    Translate to
    Vector is: From Vector 3 Variable
    --> Vector3 variable: (param) 2. XYZ
    etc.

    In this case each THING will not translate at all, but stay where it is.


    What am I missing?

  • Keep XYZ as a Vector parameter - making the same components / Actions as you describe has it work for me.

    In the "Set Interaction Parameters" component, you can ignore XYZ - set the GameObject to itself, and the YFLOAT to your intended height.

    The only thing I can spot wrong is you mention:

    Then I created the script as you described and attached it to this ActionList in the script's inspector.

    The ActionList is an asset file - it's not a prefab that you can attach scripts to, so I'm not quite sure what you mean here.

    You need to place the script in your scene - attach a single instance of it to e.g. an empty GameObject. You'll also need to configure it's Inspector - set "My Move Object Action List" to "Recalc Vector3", and the parameter IDs to 0, 1, 2 respectively (assuming that matches up with their IDs in the ActionList).

  • edited June 2020

    The ActionList is an asset file - it's not a prefab that you can attach scripts to, so I'm not quite sure what you mean here.

    I actually didn't mean "attach" but "configured", just as you mentioned in the next paragraph.
    But here I made the mistakes: neither did I attach an instance of the script to a game object in the scene, nor did I set the parameter IDs to 0, 1, 2.

    Now, after fixing this things, it indeed works in so far as the clicked THING starts to move …

    … but unfortunately not to where it is supposed to. Each THING moves along all three axes (instead of just Y) to the most exotic places in space, and this regardless of whether "Act in world-space" option of The "Object: Transform / Translate to" action is checked or unchecked (although the directions and distances THINGs travel of course differ, depending on the checkbox setting).

    But I am sure that this problem is entirely related to my scene geometry, which has some heavily nested and internally twisted structures and also some rescaled parent objects, too (which has often proved unhealthy for translating GameObjects via Vector3s).

    So while your script and assistance helped me a big lot, there is obviously quite some cleanup to do on my side.

    Thanks so much (again)!

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.