0
\$\begingroup\$

I've written some code that performs movement similar to the Tomb Of The Musk game. The idea is that the objet should move in a certain direction until it encounters an obstacle. After that, the player can choose which way the object should move.

The code I wrote seems to me to be rather unoptimized. I think it could have been done quite a bit more rationally than I did.

Object movement code:

[SerializeField]
float speed = .9f;

[SerializeField]
LayerMask obstacleMask;

Vector3 targetPosition;
Vector3 moving_direction;

bool movingHorizontally;
bool canCheck;

void Start()
{
    targetPosition = transform.position;
}

void Update()
{
    if (movingHorizontally)
        canCheck = Physics.Raycast(transform.position, Vector3.left, .6f, obstacleMask) || Physics.Raycast(transform.position, Vector3.right, .6f, obstacleMask);
    else
        canCheck = Physics.Raycast(transform.position, Vector3.forward, .6f, obstacleMask) || Physics.Raycast(transform.position, Vector3.back, .6f, obstacleMask);

    if (canCheck)
    {
        if (Input.GetAxisRaw("Horizontal") != 0)
        {
            if (Input.GetAxisRaw("Horizontal") > 0)
            {
                moving_direction = Vector3.right;
            }
            else
            {
                moving_direction = Vector3.left;
            }

            targetPosition = GetTargetPosition();
            movingHorizontally = true;

        }
        
        else if (Input.GetAxisRaw("Vertical") != 0)
        {   
            if (Input.GetAxisRaw("Vertical") > 0)
            {
                moving_direction = Vector3.forward;
            }
            else
            {
                moving_direction = Vector3.back;
            }

            targetPosition = GetTargetPosition();
            movingHorizontally = false;
        }
    }
}

void FixedUpdate()
{
    transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed);
}

Vector3 GetTargetPosition()
{

    float ray_lenght = 1;
    while(true)
    {
        if (Physics.Raycast(transform.position, moving_direction, ray_lenght, obstacleMask))
            break;

        ray_lenght += 1;
    }
    
    return transform.position + moving_direction * (ray_lenght-1);
}

Do you have any ideas regarding the improvement of my code?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Welcome to Code Review! You could improve your question by explaining what "similar to the Tomb Of The Musk game" means, if you want your question to be meaningful to more reviewers, and improve your chance of getting a good review. Also, "how to optimize" is already conveyed by the performance tag, so no need to duplicate that in your title. \$\endgroup\$ Nov 6, 2023 at 15:51

1 Answer 1

0
\$\begingroup\$

In terms of performance what I have done is removed unnecessary method calls and helped out your branch predictor by removing if/else statements.

What I have mainly done though is to enhance code readability which will make it much easier to find performance bottlenecks. I have left your logic intact as I don't have enough information to change it.

Also I noticed you have a call to Vector3.left. Have you implemented your own Vector3 class?

[SerializeField]
float speed = .9f;

[SerializeField]
LayerMask obstacleMask;

Vector3 targetPosition;
Vector3 moving_direction;

bool movingHorizontally;
bool canCheck;

void Start()
{
    targetPosition = transform.position;
}

void Update()
{
    if (!CanMove()) return;

    var horizontalRawAxis = Input.GetAxisRaw("Horizontal");
    var verticalRawAxis = Input.GetAxisRaw("Vertical");

    (moving_direction, movingHorizontally) = horzontalRawAxis > 0? (Vector3.right, true) 
        : horizontalRawAxis < 0 ? (Vector3.left, true)
        : verticalRawAxis > 0 ? (Vector3.forward, false)
        : (Vector3.back, false);

    targetPosition = GetTargetPosition();
}
           

void FixedUpdate()
{
    transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed);
}

Vector3 GetTargetPosition()
{
    float ray_lenght = 1;

    while(!PhysicsRaycast(moving_direction, ray_lenght)) ray_lenght += 1;

    return transform.position + moving_direction * (ray_lenght-1);
}


bool CanMove(MovementType movementType) => movementType switch
{
    MovementType.Left => PhysicsRaycast(Vector3.left, .6f);
    MovementType.Right => PhysicsRaycast(Vector3.right, .6f);
    MovementType.Forward => PhysicsRaycast(Vector3.forward, .6f);
    MovementType.BackWard => PhysicsRaycast(Vector3.back, .6f);

    _ => throw new Exception("Unrecognised movement type");
};

bool CanMove(){
    return movingHorizontally? CanMove(MovementType.Left) || CanMove(MovementType.Right)
        : CanMove(MovementType.Forward) || CanMove(MovementType.BackWard);
}

bool PhysicsRaycast(Vector3 moving_direction, float ray_length) => 
    Physics.Raycast(transform.position, moving_direction, ray_length, obstacleMask);


enum MovementType{
    Left,
    Right,
    Forward,
    BackWard,
}
\$\endgroup\$
15
  • \$\begingroup\$ I think your code changes are really good, however Unity doesn't like them, it says there are a lot of bugs when there aren't any, do you have any advice on this? \$\endgroup\$
    – Hanvil
    Nov 7, 2023 at 7:21
  • \$\begingroup\$ I don't know how to insert a picture here, so I'll write examples of errors in text: 1. Assets\Mover.cs(31,58): error CS1525: Invalid expression term ';' 2. Assets\Mover.cs(52,48): error CS1525: Invalid expression term 'switch' 3. Assets\Mover.cs(52,48): error CS1519: Invalid token 'switch' in class, struct, or interface member declaration 4. Assets\Mover.cs(54,27): error CS1519: Invalid token '=>' in class, struct, or interface member declaration And there are many more errors like this that I don't know how to deal with. \$\endgroup\$
    – Hanvil
    Nov 7, 2023 at 7:36
  • \$\begingroup\$ @Hanvil What line does the code snippet you shared begin at? \$\endgroup\$ Nov 7, 2023 at 17:31
  • \$\begingroup\$ the code starts at line 7 \$\endgroup\$
    – Hanvil
    Nov 7, 2023 at 17:44
  • \$\begingroup\$ @Hanvil Ok I'd try find the line that your first error is on and fix that first. Errors like this can cascade especially if characters like ';' or omitted. Also what text editor/IDE are you using? \$\endgroup\$ Nov 7, 2023 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.