Vector Axis Translation

Hello i am trying to make clean camera controller where the movement is able to pan and zoom on severas axis

after completing the basic purpose i am trying to extend it to become more dynamic by exposing some of variable to inspector.

now i am trying to accommodate multiple possibility of panning direction :

as camera navigation is limited to 2d vector x and y

but there are 3 possible axis movement x, y, and z

thus leads me to these kind of code :

public enum Axis
    {
        X,
        Y,
        Z
    }

[SerializeField]
private Vector2 _lowerLimit = Vector2.zero;

[SerializeField]
private Vector2 _upperLimit = Vector2.one;

[SerializeField]
private Axis _xAxis;
[SerializeField]
private Axis _yAxis;

public Vector3 Clamp(Vector3 vector3)
{
    return new Vector3()
    {
        x = (_xAxis != Axis.X && _yAxis != Axis.X) ? vector3.x : 
                Mathf.Clamp(vector3.x,TranslateVector(_lowerLimit).x, TranslateVector(_upperLimit).x),
        y = (_xAxis != Axis.Y && _yAxis != Axis.Y) ? vector3.y : Mathf.Clamp(vector3.y,
               TranslateVector(_lowerLimit).y, TranslateVector(_upperLimit).y),
       z = (_xAxis != Axis.Z && _yAxis != Axis.Z) ? vector3.z : Mathf.Clamp(vector3.z,
               TranslateVector(_lowerLimit).z, TranslateVector(_upperLimit).z)
            };
        }

public Vector3 TranslateVector(Vector3 vector3)
    => new Vector3(
        0 + ((_xAxis == Axis.X) ? vector3.x : 0) + ((_yAxis == Axis.X) ? vector3.y : 0),
        0 + ((_xAxis == Axis.Y) ? vector3.x : 0) + ((_yAxis == Axis.Y) ? vector3.y : 0),
        0 + ((_xAxis == Axis.Z) ? vector3.x : 0) + ((_yAxis == Axis.Z) ? vector3.y : 0)
    );

so i used xaxis and yaxis to forward horizontal and vertical input to assigned axis

but i feels like these line of code have too much repetition.

thank you beforehand

You haven’t asked any questions, but I assume you’d like help rewriting that code to be more concise.

I usually look at the lines with almost duplicate code and compare and extract the differences. If the same function is being called multiple times with the same parameters and result, store the result.

Well, it does look there is some repetition and that can almost always be removed, leading to more maintainable code.

public Vector3 TranslateVector(Vector3 vector3)
    => new Vector3(
        TranslateValue(Axis.X, vector3.x, vector3.y),
        TranslateValue(Axis.Y, vector3.x, vector3.y),
        TranslateValue(Axis.Z, vector3.x, vector3.y)
    );

private float TranslateValue(Axis axis, float valueX, float valueY)
{
    return ((_xAxis == axis) ? valueX : 0.0f) + ((_yAxis == axis) ? valueY : 0.0f)
}

You could also use the Axis enum values as index directly, though I recommend explicitly numbering them in that case:

public Vector3 TranslateVector(Vector3 vector3)
{
    Vector3 result = Vector3.zero;
    result[(int)_xAxis] = vector3.x;
    result[(int)_yAxis] = vector3.y;
    return result;
}

Maybe something like this. I wrote it in notepad so I don’t know if it compiles or works.

public Vector3 Clamp(Vector3 vector3)
{
    var lowerVector = TranslateVector(_lowerLimit);
    var upperVector = TranslateVector(_upperLimit);
 
    var clampedVector = ClampVector(vector3, lowerVector, upperVector);
 
    if(_xAxis != Axis.X && _yAxis != Axis.X) clampedVector.x = vector3.x;
    if(_xAxis != Axis.Y && _yAxis != Axis.Y) clampedVector.y = vector3.y;
    if(_xAxis != Axis.Z && _yAxis != Axis.Z) clampedVector.z = vector3.z;
 
    return clampedVector;
}

public Vector3 TranslateVector(Vector3 vector3) // Stolen from jvo3dc :p
{
    Vector3 result = Vector3.zero;
    result[(int)_xAxis] = vector3.x;
    result[(int)_yAxis] = vector3.y;
    return result;
}

public Vector3 ClampVector(Vector3 vector3, Vector3 lowerVector, Vector3 upperVector) { 
    var v = new Vector3();
    for (int i = 0; i < 3; i++) {
        v[i] = Mathf.Clamp(vector3[i], lowerVector[i], upperVector[i]);
    }
    return v;
}

i’m sorry that i forgot to put the question :frowning:

and yes i am trying to make the code cleaner and asking :

is there a better approach that could make my code much cleaner ?

I tried the code and it looks much cleaner, and it works too.thanks :smile:

i’m also still doubting if my approach to make such vector translation is good enough and looking for better approach / insight for this kind of problem