Unity - how to make an object face the direction of its movement?

Viewed 66

I'm trying to make a character prefab face the direction in which its moving. I've tired all sorts of things, with and without rigidbodies but nothing seems to work. The thing is, it does actually face in the correct direction. But once its there, it starts to rotate the whole prefab and it goes down into the ground. The character holds a 3D shield, and goes towards a tower. So once it reaches the tower it raises the shield which in turn rotates the whole character down into the ground. I would like it to just rotate in the X and Z axis and never change the Y axis.

Here's my code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BlockRadar : MonoBehaviour
{
    // Start is called before the first frame update

    public Transform Tower;

    private GameObject[] multipleBlocks;
    public Transform closestBlock;
    public bool blockContact;
    
    public float currentDistance;
    public float stopDistance;

    public Animator animator;
    public int damage;
    public float attackspeed;
    private float canAttack;

    public float moveSpeed = 5f;
    public Vector3 distance;
    private Vector3 movement;


    void Start()
    {

        closestBlock = null;
        blockContact = false;

    }

    // Update is called once per frame
    void Update()
    {

        Vector3 pos = transform.position;
        pos.y = 0;
        pos.x = 0;
        transform.position = pos;

        closestBlock = getClosestBlock();
        closestBlock.gameObject.GetComponent<Renderer>().material.color = new Color(1, 0.7f, 0, 1);

        Vector3 direction = closestBlock.position - transform.position;
        direction.Normalize();
        movement = direction;




        float dist = Vector3.Distance(closestBlock.position, transform.position);
        if (dist <= 1.5f)
        {
            {
                blockContact = true;
                animator.SetBool("Moving", false);
                Debug.Log("Now touching block");
                if (attackspeed <= canAttack)
                {
                    Attack();
                    canAttack = 0f;
                }
                else
                {
                    canAttack += Time.deltaTime;

                }

            }
        }
        





        if (dist > 1.5f)
        {
            transform.forward = movement;
            blockContact = false;
            Debug.Log("Lost contact with block");
            animator.SetBool("Moving", true);
            moveCharacter(movement);
        }
    }



    public void Attack()
    {             
        Debug.Log("ATTACKING!");
        Damage(closestBlock.transform);
        animator.SetTrigger("Attacking");       
    }


    private void FixedUpdate()
    {


    }



    void moveCharacter(Vector3 direction)
    {
        transform.Translate(direction * moveSpeed * Time.deltaTime, Space.World);

    }


    void DistanceToTower()
    {
        if (Tower)
        {
            float dist = Vector3.Distance(Tower.position, transform.position);
            if (dist <= 1)
            {
                {
                    blockContact = true;
                    Debug.Log("Now touching block");
                    if (attackspeed <= canAttack)
                    {
                        Attack();
                        canAttack = 0f;
                    }
                    else
                    {
                        canAttack += Time.deltaTime;

                    }

                }
            }
        }
    }


            

    //when the object carrying this script is destroyed
    private void OnDestroy()
    {
        if (closestBlock !=null)
        {
            closestBlock.gameObject.GetComponent<Renderer>().material.color = new Color(0, 0, 0, 0);
        }
    }

    public Transform getClosestBlock()
    {
        multipleBlocks = GameObject.FindGameObjectsWithTag("Block");
        float closestDistance = Mathf.Infinity;
        Transform trans = null;

        //finds all blocks in the scene
        foreach (GameObject go in multipleBlocks)
        {
            
            currentDistance = Vector3.Distance(transform.position, go.transform.position);
            if (currentDistance < closestDistance)
            {
                closestDistance = currentDistance;
                trans = go.transform;
            }
        }
        return trans;
    }

    void Damage(Transform block)
    {
        Tower_Stats e = block.GetComponent<Tower_Stats>();

        if (e != null)
        {
            e.TakeDamage(damage);
        }


    }

}

I would be really, really grateful for any help. As I said before I used to have rigidbodies on the character, but I removed them since I thought maybe they were the fault. But doesnt seem like it. One other thing I've noticed is that when the prefab is instantiated, its children doesnt have the correct position values. Not sure why. But if that could be a clue I just thought I'd let you know.

0 Answers
Related