Transform.forward is not pointing in front of GameObject

Hello everyone,

I’m working on a 2.5D (2D sprites in a 3D world) first person game that is all about melee combat. The enemies are also 2.5D using a box collider and sprite renderer components (among others). They always face in front of the player by rotating on the Y-axis based on the main Camera’s Euler Angle on the Y Axis:

public class Billboard : MonoBehaviour
{
    private void Update()
    {
        Vector3 newRotation = Camera.main.transform.rotation.eulerAngles; // There's only one camera so I'm not worried about fixing this just yet

        transform.rotation = Quaternion.Euler(0, newRotation.y, 0);
    }
}

The issue I’m having though is that the combat works by shooting a raycast from the GameObject doing the attacking. For the player this seems to work just fine, but for the enemy it does not. This is how I’m handling attacking using a raycast:

if (Physics.Raycast(transform.position, transform.TransformDirection(transform.forward), out RaycastHit info, raycastDistance))
{
    Debug.DrawLine(transform.position, transform.TransformDirection(transform.forward) * raycastDistance);
    if (info.collider.gameObject.TryGetComponent<PlayerHealth>(out var playerHealth) && _canAttack)
    {
        Debug.Log("Got player");
        animator.SetTrigger("Attacking");
        playerHealth.UpdateHealth(-enemyData.attackStrength);
        _canAttack = false;
        StartCoroutine(CooldownAttack());
        Invoke("ResetAnimation", attackDowntime);
    }
}

It shoots out a raycast from the center of the enemy and if it intersects with the player (based on the player’s PlayerHealth component) and if it can attack, then it performs the animation and decreases the player’s health.

When I tested this, the enemy’s forward vector doesn’t seem to be directly in front of the enemy like I expected. Instead, it points to the origin of the game world like so:

Even without calling transform.TransformDirection() this still happens.

Any help is appreciated. Thank you.

For a better reference of what I want to achieve, I expected the raycast to point out like the positive Z axis on the gizmo like here:

Usually with 2D sprites, transform.right (or its negative) would be out the “front” of the sprite.

Otherwise, using transform.forward should be the +Z blue arrow you show in the above image, assuming that is Local view versus Global View. Are you sure you’ve got the correct transform?

Check your pivot/center and global/local buttons in the Scene window in the editor.

Shortcut keys are Z and X to toggle those.

Love the two sharp teeth, one eye club guy… I fear him.

The first script can be done like this:

    void Update()
    {
        Vector3 p = Camera.main.transform.position;
        transform.LookAt(new Vector3(p.x, 0, p.z));
    }

And then the ray cast is done like this:

if (Physics.Raycast(transform.position, transform.forward, out RaycastHit info, raycastDistance))

The Debug.DrawLine should be:

Debug.DrawRay(transform.position, transform.forward * raycastDistance);

You can get the direction of an object by multiplying the object’s rotation with the world vector.

Here’s an example:

transform.forward is exactly the same as writing transform.rotation * Vector3.forward.
So even when you’re working with Rigidbody objects and don’t have access to forward, right or up of the Transform, you can always calculate it by yourself.

Cheers!

Technically you don’t know the forward vector from the image @angeloaf20 provided.
We’re not sure if we’re looking at World or Local gizmo of directions.

@Kurt-Dekker That’s good to know. I was viewing the transform in local space. And thanks for the comment about the enemy (goblin). He was supposed to just be a placeholder but given my art skills I’m tempted to make the other enemies in a similar style.

@YoyoMario transform.rotation * Vector3.forward worked. I have no idea why just using transform.forward didn’t do what I expected though.

1 Like